fixed issue 604
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 1.99.4 (2012-01-06 22:57:17) stable
|
Version 1.99.4 (2012-01-12 12:27:44) stable
|
||||||
|
|||||||
+181
-241
@@ -195,14 +195,14 @@ thread = threading.local()
|
|||||||
# internal representation of tables with field
|
# internal representation of tables with field
|
||||||
# <table>.<field>, tables and fields may only be [a-zA-Z0-0_]
|
# <table>.<field>, tables and fields may only be [a-zA-Z0-0_]
|
||||||
|
|
||||||
|
regex_type = re.compile('^([\w\_\:]+)')
|
||||||
regex_dbname = re.compile('^(\w+)(\:\w+)*')
|
regex_dbname = re.compile('^(\w+)(\:\w+)*')
|
||||||
table_field = re.compile('^([\w_]+)\.([\w_]+)$')
|
regex_table_field = re.compile('^([\w_]+)\.([\w_]+)$')
|
||||||
regex_content = re.compile('(?P<table>[\w\-]+)\.(?P<field>[\w\-]+)\.(?P<uuidkey>[\w\-]+)\.(?P<name>\w+)\.\w+$')
|
regex_content = re.compile('(?P<table>[\w\-]+)\.(?P<field>[\w\-]+)\.(?P<uuidkey>[\w\-]+)\.(?P<name>\w+)\.\w+$')
|
||||||
regex_cleanup_fn = re.compile('[\'"\s;]+')
|
regex_cleanup_fn = re.compile('[\'"\s;]+')
|
||||||
string_unpack=re.compile('(?<!\|)\|(?!\|)')
|
string_unpack=re.compile('(?<!\|)\|(?!\|)')
|
||||||
regex_python_keywords = re.compile('^(and|del|from|not|while|as|elif|global|or|with|assert|else|if|pass|yield|break|except|import|print|class|exec|in|raise|continue|finally|is|return|def|for|lambda|try)$')
|
regex_python_keywords = re.compile('^(and|del|from|not|while|as|elif|global|or|with|assert|else|if|pass|yield|break|except|import|print|class|exec|in|raise|continue|finally|is|return|def|for|lambda|try)$')
|
||||||
|
regex_select_as_parser = re.compile("\s+AS\s+(\S+)")
|
||||||
|
|
||||||
|
|
||||||
# list of drivers will be built on the fly
|
# list of drivers will be built on the fly
|
||||||
# and lists only what is available
|
# and lists only what is available
|
||||||
@@ -1141,37 +1141,39 @@ class BaseAdapter(ConnectionPool):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError, "Too many tables selected"
|
raise RuntimeError, "Too many tables selected"
|
||||||
|
|
||||||
def _select(self, query, fields, attributes):
|
def expand_all(self, fields, tablenames):
|
||||||
for key in set(attributes.keys())-set(('orderby', 'groupby', 'limitby',
|
|
||||||
'required', 'cache', 'left',
|
|
||||||
'distinct', 'having', 'join',
|
|
||||||
'for_update')):
|
|
||||||
raise SyntaxError, 'invalid select attribute: %s' % key
|
|
||||||
# ## if no fields specified take them all from the requested tables
|
|
||||||
new_fields = []
|
new_fields = []
|
||||||
for item in fields:
|
for item in fields:
|
||||||
if isinstance(item,SQLALL):
|
if isinstance(item,SQLALL):
|
||||||
new_fields += item.table
|
new_fields += item.table
|
||||||
else:
|
else:
|
||||||
new_fields.append(item)
|
new_fields.append(item)
|
||||||
fields = new_fields
|
# ## if no fields specified take them all from the requested tables
|
||||||
tablenames = self.tables(query)
|
if not new_fields:
|
||||||
|
for table in tablenames:
|
||||||
|
for field in self.db[table]:
|
||||||
|
new_fields.append(field)
|
||||||
|
return new_fields
|
||||||
|
|
||||||
|
def _select(self, query, fields, attributes):
|
||||||
|
for key in set(attributes.keys())-set(('orderby', 'groupby', 'limitby',
|
||||||
|
'required', 'cache', 'left',
|
||||||
|
'distinct', 'having', 'join',
|
||||||
|
'for_update')):
|
||||||
|
raise SyntaxError, 'invalid select attribute: %s' % key
|
||||||
|
|
||||||
|
tablenames = self.tables(query)
|
||||||
|
for field in fields:
|
||||||
|
if isinstance(field, basestring) and regex_table_field.match(field):
|
||||||
|
tn,fn = field.split('.')
|
||||||
|
field = self.db[tn][fn]
|
||||||
|
for tablename in self.tables(field):
|
||||||
|
if not tablename in tablenames:
|
||||||
|
tablenames.append(tablename)
|
||||||
|
|
||||||
if query and not query.ignore_common_filters:
|
if query and not query.ignore_common_filters:
|
||||||
query = self.common_filter(query,tablenames)
|
query = self.common_filter(query,tablenames)
|
||||||
|
|
||||||
if not fields:
|
|
||||||
for table in tablenames:
|
|
||||||
for field in self.db[table]:
|
|
||||||
fields.append(field)
|
|
||||||
else:
|
|
||||||
for field in fields:
|
|
||||||
if isinstance(field, basestring) and table_field.match(field):
|
|
||||||
tn,fn = field.split('.')
|
|
||||||
field = self.db[tn][fn]
|
|
||||||
for tablename in self.tables(field):
|
|
||||||
if not tablename in tablenames:
|
|
||||||
tablenames.append(tablename)
|
|
||||||
if len(tablenames) < 1:
|
if len(tablenames) < 1:
|
||||||
raise SyntaxError, 'Set: no tables selected'
|
raise SyntaxError, 'Set: no tables selected'
|
||||||
sql_f = ', '.join(map(self.expand, fields))
|
sql_f = ', '.join(map(self.expand, fields))
|
||||||
@@ -1289,7 +1291,7 @@ class BaseAdapter(ConnectionPool):
|
|||||||
rows = list(rows)
|
rows = list(rows)
|
||||||
limitby = attributes.get('limitby', None) or (0,)
|
limitby = attributes.get('limitby', None) or (0,)
|
||||||
rows = self.rowslice(rows,limitby[0],None)
|
rows = self.rowslice(rows,limitby[0],None)
|
||||||
return self.parse(rows,self._colnames)
|
return self.parse(rows,fields,self._colnames)
|
||||||
|
|
||||||
def _count(self, query, distinct=None):
|
def _count(self, query, distinct=None):
|
||||||
tablenames = self.tables(query)
|
tablenames = self.tables(query)
|
||||||
@@ -1443,7 +1445,97 @@ class BaseAdapter(ConnectionPool):
|
|||||||
""" By default this function does nothing; overload when db does not do slicing. """
|
""" By default this function does nothing; overload when db does not do slicing. """
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
def parse(self, rows, colnames, blob_decode=True):
|
def parse_value(self, value, field_type):
|
||||||
|
if field_type != 'blob' and isinstance(value, str):
|
||||||
|
try:
|
||||||
|
value = value.decode(db._db_codec)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
if isinstance(value, unicode):
|
||||||
|
value = value.encode('utf-8')
|
||||||
|
if isinstance(field_type, SQLCustomType):
|
||||||
|
value = field_type.decoder(value)
|
||||||
|
elif not isinstance(field_type, str) or value is None:
|
||||||
|
return value
|
||||||
|
if field_type in ('string', 'text', 'password', 'upload'):
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
key = regex_type.match(field_type).group(0)
|
||||||
|
return getattr(self,'parse_'+key)(value,field_type)
|
||||||
|
|
||||||
|
def parse_reference(self, value, field_type):
|
||||||
|
referee = field_type[10:].strip()
|
||||||
|
if not '.' in referee:
|
||||||
|
value = Reference(value)
|
||||||
|
value._table, value._record = self.db[referee], None
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_boolean(self, value, field_type):
|
||||||
|
return value == True or str(value)[:1].lower() == 't'
|
||||||
|
|
||||||
|
def parse_date(self, value, field_type):
|
||||||
|
if not isinstance(value, (datetime.date,datetime.datetime)):
|
||||||
|
(y, m, d) = map(int, str(value)[:10].strip().split('-'))
|
||||||
|
value = datetime.date(y, m, d)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_time(self, value, field_type):
|
||||||
|
if not isinstance(value, datetime.time):
|
||||||
|
time_items = map(int,str(value)[:8].strip().split(':')[:3])
|
||||||
|
if len(time_items) == 3:
|
||||||
|
(h, mi, s) = time_items
|
||||||
|
else:
|
||||||
|
(h, mi, s) = time_items + [0]
|
||||||
|
value = datetime.time(h, mi, s)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_datetime(self, value, field_type):
|
||||||
|
if not isinstance(value, datetime.datetime):
|
||||||
|
(y, m, d) = map(int,str(value)[:10].strip().split('-'))
|
||||||
|
time_items = map(int,str(value)[11:19].strip().split(':')[:3])
|
||||||
|
if len(time_items) == 3:
|
||||||
|
(h, mi, s) = time_items
|
||||||
|
else:
|
||||||
|
(h, mi, s) = time_items + [0]
|
||||||
|
value = datetime.datetime(y, m, d, h, mi, s)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_blob(self, value, field_type):
|
||||||
|
return base64.b64decode(str(value))
|
||||||
|
|
||||||
|
def parse_decimal(self, value, field_type):
|
||||||
|
decimals = int(field_type[8:-1].split(',')[-1])
|
||||||
|
if self.dbengine == 'sqlite':
|
||||||
|
value = ('%.' + str(decimals) + 'f') % value
|
||||||
|
if not isinstance(value, decimal.Decimal):
|
||||||
|
value = decimal.Decimal(str(value))
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_list_integers(self, value, field_type):
|
||||||
|
if not self.dbengine=='google:datastore':
|
||||||
|
value = bar_decode_integer(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_list_references(self, value, field_type):
|
||||||
|
if not self.dbengine=='google:datastore':
|
||||||
|
value = bar_decode_integer(value)
|
||||||
|
return [self.parse_reference(r, field_type[5:]) for r in value]
|
||||||
|
|
||||||
|
def parse_list_strings(self, value, field_type):
|
||||||
|
if not self.dbengine=='google:datastore':
|
||||||
|
value = bar_decode_string(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_id(self, value, field_type):
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
def parse_integer(self, value, field_type):
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
def parse_double(self, value, field_type):
|
||||||
|
return float(value)
|
||||||
|
|
||||||
|
def parse(self, rows, fields, colnames, blob_decode=True):
|
||||||
db = self.db
|
db = self.db
|
||||||
virtualtables = []
|
virtualtables = []
|
||||||
new_rows = []
|
new_rows = []
|
||||||
@@ -1451,114 +1543,37 @@ class BaseAdapter(ConnectionPool):
|
|||||||
new_row = Row()
|
new_row = Row()
|
||||||
for j,colname in enumerate(colnames):
|
for j,colname in enumerate(colnames):
|
||||||
value = row[j]
|
value = row[j]
|
||||||
if not table_field.match(colnames[j]):
|
if not regex_table_field.match(colnames[j]):
|
||||||
if not '_extra' in new_row:
|
if not '_extra' in new_row:
|
||||||
new_row['_extra'] = Row()
|
new_row['_extra'] = Row()
|
||||||
new_row['_extra'][colnames[j]] = value
|
new_row['_extra'][colnames[j]] = self.parse_value(value, fields[j].type)
|
||||||
select_as_parser = re.compile("\s+AS\s+(\S+)")
|
new_column_name = regex_select_as_parser.search(colnames[j])
|
||||||
new_column_name = select_as_parser.search(colnames[j])
|
|
||||||
if not new_column_name is None:
|
if not new_column_name is None:
|
||||||
column_name = new_column_name.groups(0)
|
column_name = new_column_name.groups(0)
|
||||||
setattr(new_row,column_name[0],value)
|
setattr(new_row,column_name[0],value)
|
||||||
continue
|
|
||||||
(tablename, fieldname) = colname.split('.')
|
|
||||||
table = db[tablename]
|
|
||||||
field = table[fieldname]
|
|
||||||
field_type = field.type
|
|
||||||
if field.type != 'blob' and isinstance(value, str):
|
|
||||||
try:
|
|
||||||
value = value.decode(db._db_codec)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
if isinstance(value, unicode):
|
|
||||||
value = value.encode('utf-8')
|
|
||||||
if not tablename in new_row:
|
|
||||||
colset = new_row[tablename] = Row()
|
|
||||||
if tablename not in virtualtables:
|
|
||||||
virtualtables.append(tablename)
|
|
||||||
else:
|
else:
|
||||||
colset = new_row[tablename]
|
(tablename, fieldname) = colname.split('.')
|
||||||
|
table = db[tablename]
|
||||||
|
field = table[fieldname]
|
||||||
|
if not tablename in new_row:
|
||||||
|
colset = new_row[tablename] = Row()
|
||||||
|
if tablename not in virtualtables:
|
||||||
|
virtualtables.append(tablename)
|
||||||
|
else:
|
||||||
|
colset = new_row[tablename]
|
||||||
|
colset[fieldname] = value = self.parse_value(value,field.type)
|
||||||
|
|
||||||
if isinstance(field_type, SQLCustomType):
|
if field.type == 'id':
|
||||||
colset[fieldname] = field_type.decoder(value)
|
id = value
|
||||||
# field_type = field_type.type
|
colset.update_record = lambda _ = (colset, table, id), **a: update_record(_, a)
|
||||||
elif not isinstance(field_type, str) or value is None:
|
colset.delete_record = lambda t = table, i = id: t._db(t._id==i).delete()
|
||||||
colset[fieldname] = value
|
for (referee_table, referee_name) in table._referenced_by:
|
||||||
elif isinstance(field_type, str) and \
|
s = db[referee_table][referee_name]
|
||||||
field_type.startswith('reference'):
|
referee_link = db._referee_name and \
|
||||||
referee = field_type[10:].strip()
|
db._referee_name % dict(table=referee_table,field=referee_name)
|
||||||
if not '.' in referee:
|
if referee_link and not referee_link in colset:
|
||||||
colset[fieldname] = rid = Reference(value)
|
colset[referee_link] = Set(db, s == id)
|
||||||
(rid._table, rid._record) = (db[referee], None)
|
|
||||||
else: ### reference not by id
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type == 'boolean':
|
|
||||||
if value == True or str(value)[:1].lower() == 't':
|
|
||||||
colset[fieldname] = True
|
|
||||||
else:
|
|
||||||
colset[fieldname] = False
|
|
||||||
elif field_type == 'date' \
|
|
||||||
and (not isinstance(value, datetime.date)\
|
|
||||||
or isinstance(value, datetime.datetime)):
|
|
||||||
(y, m, d) = map(int, str(value)[:10].strip().split('-'))
|
|
||||||
colset[fieldname] = datetime.date(y, m, d)
|
|
||||||
elif field_type == 'time' \
|
|
||||||
and not isinstance(value, datetime.time):
|
|
||||||
time_items = map(int,str(value)[:8].strip().split(':')[:3])
|
|
||||||
if len(time_items) == 3:
|
|
||||||
(h, mi, s) = time_items
|
|
||||||
else:
|
|
||||||
(h, mi, s) = time_items + [0]
|
|
||||||
colset[fieldname] = datetime.time(h, mi, s)
|
|
||||||
elif field_type == 'datetime'\
|
|
||||||
and not isinstance(value, datetime.datetime):
|
|
||||||
(y, m, d) = map(int,str(value)[:10].strip().split('-'))
|
|
||||||
time_items = map(int,str(value)[11:19].strip().split(':')[:3])
|
|
||||||
if len(time_items) == 3:
|
|
||||||
(h, mi, s) = time_items
|
|
||||||
else:
|
|
||||||
(h, mi, s) = time_items + [0]
|
|
||||||
colset[fieldname] = datetime.datetime(y, m, d, h, mi, s)
|
|
||||||
elif field_type == 'blob' and blob_decode:
|
|
||||||
colset[fieldname] = base64.b64decode(str(value))
|
|
||||||
elif field_type.startswith('decimal'):
|
|
||||||
decimals = int(field_type[8:-1].split(',')[-1])
|
|
||||||
if self.dbengine == 'sqlite':
|
|
||||||
value = ('%.' + str(decimals) + 'f') % value
|
|
||||||
if not isinstance(value, decimal.Decimal):
|
|
||||||
value = decimal.Decimal(str(value))
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type.startswith('list:integer'):
|
|
||||||
if not self.dbengine=='google:datastore':
|
|
||||||
colset[fieldname] = bar_decode_integer(value)
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type.startswith('list:reference'):
|
|
||||||
if not self.dbengine=='google:datastore':
|
|
||||||
colset[fieldname] = bar_decode_integer(value)
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type.startswith('list:string'):
|
|
||||||
if not self.dbengine=='google:datastore':
|
|
||||||
colset[fieldname] = bar_decode_string(value)
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
if field_type == 'id':
|
|
||||||
id = colset[field.name]
|
|
||||||
colset.update_record = lambda _ = (colset, table, id), **a: update_record(_, a)
|
|
||||||
colset.delete_record = lambda t = table, i = id: t._db(t._id==i).delete()
|
|
||||||
for (referee_table, referee_name) in \
|
|
||||||
table._referenced_by:
|
|
||||||
s = db[referee_table][referee_name]
|
|
||||||
referee_link = db._referee_name and \
|
|
||||||
db._referee_name % dict(table=referee_table,field=referee_name)
|
|
||||||
if referee_link and not referee_link in colset:
|
|
||||||
colset[referee_link] = Set(db, s == id)
|
|
||||||
colset['id'] = id
|
|
||||||
new_rows.append(new_row)
|
new_rows.append(new_row)
|
||||||
|
|
||||||
rowsobj = Rows(db, new_rows, colnames, rawrows=rows)
|
rowsobj = Rows(db, new_rows, colnames, rawrows=rows)
|
||||||
|
|
||||||
for tablename in virtualtables:
|
for tablename in virtualtables:
|
||||||
@@ -3480,7 +3495,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
|||||||
item.key().name()) or getattr(item, t) for t in fields]
|
item.key().name()) or getattr(item, t) for t in fields]
|
||||||
for item in items]
|
for item in items]
|
||||||
colnames = ['%s.%s' % (tablename, t) for t in fields]
|
colnames = ['%s.%s' % (tablename, t) for t in fields]
|
||||||
return self.parse(rows, colnames, False)
|
return self.parse(rows, fields, colnames, False)
|
||||||
|
|
||||||
|
|
||||||
def count(self,query,distinct=None):
|
def count(self,query,distinct=None):
|
||||||
@@ -3674,7 +3689,7 @@ class CouchDBAdapter(NoSQLAdapter):
|
|||||||
tablename = colnames[0].split('.')[0]
|
tablename = colnames[0].split('.')[0]
|
||||||
ctable = self.connection[tablename]
|
ctable = self.connection[tablename]
|
||||||
rows = [cols['value'] for cols in ctable.query(fn)]
|
rows = [cols['value'] for cols in ctable.query(fn)]
|
||||||
return self.parse(rows, colnames, False)
|
return self.parse(rows, fields, colnames, False)
|
||||||
|
|
||||||
def delete(self,tablename,query):
|
def delete(self,tablename,query):
|
||||||
if not isinstance(query,Query):
|
if not isinstance(query,Query):
|
||||||
@@ -3967,9 +3982,9 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
#print "colnames = %s" % colnames
|
#print "colnames = %s" % colnames
|
||||||
#rows = [row.values() for row in mongo_list_dicts]
|
#rows = [row.values() for row in mongo_list_dicts]
|
||||||
rows = mongo_list_dicts
|
rows = mongo_list_dicts
|
||||||
return self.parse(rows, mongofields_dict.keys(), False, tablename)
|
return self.parse(rows, fields, mongofields_dict.keys(), False, tablename)
|
||||||
|
|
||||||
def parse(self, rows, colnames, blob_decode=True,tablename=None):
|
def parse(self, rows, fields, colnames, blob_decode=True,tablename=None):
|
||||||
import pymongo.objectid
|
import pymongo.objectid
|
||||||
print "in parse"
|
print "in parse"
|
||||||
print "colnames=%s" % colnames
|
print "colnames=%s" % colnames
|
||||||
@@ -4000,118 +4015,39 @@ class MongoDBAdapter(NoSQLAdapter):
|
|||||||
colname = "%s.%s" % (tablename, colname) # hack to match re (table_field)
|
colname = "%s.%s" % (tablename, colname) # hack to match re (table_field)
|
||||||
if i == 0: #only on first row
|
if i == 0: #only on first row
|
||||||
table_colnames.append(colname)
|
table_colnames.append(colname)
|
||||||
if not table_field.match(colname):
|
|
||||||
|
|
||||||
|
if not regex_table_field.match(colnames[j]):
|
||||||
if not '_extra' in new_row:
|
if not '_extra' in new_row:
|
||||||
new_row['_extra'] = Row()
|
new_row['_extra'] = Row()
|
||||||
new_row['_extra'][colnames[j]] = value
|
new_row['_extra'][colnames[j]] = self.parse_value(value, fields[j].type)
|
||||||
select_as_parser = re.compile("\s+AS\s+(\S+)")
|
new_column_name = regex_select_as_parser.search(colnames[j])
|
||||||
new_column_name = select_as_parser.search(colnames[j])
|
|
||||||
if not new_column_name is None:
|
if not new_column_name is None:
|
||||||
column_name = new_column_name.groups(0)
|
column_name = new_column_name.groups(0)
|
||||||
setattr(new_row,column_name[0],value)
|
setattr(new_row,column_name[0],value)
|
||||||
continue
|
|
||||||
(tablename, fieldname) = colname.split('.')
|
|
||||||
table = db[tablename]
|
|
||||||
field = table[fieldname]
|
|
||||||
field_type = field.type
|
|
||||||
# hack to get past field_type = 'id'
|
|
||||||
#if field_type == 'id': field_type = '_id'
|
|
||||||
print "field = %s, type = %s" % (field, field_type)
|
|
||||||
if field.type != 'blob' and isinstance(value, str):
|
|
||||||
try:
|
|
||||||
value = value.decode(db._db_codec)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
if isinstance(value, unicode):
|
|
||||||
value = value.encode('utf-8')
|
|
||||||
if not tablename in new_row:
|
|
||||||
colset = new_row[tablename] = Row()
|
|
||||||
if tablename not in virtualtables:
|
|
||||||
virtualtables.append(tablename)
|
|
||||||
else:
|
else:
|
||||||
colset = new_row[tablename]
|
(tablename, fieldname) = colname.split('.')
|
||||||
|
table = db[tablename]
|
||||||
|
field = table[fieldname]
|
||||||
|
if not tablename in new_row:
|
||||||
|
colset = new_row[tablename] = Row()
|
||||||
|
if tablename not in virtualtables:
|
||||||
|
virtualtables.append(tablename)
|
||||||
|
else:
|
||||||
|
colset = new_row[tablename]
|
||||||
|
colset[fieldname] = value = self.parse_value(value,field.type)
|
||||||
|
|
||||||
|
if field.type == 'id':
|
||||||
|
id = value
|
||||||
|
colset.update_record = lambda _ = (colset, table, id), **a: update_record(_, a)
|
||||||
|
colset.delete_record = lambda t = table, i = id: t._db(t._id==i).delete()
|
||||||
|
for (referee_table, referee_name) in table._referenced_by:
|
||||||
|
s = db[referee_table][referee_name]
|
||||||
|
referee_link = db._referee_name and \
|
||||||
|
db._referee_name % dict(table=referee_table,field=referee_name)
|
||||||
|
if referee_link and not referee_link in colset:
|
||||||
|
colset[referee_link] = Set(db, s == id)
|
||||||
|
|
||||||
if isinstance(field_type, SQLCustomType):
|
|
||||||
colset[fieldname] = field_type.decoder(value)
|
|
||||||
# field_type = field_type.type
|
|
||||||
elif not isinstance(field_type, str) or value is None:
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif isinstance(field_type, str) and \
|
|
||||||
field_type.startswith('reference'):
|
|
||||||
referee = field_type[10:].strip()
|
|
||||||
if not '.' in referee:
|
|
||||||
colset[fieldname] = rid = Reference(value)
|
|
||||||
(rid._table, rid._record) = (db[referee], None)
|
|
||||||
else: ### reference not by id
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type == 'boolean':
|
|
||||||
if value == True or str(value)[:1].lower() == 't':
|
|
||||||
colset[fieldname] = True
|
|
||||||
else:
|
|
||||||
colset[fieldname] = False
|
|
||||||
elif field_type == 'date' \
|
|
||||||
and (not isinstance(value, datetime.date)\
|
|
||||||
or isinstance(value, datetime.datetime)):
|
|
||||||
(y, m, d) = map(int, str(value)[:10].strip().split('-'))
|
|
||||||
colset[fieldname] = datetime.date(y, m, d)
|
|
||||||
elif field_type == 'time' \
|
|
||||||
and not isinstance(value, datetime.time): #psr pymongo time as datetime
|
|
||||||
if isinstance(value,datetime.datetime):
|
|
||||||
colset[fieldname] = value.time()
|
|
||||||
else:
|
|
||||||
time_items = map(int,str(value)[:8].strip().split(':')[:3])
|
|
||||||
if len(time_items) == 3:
|
|
||||||
(h, mi, s) = time_items
|
|
||||||
else:
|
|
||||||
(h, mi, s) = time_items + [0]
|
|
||||||
colset[fieldname] = datetime.time(h, mi, s)
|
|
||||||
elif field_type == 'datetime'\
|
|
||||||
and not isinstance(value, datetime.datetime):
|
|
||||||
(y, m, d) = map(int,str(value)[:10].strip().split('-'))
|
|
||||||
time_items = map(int,str(value)[11:19].strip().split(':')[:3])
|
|
||||||
if len(time_items) == 3:
|
|
||||||
(h, mi, s) = time_items
|
|
||||||
else:
|
|
||||||
(h, mi, s) = time_items + [0]
|
|
||||||
colset[fieldname] = datetime.datetime(y, m, d, h, mi, s)
|
|
||||||
elif field_type == 'blob' and blob_decode:
|
|
||||||
colset[fieldname] = base64.b64decode(str(value))
|
|
||||||
elif field_type.startswith('decimal'):
|
|
||||||
decimals = int(field_type[8:-1].split(',')[-1])
|
|
||||||
if self.dbengine == 'sqlite':
|
|
||||||
value = ('%.' + str(decimals) + 'f') % value
|
|
||||||
if not isinstance(value, decimal.Decimal):
|
|
||||||
value = decimal.Decimal(str(value))
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type.startswith('list:integer'):
|
|
||||||
if not self.dbengine=='google:datastore' and not self.dbengine=='mongodb': #<-- comparation to google datastore is kinda unnessarly
|
|
||||||
colset[fieldname] = bar_decode_integer(value)
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type.startswith('list:reference'):
|
|
||||||
if not self.dbengine=='google:datastore' and not self.dbengine=='mongodb': #<-- comparation to google datastore is kinda unnessarly
|
|
||||||
colset[fieldname] = bar_decode_integer(value)
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
elif field_type.startswith('list:string'):
|
|
||||||
if not self.dbengine=='google:datastore' and not self.dbengine=='mongodb': #<-- comparation to google datastore is kinda unnessarly
|
|
||||||
colset[fieldname] = bar_decode_string(value)
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
else:
|
|
||||||
colset[fieldname] = value
|
|
||||||
if field_type == 'id':
|
|
||||||
id = colset[field.name]
|
|
||||||
colset.update_record = lambda _ = (colset, table, id), **a: update_record(_, a)
|
|
||||||
colset.delete_record = lambda t = table, i = id: t._db(t._id==i).delete()
|
|
||||||
for (referee_table, referee_name) in \
|
|
||||||
table._referenced_by:
|
|
||||||
s = db[referee_table][referee_name]
|
|
||||||
referee_link = db._referee_name and \
|
|
||||||
db._referee_name % dict(table=referee_table,field=referee_name)
|
|
||||||
if referee_link and not referee_link in colset:
|
|
||||||
colset[referee_link] = Set(db, s == id)
|
|
||||||
colset['id'] = id
|
|
||||||
new_rows.append(new_row)
|
new_rows.append(new_row)
|
||||||
print "table_colnames = %s" % table_colnames
|
print "table_colnames = %s" % table_colnames
|
||||||
rowsobj = Rows(db, new_rows, table_colnames, rawrows=rows)
|
rowsobj = Rows(db, new_rows, table_colnames, rawrows=rows)
|
||||||
@@ -4433,7 +4369,7 @@ class Row(dict):
|
|||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
key=str(key)
|
key=str(key)
|
||||||
m = table_field.match(key)
|
m = regex_table_field.match(key)
|
||||||
if key in self.get('_extra',{}):
|
if key in self.get('_extra',{}):
|
||||||
return self._extra[key]
|
return self._extra[key]
|
||||||
elif m:
|
elif m:
|
||||||
@@ -6334,7 +6270,9 @@ class Set(object):
|
|||||||
return self.db._adapter._count(self.query,distinct)
|
return self.db._adapter._count(self.query,distinct)
|
||||||
|
|
||||||
def _select(self, *fields, **attributes):
|
def _select(self, *fields, **attributes):
|
||||||
return self.db._adapter._select(self.query,fields,attributes)
|
adapter = self.db._adapter
|
||||||
|
fields = adapter.expand_all(fields, adapter.tables(self.query))
|
||||||
|
return adapter._select(self.query,fields,attributes)
|
||||||
|
|
||||||
def _delete(self):
|
def _delete(self):
|
||||||
tablename=self.db._adapter.get_table(self.query)
|
tablename=self.db._adapter.get_table(self.query)
|
||||||
@@ -6351,8 +6289,10 @@ class Set(object):
|
|||||||
def count(self,distinct=None):
|
def count(self,distinct=None):
|
||||||
return self.db._adapter.count(self.query,distinct)
|
return self.db._adapter.count(self.query,distinct)
|
||||||
|
|
||||||
def select(self, *fields, **attributes):
|
def select(self, *fields, **attributes):
|
||||||
return self.db._adapter.select(self.query,fields,attributes)
|
adapter = self.db._adapter
|
||||||
|
fields = adapter.expand_all(fields, adapter.tables(self.query))
|
||||||
|
return adapter.select(self.query,fields,attributes)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
tablename=self.db._adapter.get_table(self.query)
|
tablename=self.db._adapter.get_table(self.query)
|
||||||
@@ -6687,7 +6627,7 @@ class Rows(object):
|
|||||||
for record in self:
|
for record in self:
|
||||||
row = []
|
row = []
|
||||||
for col in colnames:
|
for col in colnames:
|
||||||
if not table_field.match(col):
|
if not regex_table_field.match(col):
|
||||||
row.append(record._extra[col])
|
row.append(record._extra[col])
|
||||||
else:
|
else:
|
||||||
(t, f) = col.split('.')
|
(t, f) = col.split('.')
|
||||||
@@ -6722,7 +6662,7 @@ class Rows(object):
|
|||||||
def inner_loop(record, col):
|
def inner_loop(record, col):
|
||||||
(t, f) = col.split('.')
|
(t, f) = col.split('.')
|
||||||
res = None
|
res = None
|
||||||
if not table_field.match(col):
|
if not regex_table_field.match(col):
|
||||||
key = col
|
key = col
|
||||||
res = record._extra[col]
|
res = record._extra[col]
|
||||||
else:
|
else:
|
||||||
|
|||||||
+1
-1
@@ -1592,7 +1592,7 @@ class SQLFORM(FORM):
|
|||||||
check_authorization()
|
check_authorization()
|
||||||
table = db[request.args[-2]]
|
table = db[request.args[-2]]
|
||||||
if ondelete:
|
if ondelete:
|
||||||
ondelete(table,request.args[-1],ret)
|
ondelete(table,request.args[-1])
|
||||||
ret = db(table.id==request.args[-1]).delete()
|
ret = db(table.id==request.args[-1]).delete()
|
||||||
return ret
|
return ret
|
||||||
elif csv and len(request.args)>0 and request.args[-1]=='csv':
|
elif csv and len(request.args)>0 and request.args[-1]=='csv':
|
||||||
|
|||||||
Reference in New Issue
Block a user