Skip to content

Commit ff49ca0

Browse files
committed
Add View support (without DDL)
Given the Views behave similar to Tables on CRUD operations, they are treated as if they were tables. This patch insures that all operations available through a Table object are also available if the underlying object is a View. Table.is_view() method was added to verify if the underlying object is a View. Tests were added/changed for regression.
1 parent d5a1a23 commit ff49ca0

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

lib/mysqlx/crud.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,15 @@
3131
DropCollectionIndexStatement)
3232

3333

34+
_COUNT_VIEWS_QUERY = ("SELECT COUNT(*) FROM information_schema.views "
35+
"WHERE table_schema = '{0}' AND table_name = '{1}'")
3436
_COUNT_TABLES_QUERY = ("SELECT COUNT(*) FROM information_schema.tables "
3537
"WHERE table_schema = '{0}' AND table_name = '{1}'")
3638
_COUNT_SCHEMAS_QUERY = ("SELECT COUNT(*) FROM information_schema.schemata "
3739
"WHERE schema_name like '{0}'")
3840
_COUNT_QUERY = "SELECT COUNT(*) FROM `{0}`.`{1}`"
3941
_DROP_TABLE_QUERY = "DROP TABLE IF EXISTS `{0}`.`{1}`"
42+
_DROP_VIEW_QUERY = "DROP VIEW IF EXISTS `{0}`.`{1}`"
4043

4144

4245
class DatabaseObject(object):
@@ -96,6 +99,7 @@ def am_i_real(self):
9699
def who_am_i(self):
97100
return self.get_name()
98101

102+
99103
class Schema(DatabaseObject):
100104
"""A client-side representation of a database schema. Provides access to
101105
the schema contents.
@@ -159,11 +163,11 @@ def get_tables(self):
159163
rows = self._connection.get_row_result("list_objects", self._name)
160164
rows.fetch_all()
161165
tables = []
166+
object_types = ("TABLE", "VIEW",)
162167
for row in rows:
163-
if row.get_string("type") != "TABLE":
164-
continue
165-
table = Table(self, row.get_string("name"))
166-
tables.append(table)
168+
if row.get_string("type") in object_types:
169+
table = Table(self, row.get_string("name"))
170+
tables.append(table)
167171
return tables
168172

169173
def get_table(self, name, check_existence=False):
@@ -205,8 +209,13 @@ def drop_table(self, name):
205209
Args:
206210
name (str): The name of the table to be dropped.
207211
"""
208-
self._connection.execute_nonquery(
209-
"sql", _DROP_TABLE_QUERY.format(self._name, name), False)
212+
table = Table(self, name)
213+
if table.is_view():
214+
self._connection.execute_nonquery(
215+
"sql", _DROP_VIEW_QUERY.format(self._name, name), False)
216+
else:
217+
self._connection.execute_nonquery(
218+
"sql", _DROP_TABLE_QUERY.format(self._name, name), False)
210219

211220
def create_collection(self, name, reuse=False):
212221
"""Creates in the current schema a new collection with the specified
@@ -407,3 +416,12 @@ def count(self):
407416
"""
408417
sql = _COUNT_QUERY.format(self._schema.name, self._name)
409418
return self._connection.execute_sql_scalar(sql)
419+
420+
def is_view(self):
421+
"""Determine if the underlying object is a view or not.
422+
423+
Returns:
424+
bool: `True` if the underlying object is a view.
425+
"""
426+
sql = _COUNT_VIEWS_QUERY.format(self._schema.get_name(), self._name)
427+
return self._connection.execute_sql_scalar(sql) == 1

tests/test_mysqlx_crud.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535

3636
_CREATE_TEST_TABLE_QUERY = "CREATE TABLE `{0}`.`{1}` (id INT)"
3737
_INSERT_TEST_TABLE_QUERY = "INSERT INTO `{0}`.`{1}` VALUES ({2})"
38+
_CREATE_TEST_VIEW_QUERY = ("CREATE VIEW `{0}`.`{1}` AS SELECT * "
39+
"FROM `{2}`.`{3}`;")
3840
_COUNT_TABLES_QUERY = ("SELECT COUNT(*) FROM information_schema.tables "
3941
"WHERE table_schema = '{0}' AND table_name = '{1}'")
4042

@@ -103,18 +105,21 @@ def test_get_tables(self):
103105
tables = self.schema.get_tables()
104106
self.assertEqual(0, len(tables), "Should have returned 0 objects")
105107

106-
self.node_session.sql("CREATE TABLE {0}.table1(id INT)"
107-
"".format(self.schema_name)).execute()
108-
self.node_session.sql("CREATE TABLE {0}.table2(id INT)"
109-
"".format(self.schema_name)).execute()
110-
self.node_session.sql("CREATE TABLE {0}.table3(id INT)"
111-
"".format(self.schema_name)).execute()
112-
108+
self.node_session.sql(_CREATE_TEST_TABLE_QUERY.format(
109+
self.schema_name, "table1")).execute()
110+
self.node_session.sql(_CREATE_TEST_TABLE_QUERY.format(
111+
self.schema_name, "table2")).execute()
112+
self.node_session.sql(_CREATE_TEST_TABLE_QUERY.format(
113+
self.schema_name, "table3")).execute()
114+
self.node_session.sql(_CREATE_TEST_VIEW_QUERY.format(
115+
self.schema_name, "view1",
116+
self.schema_name, "table1")).execute()
113117
tables = self.schema.get_tables()
114-
self.assertEqual(3, len(tables), "Should have returned 3 objects")
118+
self.assertEqual(4, len(tables), "Should have returned 4 objects")
115119
self.assertEqual("table1", tables[0].get_name())
116120
self.assertEqual("table2", tables[1].get_name())
117121
self.assertEqual("table3", tables[2].get_name())
122+
self.assertEqual("view1", tables[3].get_name())
118123

119124
def test_drop_collection(self):
120125
collection_name = "collection_test"
@@ -621,3 +626,19 @@ def test_column_metadata(self):
621626
self.assertEqual("active", col.get_column_name())
622627
self.assertEqual("test", col.get_table_name())
623628
self.assertEqual(mysqlx.ColumnType.BIT, col.get_type())
629+
630+
def test_is_view(self):
631+
table_name = "table_test"
632+
view_name = "view_test"
633+
self.node_session.sql(_CREATE_TEST_TABLE_QUERY.format(
634+
self.schema_name, table_name)).execute()
635+
self.node_session.sql(_INSERT_TEST_TABLE_QUERY.format(
636+
self.schema_name, table_name, "1")).execute()
637+
table = self.schema.get_table(table_name)
638+
self.assertFalse(table.is_view())
639+
640+
self.node_session.sql(_CREATE_TEST_VIEW_QUERY.format(
641+
self.schema_name, view_name,
642+
self.schema_name, table_name)).execute()
643+
view = self.schema.get_table(view_name)
644+
self.assertTrue(view.is_view())

0 commit comments

Comments
 (0)