Skip to content

Commit a515895

Browse files
author
Reggie Burnett
committed
implemented table insert and cleaned up protcol code so collection and table insert are both using same protocol code
1 parent 27b5381 commit a515895

File tree

5 files changed

+59
-29
lines changed

5 files changed

+59
-29
lines changed

lib/mysqlx/connection.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,8 @@ def _authenticate(self):
9292
def send_sql(self, sql, *args):
9393
self.protocol.send_execute_statement("sql", sql, args)
9494

95-
def send_doc_insert(self, statement):
96-
self.protocol.send_doc_insert(statement.schema.name,
97-
statement.target.name,
98-
statement._docs)
95+
def send_insert(self, statement):
96+
self.protocol.send_insert(statement)
9997
return Result(self)
10098

10199
def find(self, statement):

lib/mysqlx/crud.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
from .statement import (AddStatement, RemoveStatement, TableDeleteStatement,
2525
FindStatement, SelectStatement,
26-
CreateCollectionIndexStatement,
26+
CreateCollectionIndexStatement, InsertStatement,
2727
DropCollectionIndexStatement)
2828

2929

@@ -179,7 +179,7 @@ def select(self, *fields):
179179
return SelectStatement(self, *fields)
180180

181181
def insert(self, *fields):
182-
pass
182+
return InsertStatement(self, *fields)
183183

184184
def update(self):
185185
pass

lib/mysqlx/protocol.py

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,26 @@ def send_execute_statement(self, namespace, stmt, args):
164164
self._writer.write_message(MySQLx.ClientMessages.SQL_STMT_EXECUTE,
165165
stmt)
166166

167-
def send_doc_insert(self, schema, target, docs):
167+
def send_insert(self, statement):
168168
insert = MySQLxCrud.Insert(
169-
collection=MySQLxCrud.Collection(schema=schema, name=target),
170-
data_model=MySQLxCrud.DOCUMENT)
171-
for doc in docs:
169+
data_model=MySQLxCrud.DOCUMENT if statement._doc_based else MySQLxCrud.TABLE,
170+
collection=MySQLxCrud.Collection(name=statement.target.name, schema=statement.schema.name))
171+
if hasattr(statement, '_fields'):
172+
for field in statement._fields:
173+
insert.projection.extend([ExprParser(field, not statement._doc_based).parse_table_insert_field()])
174+
for value in statement._values:
172175
row = MySQLxCrud.Insert.TypedRow()
173-
o = self.arg_object_to_expr(doc, False)
174-
row.field.extend([o])
176+
if isinstance(value, list):
177+
for v in value:
178+
o = self.arg_object_to_expr(v, not statement._doc_based)
179+
row.field.extend([o])
180+
else:
181+
o = self.arg_object_to_expr(value, not statement._doc_based)
182+
row.field.extend([o])
175183
insert.row.extend([row])
176-
177184
self._writer.write_message(MySQLx.ClientMessages.CRUD_INSERT, insert)
178185

186+
179187
def _create_any(self, arg):
180188
if isinstance(arg, (str, unicode,)):
181189
val = MySQLxDatatypes.Scalar.String(value=arg)
@@ -253,21 +261,21 @@ def get_column_metadata(self, rs):
253261
def arg_object_to_expr(self, value, allow_relational):
254262
if value == None:
255263
return Expr.build_null_scalar()
256-
value_type = type(value)
257-
if value_type == type(True):
258-
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=ExprParser().build_bool_scalar(value))
264+
#value_type = type(value)
265+
if isinstance(value, bool):
266+
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_bool_scalar(value))
259267
elif isinstance(value, (int, long)):
260-
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=ExprParser().build_int_scalar(value))
268+
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_int_scalar(value))
261269
elif isinstance(value, (float)):
262-
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=ExprParser().build_double_scalar(value))
263-
elif value_type == type(str):
270+
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_double_scalar(value))
271+
elif isinstance(value, basestring):
264272
try:
265273
expression = ExprParser(value, allow_relational).expr()
266274
if expression.has_identifier():
267-
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=ExprParser().build_string_scalar(value))
275+
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_string_scalar(value))
268276
return expression
269277
except Exception as e:
270-
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=ExprParser().build_string_scalar(value))
278+
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_string_scalar(value))
271279
elif isinstance(value, DbDoc):
272280
return MySQLxExpr.Expr(type=MySQLxExpr.Expr.LITERAL, literal=build_string_scalar(str(value)))
273-
raise Exception("Unsupported type")
281+
raise Exception("Unsupported type: " + str(type(value)))

lib/mysqlx/statement.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,20 @@ def execute(self):
106106
class AddStatement(Statement):
107107
def __init__(self, collection):
108108
super(AddStatement, self).__init__(target=collection)
109-
self._docs = []
109+
self._values = []
110110

111111
def add(self, *values):
112112
for val in values:
113113
if isinstance(val, DbDoc):
114-
self._docs.append(val)
114+
self._values.append(val)
115115
else:
116-
self._docs.append(DbDoc(val))
116+
self._values.append(DbDoc(val))
117117
return self
118118

119119
def execute(self):
120-
for doc in self._docs:
120+
for doc in self._values:
121121
doc.ensure_id()
122-
return self._connection.send_doc_insert(self)
122+
return self._connection.send_insert(self)
123123

124124
class FindStatement(FilterableStatement):
125125
def __init__(self, collection, condition=None):
@@ -157,6 +157,19 @@ def execute(self):
157157
return self._connection.find(self)
158158

159159

160+
class InsertStatement(Statement):
161+
def __init__(self, table, *fields):
162+
super(InsertStatement, self).__init__(target=table, doc_based=False)
163+
self._fields = fields
164+
self._values = []
165+
166+
def values(self, *values):
167+
self._values.append(list(values))
168+
return self
169+
170+
def execute(self):
171+
return self._connection.send_insert(self)
172+
160173
class RemoveStatement(FilterableStatement):
161174
def __init__(self, collection):
162175
super(RemoveStatement, self).__init__(target=collection)

tests/test_mysqlx_crud.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,19 @@ def test_having(self):
361361
self.assertEqual(42, rows[0]["age"])
362362

363363
def test_insert(self):
364-
# TODO: To implement
365-
pass
364+
table = self.schema.get_table("test")
365+
366+
self.node_session.sql("CREATE TABLE {0}.test(age INT, name VARCHAR(50), gender CHAR(1))".format(self.schema_name)).execute()
367+
368+
result = table.insert("age", "name") \
369+
.values(21, 'Fred') \
370+
.values(28, 'Barney') \
371+
.values(42, 'Wilma') \
372+
.values(67, 'Betty').execute()
373+
374+
result = table.select().execute()
375+
rows = result.fetch_all()
376+
self.assertEqual(4, len(rows))
366377

367378
def test_update(self):
368379
# TODO: To implement

0 commit comments

Comments
 (0)