Skip to content

Commit 3b2afba

Browse files
author
Reggie Burnett
committed
Merge branch 'release/2.2.0' of myrepo.no.oracle.com:connector-python into release/2.2.0
2 parents c306be8 + e970ac4 commit 3b2afba

File tree

6 files changed

+127
-3
lines changed

6 files changed

+127
-3
lines changed

lib/mysqlx/crud.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
# along with this program; if not, write to the Free Software
2222
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2323

24-
from .statement import AddStatement, RemoveStatement, TableDeleteStatement, FindStatement, SelectStatement
24+
from .statement import (AddStatement, RemoveStatement, TableDeleteStatement,
25+
FindStatement, SelectStatement,
26+
CreateCollectionIndexStatement,
27+
DropCollectionIndexStatement)
2528

2629

2730
_COUNT_TABLES_QUERY = ("SELECT COUNT(*) FROM information_schema.tables "
@@ -146,6 +149,23 @@ def count(self):
146149
sql = _COUNT_QUERY.format(self._schema.name, self._name)
147150
return self._connection.execute_sql_scalar(sql)
148151

152+
def create_index(self, index_name, is_unique):
153+
"""Creates a collection index.
154+
155+
Args:
156+
index_name (string): Index name.
157+
is_unique (bool): True if the index is unique.
158+
"""
159+
return CreateCollectionIndexStatement(self, index_name, is_unique)
160+
161+
def drop_index(self, index_name):
162+
"""Drops a collection index.
163+
164+
Args:
165+
index_name (string): Index name.
166+
"""
167+
return DropCollectionIndexStatement(self, index_name)
168+
149169

150170
class Table(DatabaseObject):
151171
def __init__(self, schema, name):

lib/mysqlx/protocol.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ def _create_any(self, arg):
181181
val = MySQLxDatatypes.Scalar.String(value=arg)
182182
scalar = MySQLxDatatypes.Scalar(type=8, v_string=val)
183183
return MySQLxDatatypes.Any(type=1, scalar=scalar)
184+
elif isinstance(arg, bool):
185+
return MySQLxDatatypes.Any(type=1, scalar=build_bool_scalar(arg))
186+
elif isinstance(arg, int):
187+
return MySQLxDatatypes.Any(type=1, scalar=build_int_scalar(arg))
184188
return None
185189

186190
def close_result(self, rs):
@@ -266,4 +270,4 @@ def arg_object_to_expr(self, value, allow_relational):
266270
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=ExprParser().build_string_scalar(value))
267271
elif isinstance(value, DbDoc):
268272
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_string_scalar(str(value)))
269-
raise Exception("Unsupported type")
273+
raise Exception("Unsupported type")

lib/mysqlx/statement.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,63 @@ def __init__(self, table, condition=None):
173173

174174
def execute(self):
175175
return self._connection.delete(self)
176+
177+
178+
class CreateCollectionIndexStatement(Statement):
179+
"""A statement that creates an index on a collection.
180+
181+
Args:
182+
collection (mysqlx.Collection): Collection.
183+
index_name (string): Index name.
184+
is_unique (bool): True if the index is unique.
185+
"""
186+
def __init__(self, collection, index_name, is_unique):
187+
super(CreateCollectionIndexStatement, self).__init__(target=collection)
188+
self._index_name = index_name
189+
self._is_unique = is_unique
190+
self._fields = []
191+
192+
def field(self, document_path, column_type, is_required):
193+
"""Add the field specification to this index creation statement.
194+
195+
Args:
196+
document_path (string): Document path.
197+
column_type (string): Column type.
198+
is_required (bool): True if the field is required.
199+
"""
200+
self._fields.append((document_path, column_type, is_required,))
201+
return self
202+
203+
def execute(self):
204+
"""Execute the Statement.
205+
206+
Returns:
207+
mysqlx.Result
208+
"""
209+
fields = [item for sublist in self._fields for item in sublist]
210+
return self._connection.execute_nonquery(
211+
"xplugin", "create_collection_index", True,
212+
self._target.schema.name, self._target.name, self._index_name,
213+
self._is_unique, *fields)
214+
215+
216+
class DropCollectionIndexStatement(Statement):
217+
"""A statement that drops an index on a collection.
218+
219+
Args:
220+
collection (mysqlx.Collection): Collection.
221+
index_name (string): Index name.
222+
"""
223+
def __init__(self, collection, index_name):
224+
super(DropCollectionIndexStatement, self).__init__(target=collection)
225+
self._index_name = index_name
226+
227+
def execute(self):
228+
"""Execute the Statement.
229+
230+
Returns:
231+
mysqlx.Result
232+
"""
233+
return self._connection.execute_nonquery(
234+
"xplugin", "drop_collection_index", True,
235+
self._target.schema.name, self._target.name, self._index_name)

tests/mysqld.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ def start(self):
556556
'bind_address': self._bind_address,
557557
'port': self._port,
558558
'mysqlx_port': self._mysqlx_port,
559+
'mysqlx_plugin': 'mysqlx.so' if os.name == 'posix' else 'mysqlx',
559560
'unix_socket': _convert_forward_slash(self._unix_socket),
560561
'ssl_dir': _convert_forward_slash(self._ssldir),
561562
'pid_file': _convert_forward_slash(self._pid_file),

tests/test_mysqlx_crud.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,45 @@ def test_results(self):
251251
docs1 = result1.fetch_all();
252252
self.assertEqual(4, len(docs1))
253253

254+
def test_create_index(self):
255+
collection_name = "collection_test"
256+
collection = self.schema.create_collection(collection_name)
257+
258+
index_name = "age_idx"
259+
collection.create_index(index_name, True) \
260+
.field("$.age", "INT", False).execute()
261+
262+
show_indexes_sql = (
263+
"SHOW INDEXES FROM `{0}`.`{1}` WHERE Key_name='{2}'"
264+
"".format(self.schema_name, collection_name, index_name)
265+
)
266+
267+
result = self.node_session.sql(show_indexes_sql).execute()
268+
rows = result.fetch_all()
269+
self.assertEqual(1, len(rows))
270+
271+
def test_drop_index(self):
272+
collection_name = "collection_test"
273+
collection = self.schema.create_collection(collection_name)
274+
275+
index_name = "age_idx"
276+
collection.create_index(index_name, True) \
277+
.field("$.age", "INT", False).execute()
278+
279+
show_indexes_sql = (
280+
"SHOW INDEXES FROM `{0}`.`{1}` WHERE Key_name='{2}'"
281+
"".format(self.schema_name, collection_name, index_name)
282+
)
283+
284+
result = self.node_session.sql(show_indexes_sql).execute()
285+
rows = result.fetch_all()
286+
self.assertEqual(1, len(rows))
287+
288+
collection.drop_index(index_name).execute()
289+
result = self.node_session.sql(show_indexes_sql).execute()
290+
rows = result.fetch_all()
291+
self.assertEqual(0, len(rows))
292+
254293

255294
@unittest.skipIf(MYSQLX_AVAILABLE is False, "MySQLX not available")
256295
@unittest.skipIf(tests.MYSQL_VERSION < (5, 7, 12), "XPlugin not compatible")

unittests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
MY_CNF = """
102102
# MySQL option file for MySQL Connector/Python tests
103103
[mysqld-5.7]
104-
plugin-load=mysqlx
104+
plugin-load={mysqlx_plugin}
105105
loose_mysqlx_port={mysqlx_port}
106106
107107
[mysqld-5.6]

0 commit comments

Comments
 (0)