Skip to content

Commit ef813f3

Browse files
committed
Robustify SQL<->HyperDB data type conversion.
1 parent 19adf85 commit ef813f3

File tree

2 files changed

+58
-19
lines changed

2 files changed

+58
-19
lines changed

roundup/backends/back_mysql.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ def add_new_columns_v2(self):
297297
# convert to new MySQL data type
298298
prop = properties[name]
299299
if v is not None:
300-
e = self.hyperdb_to_sql_value[prop.__class__](v)
300+
e = self.to_sql_value(prop.__class__)(v)
301301
else:
302302
e = None
303303
l.append(e)
@@ -349,7 +349,7 @@ def add_new_columns_v2(self):
349349

350350
# re-create journal table
351351
self.create_journal_table(klass)
352-
dc = self.hyperdb_to_sql_value[hyperdb.Date]
352+
dc = self.to_sql_value(hyperdb.Date)
353353
for nodeid, journaldate, journaltag, action, params in olddata:
354354
self.save_journal(cn, cols, nodeid, dc(journaldate),
355355
journaltag, action, params)

roundup/backends/rdbms_common.py

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -387,17 +387,30 @@ def reindex(self, classname=None, show_progress=False):
387387
hyperdb.Boolean : 'BOOLEAN',
388388
hyperdb.Number : 'REAL',
389389
}
390+
391+
def hyperdb_to_sql_datatype(self, propclass):
392+
393+
datatype = self.hyperdb_to_sql_datatypes.get(propclass)
394+
if datatype:
395+
return datatype
396+
397+
for k, v in self.hyperdb_to_sql_datatypes.iteritems():
398+
if issubclass(propclass, k):
399+
return v
400+
401+
raise ValueError, '%r is not a hyperdb property class' % propclass
402+
390403
def determine_columns(self, properties):
391404
""" Figure the column names and multilink properties from the spec
392405
393406
"properties" is a list of (name, prop) where prop may be an
394407
instance of a hyperdb "type" _or_ a string repr of that type.
395408
"""
396409
cols = [
397-
('_actor', self.hyperdb_to_sql_datatypes[hyperdb.Link]),
398-
('_activity', self.hyperdb_to_sql_datatypes[hyperdb.Date]),
399-
('_creator', self.hyperdb_to_sql_datatypes[hyperdb.Link]),
400-
('_creation', self.hyperdb_to_sql_datatypes[hyperdb.Date]),
410+
('_actor', self.hyperdb_to_sql_datatype(hyperdb.Link)),
411+
('_activity', self.hyperdb_to_sql_datatype(hyperdb.Date)),
412+
('_creator', self.hyperdb_to_sql_datatype(hyperdb.Link)),
413+
('_creation', self.hyperdb_to_sql_datatype(hyperdb.Date)),
401414
]
402415
mls = []
403416
# add the multilinks separately
@@ -411,7 +424,7 @@ def determine_columns(self, properties):
411424
#and prop.find('Multilink') != -1:
412425
#mls.append(col)
413426

414-
datatype = self.hyperdb_to_sql_datatypes[prop.__class__]
427+
datatype = self.hyperdb_to_sql_datatype(prop.__class__)
415428
cols.append(('_'+col, datatype))
416429

417430
# Intervals stored as two columns
@@ -489,7 +502,7 @@ def update_class(self, spec, old_spec, force=0):
489502
self.create_multilink_table(spec, propname)
490503
else:
491504
# add the column
492-
coltype = self.hyperdb_to_sql_datatypes[prop.__class__]
505+
coltype = self.hyperdb_to_sql_datatype(prop.__class__)
493506
sql = 'alter table _%s add column _%s %s'%(
494507
spec.classname, propname, coltype)
495508
self.sql(sql)
@@ -607,7 +620,7 @@ def create_journal_table(self, spec):
607620
sql = """create table %s__journal (
608621
nodeid integer, date %s, tag varchar(255),
609622
action varchar(255), params text)""" % (spec.classname,
610-
self.hyperdb_to_sql_datatypes[hyperdb.Date])
623+
self.hyperdb_to_sql_datatype(hyperdb.Date))
611624
self.sql(sql)
612625
self.create_journal_table_indexes(spec)
613626

@@ -768,6 +781,19 @@ def clear(self):
768781
hyperdb.Number : lambda x: x,
769782
hyperdb.Multilink : lambda x: x, # used in journal marshalling
770783
}
784+
785+
def to_sql_value(self, propklass):
786+
787+
fn = self.hyperdb_to_sql_value.get(propklass)
788+
if fn:
789+
return fn
790+
791+
for k, v in self.hyperdb_to_sql_value.iteritems():
792+
if issubclass(propklass, k):
793+
return v
794+
795+
raise ValueError, '%r is not a hyperdb property class' % propklass
796+
771797
def addnode(self, classname, nodeid, node):
772798
""" Add the specified node to its class's db.
773799
"""
@@ -821,7 +847,7 @@ def addnode(self, classname, nodeid, node):
821847
prop = props[col[1:]]
822848
value = values[col[1:]]
823849
if value is not None:
824-
value = self.hyperdb_to_sql_value[prop.__class__](value)
850+
value = self.to_sql_value(prop.__class__)(value)
825851
vals.append(value)
826852
vals.append(nodeid)
827853
vals = tuple(vals)
@@ -892,7 +918,7 @@ def setnode(self, classname, nodeid, values, multilink_changes={}):
892918
if value is None:
893919
e = None
894920
else:
895-
e = self.hyperdb_to_sql_value[prop.__class__](value)
921+
e = self.to_sql_value(prop.__class__)(value)
896922
vals.append(e)
897923

898924
vals.append(int(nodeid))
@@ -955,6 +981,19 @@ def setnode(self, classname, nodeid, values, multilink_changes={}):
955981
hyperdb.Number : _num_cvt,
956982
hyperdb.Multilink : lambda x: x, # used in journal marshalling
957983
}
984+
985+
def to_hyperdb_value(self, propklass):
986+
987+
fn = self.sql_to_hyperdb_value.get(propklass)
988+
if fn:
989+
return fn
990+
991+
for k, v in self.sql_to_hyperdb_value.iteritems():
992+
if issubclass(propklass, k):
993+
return v
994+
995+
raise ValueError, '%r is not a hyperdb property class' % propklass
996+
958997
def getnode(self, classname, nodeid):
959998
""" Get a node from the database.
960999
"""
@@ -997,7 +1036,7 @@ def getnode(self, classname, nodeid):
9971036
continue
9981037
value = values[col]
9991038
if value is not None:
1000-
value = self.sql_to_hyperdb_value[props[name].__class__](value)
1039+
value = self.to_hyperdb_value(props[name].__class__)(value)
10011040
node[name] = value
10021041

10031042

@@ -1116,7 +1155,7 @@ def addjournal(self, classname, nodeid, action, params, creator=None,
11161155

11171156
params = repr(params)
11181157

1119-
dc = self.hyperdb_to_sql_value[hyperdb.Date]
1158+
dc = self.to_sql_value(hyperdb.Date)
11201159
journaldate = dc(journaldate)
11211160

11221161
self.save_journal(classname, cols, nodeid, journaldate,
@@ -1131,7 +1170,7 @@ def setjournal(self, classname, nodeid, journal):
11311170
# create the journal entry
11321171
cols = 'nodeid,date,tag,action,params'
11331172

1134-
dc = self.hyperdb_to_sql_value[hyperdb.Date]
1173+
dc = self.to_sql_value(hyperdb.Date)
11351174
for nodeid, journaldate, journaltag, action, params in journal:
11361175
self.log_debug('addjournal %s%s %r %s %s %r'%(
11371176
classname, nodeid, journaldate, journaltag, action,
@@ -1153,7 +1192,7 @@ def _journal_marshal(self, params, classname):
11531192
if not value:
11541193
continue
11551194
property = properties[param]
1156-
cvt = self.hyperdb_to_sql_value[property.__class__]
1195+
cvt = self.to_sql_value(property.__class__)
11571196
if isinstance(property, Password):
11581197
params[param] = cvt(value)
11591198
elif isinstance(property, Date):
@@ -1174,7 +1213,7 @@ def getjournal(self, classname, nodeid):
11741213
journal = self.load_journal(classname, cols, nodeid)
11751214

11761215
# now unmarshal the data
1177-
dc = self.sql_to_hyperdb_value[hyperdb.Date]
1216+
dc = self.to_hyperdb_value(hyperdb.Date)
11781217
res = []
11791218
properties = self.getclass(classname).getprops()
11801219
for nodeid, date_stamp, user, action, params in journal:
@@ -1187,7 +1226,7 @@ def getjournal(self, classname, nodeid):
11871226
if property is None:
11881227
# deleted property
11891228
continue
1190-
cvt = self.sql_to_hyperdb_value[property.__class__]
1229+
cvt = self.to_hyperdb_value(property.__class__)
11911230
if isinstance(property, Password):
11921231
params[param] = cvt(value)
11931232
elif isinstance(property, Date):
@@ -1224,7 +1263,7 @@ def load_journal(self, classname, cols, nodeid):
12241263
def pack(self, pack_before):
12251264
""" Delete all journal entries except "create" before 'pack_before'.
12261265
"""
1227-
date_stamp = self.hyperdb_to_sql_value[Date](pack_before)
1266+
date_stamp = self.to_sql_value(Date)(pack_before)
12281267

12291268
# do the delete
12301269
for classname in self.classes.keys():
@@ -2256,7 +2295,7 @@ def filter(self, search_matches, filterspec, sort=[], group=[]):
22562295
cn, ln, pln, k, ln))
22572296
oc = '_%s._%s'%(ln, lp)
22582297
elif isinstance(propclass, Date) and p.sort_type < 2:
2259-
dc = self.db.hyperdb_to_sql_value[hyperdb.Date]
2298+
dc = self.db.to_sql_value(hyperdb.Date)
22602299
if isinstance(v, type([])):
22612300
s = ','.join([a for x in v])
22622301
where.append('_%s._%s in (%s)'%(pln, k, s))

0 commit comments

Comments
 (0)