fix for recursive selects on lazy tables
This commit is contained in:
+40
-6
@@ -2083,7 +2083,7 @@ class BaseAdapter(ConnectionPool):
|
|||||||
if not REGEX_TABLE_DOT_FIELD.match(colname):
|
if not REGEX_TABLE_DOT_FIELD.match(colname):
|
||||||
tmps.append(None)
|
tmps.append(None)
|
||||||
else:
|
else:
|
||||||
(tablename, fieldname) = colname.split('.')
|
(tablename, _the_sep_, fieldname) = colname.partition('.')
|
||||||
table = db[tablename]
|
table = db[tablename]
|
||||||
field = table[fieldname]
|
field = table[fieldname]
|
||||||
ft = field.type
|
ft = field.type
|
||||||
@@ -2123,6 +2123,8 @@ class BaseAdapter(ConnectionPool):
|
|||||||
id = value
|
id = value
|
||||||
colset.update_record = RecordUpdater(colset,table,id)
|
colset.update_record = RecordUpdater(colset,table,id)
|
||||||
colset.delete_record = RecordDeleter(table,id)
|
colset.delete_record = RecordDeleter(table,id)
|
||||||
|
if table._db._lazy_tables:
|
||||||
|
colset['__get_lazy_reference__'] = LazyReferenceGetter(table, id)
|
||||||
for rfield in table._referenced_by:
|
for rfield in table._referenced_by:
|
||||||
referee_link = db._referee_name and \
|
referee_link = db._referee_name and \
|
||||||
db._referee_name % dict(
|
db._referee_name % dict(
|
||||||
@@ -7000,7 +7002,13 @@ class Row(object):
|
|||||||
return ogetattr(self, m.group(1))[m.group(2)]
|
return ogetattr(self, m.group(1))[m.group(2)]
|
||||||
except (KeyError,AttributeError,TypeError):
|
except (KeyError,AttributeError,TypeError):
|
||||||
key = m.group(2)
|
key = m.group(2)
|
||||||
return ogetattr(self, key)
|
try:
|
||||||
|
return ogetattr(self, key)
|
||||||
|
except (KeyError,AttributeError,TypeError), ae:
|
||||||
|
try:
|
||||||
|
return self.__get_lazy_reference__(key)
|
||||||
|
except:
|
||||||
|
raise ae
|
||||||
|
|
||||||
__setitem__ = lambda self, key, value: setattr(self, str(key), value)
|
__setitem__ = lambda self, key, value: setattr(self, str(key), value)
|
||||||
|
|
||||||
@@ -7010,8 +7018,12 @@ class Row(object):
|
|||||||
|
|
||||||
__call__ = __getitem__
|
__call__ = __getitem__
|
||||||
|
|
||||||
get = lambda self, key, default=None: self.__dict__.get(key,default)
|
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
try:
|
||||||
|
return self.__getitem__(key)
|
||||||
|
except(KeyError, AttributeError, TypeError):
|
||||||
|
return self.__dict__.get(key,default)
|
||||||
|
|
||||||
has_key = __contains__ = lambda self, key: key in self.__dict__
|
has_key = __contains__ = lambda self, key: key in self.__dict__
|
||||||
|
|
||||||
@@ -7035,6 +7047,16 @@ class Row(object):
|
|||||||
|
|
||||||
__long__ = lambda self: long(object.__getattribute__(self,'id'))
|
__long__ = lambda self: long(object.__getattribute__(self,'id'))
|
||||||
|
|
||||||
|
__getattr__ = __getitem__
|
||||||
|
|
||||||
|
def __getattribute__(self, key):
|
||||||
|
try:
|
||||||
|
return object.__getattribute__(self, key)
|
||||||
|
except AttributeError, ae:
|
||||||
|
try:
|
||||||
|
return self.__get_lazy_reference__(key)
|
||||||
|
except:
|
||||||
|
raise ae
|
||||||
|
|
||||||
def __eq__(self,other):
|
def __eq__(self,other):
|
||||||
try:
|
try:
|
||||||
@@ -8455,10 +8477,10 @@ class Table(object):
|
|||||||
field_type = field.type
|
field_type = field.type
|
||||||
if isinstance(field_type,str) and field_type[:10] == 'reference ':
|
if isinstance(field_type,str) and field_type[:10] == 'reference ':
|
||||||
ref = field_type[10:].strip()
|
ref = field_type[10:].strip()
|
||||||
if not ref.strip():
|
if not ref:
|
||||||
raise SyntaxError('Table: reference to nothing: %s' %ref)
|
SyntaxError('Table: reference to nothing: %s' %ref)
|
||||||
if '.' in ref:
|
if '.' in ref:
|
||||||
rtablename, rfieldname = ref.split('.',1)
|
rtablename, throw_it,rfieldname = ref.partition('.')
|
||||||
else:
|
else:
|
||||||
rtablename, rfieldname = ref, None
|
rtablename, rfieldname = ref, None
|
||||||
if not rtablename in db:
|
if not rtablename in db:
|
||||||
@@ -10154,6 +10176,18 @@ class RecordDeleter(object):
|
|||||||
def __call__(self):
|
def __call__(self):
|
||||||
return self.db(self.db[self.tablename]._id==self.id).delete()
|
return self.db(self.db[self.tablename]._id==self.id).delete()
|
||||||
|
|
||||||
|
class LazyReferenceGetter(object):
|
||||||
|
def __init__(self, table, id):
|
||||||
|
self.db, self.tablename, self.id = table._db, table._tablename, id
|
||||||
|
def __call__(self, other_tablename):
|
||||||
|
table = self.db[self.tablename]
|
||||||
|
other_table = self.db[other_tablename]
|
||||||
|
for rfield in table._referenced_by:
|
||||||
|
if rfield.table == other_table:
|
||||||
|
return LazySet(rfield, self.id)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
class LazySet(object):
|
class LazySet(object):
|
||||||
def __init__(self, field, id):
|
def __init__(self, field, id):
|
||||||
self.db, self.tablename, self.fieldname, self.id = \
|
self.db, self.tablename, self.fieldname, self.id = \
|
||||||
|
|||||||
Reference in New Issue
Block a user