fixed mongodb issue 1401 and improvements, thanks Alan
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 2.4.5-stable+timestamp.2013.03.25.15.24.28
|
Version 2.4.5-stable+timestamp.2013.03.25.15.26.55
|
||||||
|
|||||||
+47
-18
@@ -122,6 +122,7 @@ Supported DAL URI strings:
|
|||||||
'google:sql' # for google app engine with sql (mysql compatible)
|
'google:sql' # for google app engine with sql (mysql compatible)
|
||||||
'teradata://DSN=dsn;UID=user;PWD=pass; DATABASE=database' # experimental
|
'teradata://DSN=dsn;UID=user;PWD=pass; DATABASE=database' # experimental
|
||||||
'imap://user:password@server:port' # experimental
|
'imap://user:password@server:port' # experimental
|
||||||
|
'mongodb://user:password@server:port/database' # experimental
|
||||||
|
|
||||||
For more info:
|
For more info:
|
||||||
help(DAL)
|
help(DAL)
|
||||||
@@ -1942,17 +1943,17 @@ class BaseAdapter(ConnectionPool):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
def parse_list_integers(self, value, field_type):
|
def parse_list_integers(self, value, field_type):
|
||||||
if not self.dbengine=='google:datastore':
|
if not self.dbengine in ('google:datastore', 'mongodb'):
|
||||||
value = bar_decode_integer(value)
|
value = bar_decode_integer(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def parse_list_references(self, value, field_type):
|
def parse_list_references(self, value, field_type):
|
||||||
if not self.dbengine=='google:datastore':
|
if not self.dbengine in ('google:datastore', 'mongodb'):
|
||||||
value = bar_decode_integer(value)
|
value = bar_decode_integer(value)
|
||||||
return [self.parse_reference(r, field_type[5:]) for r in value]
|
return [self.parse_reference(r, field_type[5:]) for r in value]
|
||||||
|
|
||||||
def parse_list_strings(self, value, field_type):
|
def parse_list_strings(self, value, field_type):
|
||||||
if not self.dbengine=='google:datastore':
|
if not self.dbengine in ('google:datastore', 'mongodb'):
|
||||||
value = bar_decode_string(value)
|
value = bar_decode_string(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@@ -5189,6 +5190,7 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
"Requires an integer or base 16 value")
|
"Requires an integer or base 16 value")
|
||||||
elif isinstance(arg, self.ObjectId):
|
elif isinstance(arg, self.ObjectId):
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
if not isinstance(arg, (int, long)):
|
if not isinstance(arg, (int, long)):
|
||||||
raise TypeError("object_id argument must be of type " +
|
raise TypeError("object_id argument must be of type " +
|
||||||
"ObjectId or an objectid representable integer")
|
"ObjectId or an objectid representable integer")
|
||||||
@@ -5198,8 +5200,26 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
hexvalue = hex(arg)[2:].replace("L", "")
|
hexvalue = hex(arg)[2:].replace("L", "")
|
||||||
return self.ObjectId(hexvalue)
|
return self.ObjectId(hexvalue)
|
||||||
|
|
||||||
|
def parse_reference(self, value, field_type):
|
||||||
|
# here we have to check for ObjectID before base parse
|
||||||
|
if isinstance(value, self.ObjectId):
|
||||||
|
value = int(str(value), 16)
|
||||||
|
return super(MongoDBAdapter,
|
||||||
|
self).parse_reference(value, field_type)
|
||||||
|
|
||||||
|
def parse_id(self, value, field_type):
|
||||||
|
if isinstance(value, self.ObjectId):
|
||||||
|
value = int(str(value), 16)
|
||||||
|
return super(MongoDBAdapter,
|
||||||
|
self).parse_id(value, field_type)
|
||||||
|
|
||||||
def represent(self, obj, fieldtype):
|
def represent(self, obj, fieldtype):
|
||||||
value = NoSQLAdapter.represent(self, obj, fieldtype)
|
# the base adatpter does not support MongoDB ObjectId
|
||||||
|
if isinstance(obj, self.ObjectId):
|
||||||
|
value = obj
|
||||||
|
else:
|
||||||
|
value = NoSQLAdapter.represent(self, obj, fieldtype)
|
||||||
|
# reference types must be convert to ObjectID
|
||||||
if fieldtype =='date':
|
if fieldtype =='date':
|
||||||
if value == None:
|
if value == None:
|
||||||
return value
|
return value
|
||||||
@@ -5216,15 +5236,24 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
# mongodb doesn't has a time object and so it must datetime,
|
# mongodb doesn't has a time object and so it must datetime,
|
||||||
# string or integer
|
# string or integer
|
||||||
return datetime.datetime.combine(d, value)
|
return datetime.datetime.combine(d, value)
|
||||||
elif fieldtype == 'list:string' or \
|
elif (isinstance(fieldtype, basestring) and
|
||||||
fieldtype == 'list:integer' or \
|
fieldtype.startswith('list:')):
|
||||||
fieldtype == 'list:reference':
|
if fieldtype.startswith('list:reference'):
|
||||||
|
newval = []
|
||||||
|
for v in value:
|
||||||
|
newval.append(self.object_id(v))
|
||||||
|
return newval
|
||||||
return value
|
return value
|
||||||
|
elif ((isinstance(fieldtype, basestring) and
|
||||||
|
fieldtype.startswith("reference")) or
|
||||||
|
(isinstance(fieldtype, Table))):
|
||||||
|
value = self.object_id(value)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
# Safe determines whether a asynchronious request is done or a
|
# Safe determines whether a asynchronious request is done or a
|
||||||
# synchronious action is done
|
# synchronious action is done
|
||||||
# For safety, we use by default synchronious requests
|
# For safety, we use by default synchronous requests
|
||||||
def insert(self, table, fields, safe=None):
|
def insert(self, table, fields, safe=None):
|
||||||
if safe==None:
|
if safe==None:
|
||||||
safe = self.safe
|
safe = self.safe
|
||||||
@@ -5272,14 +5301,18 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
if expression.first.type == 'id':
|
if expression.first.type == 'id':
|
||||||
expression.first.name = '_id'
|
expression.first.name = '_id'
|
||||||
# cast to Mongo ObjectId
|
# cast to Mongo ObjectId
|
||||||
expression.second = self.object_id(expression.second)
|
if isinstance(expression.second, (tuple, list, set)):
|
||||||
|
expression.second = [self.object_id(item) for
|
||||||
|
item in expression.second]
|
||||||
|
else:
|
||||||
|
expression.second = self.object_id(expression.second)
|
||||||
result = expression.op(expression.first, expression.second)
|
result = expression.op(expression.first, expression.second)
|
||||||
|
|
||||||
if isinstance(expression, Field):
|
if isinstance(expression, Field):
|
||||||
if expression.type=='id':
|
if expression.type=='id':
|
||||||
result = "_id"
|
result = "_id"
|
||||||
else:
|
else:
|
||||||
result = expression.name
|
result = expression.name
|
||||||
|
|
||||||
elif isinstance(expression, (Expression, Query)):
|
elif isinstance(expression, (Expression, Query)):
|
||||||
if not expression.second is None:
|
if not expression.second is None:
|
||||||
result = expression.op(expression.first, expression.second)
|
result = expression.op(expression.first, expression.second)
|
||||||
@@ -5290,7 +5323,7 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
else:
|
else:
|
||||||
result = expression.op
|
result = expression.op
|
||||||
elif field_type:
|
elif field_type:
|
||||||
result = str(self.represent(expression,field_type))
|
result = self.represent(expression,field_type)
|
||||||
elif isinstance(expression,(list,tuple)):
|
elif isinstance(expression,(list,tuple)):
|
||||||
result = ','.join(self.represent(item,field_type) for
|
result = ','.join(self.represent(item,field_type) for
|
||||||
item in expression)
|
item in expression)
|
||||||
@@ -5344,7 +5377,6 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
else:
|
else:
|
||||||
raise SyntaxError("The table name could not be found in " +
|
raise SyntaxError("The table name could not be found in " +
|
||||||
"the query nor from the select statement.")
|
"the query nor from the select statement.")
|
||||||
|
|
||||||
mongoqry_dict = self.expand(query)
|
mongoqry_dict = self.expand(query)
|
||||||
fields = fields or self.db[tablename]
|
fields = fields or self.db[tablename]
|
||||||
for field in fields:
|
for field in fields:
|
||||||
@@ -5394,15 +5426,12 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
# record id's
|
# record id's
|
||||||
if fieldname == "id": fieldname = "_id"
|
if fieldname == "id": fieldname = "_id"
|
||||||
if fieldname in record:
|
if fieldname in record:
|
||||||
if isinstance(record[fieldname],
|
value = record[fieldname]
|
||||||
self.ObjectId):
|
|
||||||
value = int(str(record[fieldname]), 16)
|
|
||||||
else:
|
|
||||||
value = record[fieldname]
|
|
||||||
else:
|
else:
|
||||||
value = None
|
value = None
|
||||||
row.append(value)
|
row.append(value)
|
||||||
rows.append(row)
|
rows.append(row)
|
||||||
|
|
||||||
processor = attributes.get('processor', self.parse)
|
processor = attributes.get('processor', self.parse)
|
||||||
result = processor(rows, fields, newnames, False)
|
result = processor(rows, fields, newnames, False)
|
||||||
return result
|
return result
|
||||||
@@ -5502,7 +5531,7 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
def BELONGS(self, first, second):
|
def BELONGS(self, first, second):
|
||||||
if isinstance(second, str):
|
if isinstance(second, str):
|
||||||
return {self.expand(first) : {"$in" : [ second[:-1]]} }
|
return {self.expand(first) : {"$in" : [ second[:-1]]} }
|
||||||
elif second==[] or second==():
|
elif second==[] or second==() or second==set():
|
||||||
return {1:0}
|
return {1:0}
|
||||||
items = [self.expand(item, first.type) for item in second]
|
items = [self.expand(item, first.type) for item in second]
|
||||||
return {self.expand(first) : {"$in" : items} }
|
return {self.expand(first) : {"$in" : items} }
|
||||||
|
|||||||
Reference in New Issue
Block a user