Mercurial > p > roundup > code
diff roundup/backends/rdbms_common.py @ 6065:1ec4aa670b0c
Flake8 whitespace; remove imports; type()!=type() -> isinstance()
Removed imports sys errno.
Replaced
type(value) != type(''):
isinstance(value, type(''))
multiple instances.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 18 Jan 2020 14:53:44 -0500 |
| parents | 3175bb92ca28 |
| children | e6073c2291c6 |
line wrap: on
line diff
--- a/roundup/backends/rdbms_common.py Sat Jan 18 11:47:45 2020 -0500 +++ b/roundup/backends/rdbms_common.py Sat Jan 18 14:53:44 2020 -0500 @@ -52,13 +52,12 @@ __docformat__ = 'restructuredtext' # standard python modules -import sys, os, time, re, errno, weakref, copy, logging, datetime +import os, time, re, weakref, copy, logging, datetime # roundup modules from roundup import hyperdb, date, password, roundupdb, security, support from roundup.hyperdb import String, Password, Date, Interval, Link, \ - Multilink, DatabaseError, Boolean, Number, Integer, Node -from roundup.backends import locking + Multilink, DatabaseError, Boolean, Number, Integer from roundup.i18n import _ @@ -76,6 +75,7 @@ # dummy value meaning "argument not passed" _marker = [] + def _num_cvt(num): num = str(num) try: @@ -83,27 +83,29 @@ except ValueError: return float(num) + def _bool_cvt(value): if value in ('TRUE', 'FALSE'): return {'TRUE': 1, 'FALSE': 0}[value] # assume it's a number returned from the db API return int(value) + def date_to_hyperdb_value(d): """ convert date d to a roundup date """ - if isinstance (d, datetime.datetime): + if isinstance(d, datetime.datetime): return date.Date(d) - return date.Date (str(d).replace(' ', '.')) + return date.Date(str(d).replace(' ', '.')) def connection_dict(config, dbnamestr=None): """ Used by Postgresql and MySQL to detemine the keyword args for opening the database connection.""" - d = { } + d = {} if dbnamestr: d[dbnamestr] = config.RDBMS_NAME for name in ('host', 'port', 'password', 'user', 'read_default_group', - 'read_default_file'): + 'read_default_file'): cvar = 'RDBMS_'+name.upper() if config[cvar] is not None: d[name] = config[cvar] @@ -117,7 +119,7 @@ """ def __init__(self): - self.ranges = [] + self.ranges = [] self.singles = [] def append(self, nid): @@ -136,7 +138,7 @@ self.singles.append(nid) def where(self, field, placeholder): - ranges = self.ranges + ranges = self.ranges singles = self.singles if not singles and not ranges: return "(1=0)", [] @@ -162,7 +164,8 @@ - some functionality is specific to the actual SQL database, hence the sql_* methods that are NotImplemented - - we keep a cache of the latest N row fetches (where N is configurable). + - we keep a cache of the latest N row fetches (where N is + configurable). """ def __init__(self, config, journaltag=None): """ Open the database and load the schema from it. @@ -182,7 +185,7 @@ self.cache_size = config.RDBMS_CACHE_SIZE self.clearCache() self.stats = {'cache_hits': 0, 'cache_misses': 0, 'get_items': 0, - 'filtering': 0} + 'filtering': 0} # make sure the database directory exists if not os.path.isdir(self.config.DATABASE): @@ -193,7 +196,7 @@ # Uppercase to not collide with Class names self.Session = None - self.Otk = None + self.Otk = None # open a connection to the database, creating the "conn" attribute self.open_connection() @@ -224,7 +227,7 @@ def sql(self, sql, args=None, cursor=None): """ Execute the sql with the optional args. """ - self.log_debug('SQL %r %r'%(sql, args)) + self.log_debug('SQL %r %r' % (sql, args)) if not cursor: cursor = self.cursor if args: @@ -260,7 +263,6 @@ v = v.replace('_', '\\_') return '%' + v + '%' - def init_dbschema(self): self.database_schema = { 'version': self.current_db_version, @@ -283,7 +285,7 @@ """ s = repr(self.database_schema) self.sql('delete from schema') - self.sql('insert into schema values (%s)'%self.arg, (s,)) + self.sql('insert into schema values (%s)' % self.arg, (s,)) def post_init(self): """ Called once the schema initialisation has finished. @@ -309,7 +311,7 @@ tables[classname] = spec.schema() save = 1 - for classname, spec in list(tables.items()): + for classname, _spec in list(tables.items()): if classname not in self.classes: self.drop_class(classname, tables[classname]) del tables[classname] @@ -330,6 +332,7 @@ # of the backen database current_db_version = 5 db_version_updated = False + def upgrade_db(self): """ Update the SQL database to reflect changes in the backend code. @@ -338,7 +341,8 @@ version = self.database_schema.get('version', 1) if version > self.current_db_version: raise DatabaseError('attempting to run rev %d DATABASE with rev ' - '%d CODE!'%(version, self.current_db_version)) + '%d CODE!' % (version, + self.current_db_version)) if version == self.current_db_version: # nothing to do return 0 @@ -375,9 +379,9 @@ def fix_version_3_tables(self): # drop the shorter VARCHAR OTK column and add a new TEXT one for name in ('otk', 'session'): - self.sql('DELETE FROM %ss'%name) - self.sql('ALTER TABLE %ss DROP %s_value'%(name, name)) - self.sql('ALTER TABLE %ss ADD %s_value TEXT'%(name, name)) + self.sql('DELETE FROM %ss' % name) + self.sql('ALTER TABLE %ss DROP %s_value' % (name, name)) + self.sql('ALTER TABLE %ss ADD %s_value TEXT' % (name, name)) def fix_version_2_tables(self): # Default (used by sqlite): NOOP @@ -387,10 +391,10 @@ # note this is an explicit call now c = self.cursor for cn, klass in self.classes.items(): - c.execute('select id from _%s where __retired__<>0'%(cn,)) + c.execute('select id from _%s where __retired__<>0' % (cn,)) for (id,) in c.fetchall(): - c.execute('update _%s set __retired__=%s where id=%s'%(cn, - self.arg, self.arg), (id, id)) + c.execute('update _%s set __retired__=%s where id=%s' % (cn, + self.arg, self.arg), (id, id)) if klass.key: self.add_class_key_required_unique_constraint(cn, klass.key) @@ -401,17 +405,17 @@ cols = ','.join('nodeid date tag action params'.split()) for klass in self.classes.values(): # slurp and drop - sql = 'select %s from %s__journal order by date'%(cols, - klass.classname) + sql = 'select %s from %s__journal order by date' % \ + (cols, klass.classname) c.execute(sql) contents = c.fetchall() self.drop_journal_table_indexes(klass.classname) - c.execute('drop table %s__journal'%klass.classname) + c.execute('drop table %s__journal' % klass.classname) # re-create and re-populate self.create_journal_table(klass) a = self.arg - sql = 'insert into %s__journal (%s) values (%s,%s,%s,%s,%s)'%( + sql = 'insert into %s__journal (%s) values (%s,%s,%s,%s,%s)' % ( klass.classname, cols, a, a, a, a, a) for row in contents: # no data conversion needed @@ -425,17 +429,17 @@ # slurp and drop cols, mls = self.determine_columns(list(klass.properties.items())) scols = ','.join([i[0] for i in cols]) - sql = 'select id,%s from _%s'%(scols, klass.classname) + sql = 'select id,%s from _%s' % (scols, klass.classname) c.execute(sql) contents = c.fetchall() self.drop_class_table_indexes(klass.classname, klass.getkey()) - c.execute('drop table _%s'%klass.classname) + c.execute('drop table _%s' % klass.classname) # re-create and re-populate self.create_class_table(klass, create_sequence=0) a = ','.join([self.arg for i in range(len(cols)+1)]) - sql = 'insert into _%s (id,%s) values (%s)'%(klass.classname, - scols, a) + sql = 'insert into _%s (id,%s) values (%s)' % (klass.classname, + scols, a) for row in contents: l = [] for entry in row: @@ -448,7 +452,6 @@ def refresh_database(self): self.post_init() - def reindex(self, classname=None, show_progress=False): if classname: classes = [self.getclass(classname)] @@ -456,8 +459,8 @@ classes = list(self.classes.values()) for klass in classes: if show_progress: - for nodeid in support.Progress('Reindex %s'%klass.classname, - klass.list()): + for nodeid in support.Progress('Reindex %s' % klass.classname, + klass.list()): klass.index(nodeid) else: for nodeid in klass.list(): @@ -469,9 +472,9 @@ implements_double_precision = True hyperdb_to_sql_datatypes = { - hyperdb.String : 'TEXT', - hyperdb.Date : 'TIMESTAMP', - hyperdb.Link : 'INTEGER', + hyperdb.String : 'TEXT', + hyperdb.Date : 'TIMESTAMP', + hyperdb.Link : 'INTEGER', hyperdb.Interval : 'VARCHAR(255)', hyperdb.Password : 'VARCHAR(255)', hyperdb.Boolean : 'BOOLEAN', @@ -479,21 +482,21 @@ hyperdb.Integer : 'INTEGER', } - def hyperdb_to_sql_datatype(self, propclass, prop = None): + def hyperdb_to_sql_datatype(self, propclass, prop=None): datatype = self.hyperdb_to_sql_datatypes.get(propclass) if self.implements_double_precision and prop and \ - isinstance(prop, Number) and prop.use_double: + isinstance(prop, Number) and prop.use_double: datatype = 'DOUBLE PRECISION' if datatype: return datatype - + for k, v in self.hyperdb_to_sql_datatypes.items(): if issubclass(propclass, k): return v raise ValueError('%r is not a hyperdb property class' % propclass) - + def determine_columns(self, properties): """ Figure the column names and multilink properties from the spec @@ -515,8 +518,8 @@ if isinstance(prop, type('')): raise ValueError("string property spec!") - #and prop.find('Multilink') != -1: - #mls.append(col) + # and prop.find('Multilink') != -1: + # mls.append(col) datatype = self.hyperdb_to_sql_datatype(prop.__class__, prop) cols.append(('_'+col, datatype)) @@ -542,13 +545,14 @@ return 0 if not self.config.RDBMS_ALLOW_ALTER: - raise DatabaseError(_('ALTER operation disallowed: %r -> %r.'%(old_spec, new_spec))) + raise DatabaseError(_('ALTER operation disallowed: %r -> %r.'% ( + old_spec, new_spec))) logger = logging.getLogger('roundup.hyperdb.backend') - logger.info('update_class %s'%spec.classname) - - logger.debug('old_spec %r'%(old_spec,)) - logger.debug('new_spec %r'%(new_spec,)) + logger.info('update_class %s' % spec.classname) + + logger.debug('old_spec %r' % (old_spec,)) + logger.debug('new_spec %r' % (new_spec,)) # detect key prop change for potential index change keyprop_changes = {} @@ -570,7 +574,7 @@ self.drop_multilink_table_indexes(spec.classname, name) # now the multilink table itself - sql = 'drop table %s_%s'%(spec.classname, name) + sql = 'drop table %s_%s' % (spec.classname, name) else: # if this is the key prop, drop the index first if old_spec[0] == prop: @@ -578,7 +582,8 @@ del keyprop_changes['remove'] # drop the column - sql = 'alter table _%s drop column _%s'%(spec.classname, name) + sql = 'alter table _%s drop column _%s' % (spec.classname, + name) self.sql(sql) @@ -586,7 +591,7 @@ # changed, we still need to remove the old index if 'remove' in keyprop_changes: self.drop_class_table_key_index(spec.classname, - keyprop_changes['remove']) + keyprop_changes['remove']) # add new columns for propname, prop in new_spec[1]: @@ -598,13 +603,13 @@ else: # add the column coltype = self.hyperdb_to_sql_datatype(prop.__class__, prop) - sql = 'alter table _%s add column _%s %s'%( + sql = 'alter table _%s add column _%s %s' % ( spec.classname, propname, coltype) self.sql(sql) # extra Interval column if isinstance(prop, Interval): - sql = 'alter table _%s add column __%s_int__ BIGINT'%( + sql = 'alter table _%s add column __%s_int__ BIGINT' % ( spec.classname, propname) self.sql(sql) @@ -617,7 +622,7 @@ # changed, we still need to add the new index if 'add' in keyprop_changes: self.create_class_table_key_index(spec.classname, - keyprop_changes['add']) + keyprop_changes['add']) return 1 @@ -638,8 +643,8 @@ cols, mls = self.determine_all_columns(spec) # create the base table - scols = ','.join(['%s %s'%x for x in cols]) - sql = 'create table _%s (%s)'%(spec.classname, scols) + scols = ','.join(['%s %s' % x for x in cols]) + sql = 'create table _%s (%s)' % (spec.classname, scols) self.sql(sql) self.create_class_table_indexes(spec) @@ -650,41 +655,42 @@ """ create the class table for the given spec """ # create __retired__ index - index_sql2 = 'create index _%s_retired_idx on _%s(__retired__)'%( + index_sql2 = 'create index _%s_retired_idx on _%s(__retired__)' % ( spec.classname, spec.classname) self.sql(index_sql2) # create index for key property if spec.key: - index_sql3 = 'create index _%s_%s_idx on _%s(_%s)'%( + index_sql3 = 'create index _%s_%s_idx on _%s(_%s)' % ( spec.classname, spec.key, spec.classname, spec.key) self.sql(index_sql3) # and the unique index for key / retired(id) self.add_class_key_required_unique_constraint(spec.classname, - spec.key) + spec.key) # TODO: create indexes on (selected?) Link property columns, as # they're more likely to be used for lookup def add_class_key_required_unique_constraint(self, cn, key): sql = '''create unique index _%s_key_retired_idx - on _%s(__retired__, _%s)'''%(cn, cn, key) + on _%s(__retired__, _%s)''' % (cn, cn, key) try: self.sql(sql) except Exception: # nosec # XXX catch e.g.: - # _sqlite.DatabaseError: index _status_key_retired_idx already exists + # _sqlite.DatabaseError: index _status_key_retired_idx + # already exists pass def drop_class_table_indexes(self, cn, key): # drop the old table indexes first - l = ['_%s_id_idx'%cn, '_%s_retired_idx'%cn] + l = ['_%s_id_idx' % cn, '_%s_retired_idx' % cn] if key: - l.append('_%s_%s_idx'%(cn, key)) - - table_name = '_%s'%cn + l.append('_%s_%s_idx' % (cn, key)) + + table_name = '_%s' % cn for index_name in l: if not self.sql_index_exists(table_name, index_name): continue @@ -694,18 +700,18 @@ def create_class_table_key_index(self, cn, key): """ create the class table for the given spec """ - sql = 'create index _%s_%s_idx on _%s(_%s)'%(cn, key, cn, key) + sql = 'create index _%s_%s_idx on _%s(_%s)' % (cn, key, cn, key) self.sql(sql) def drop_class_table_key_index(self, cn, key): - table_name = '_%s'%cn - index_name = '_%s_%s_idx'%(cn, key) + table_name = '_%s' % cn + index_name = '_%s_%s_idx' % (cn, key) if self.sql_index_exists(table_name, index_name): sql = 'drop index '+index_name self.sql(sql) # and now the retired unique index too - index_name = '_%s_key_retired_idx'%cn + index_name = '_%s_key_retired_idx' % cn if self.sql_index_exists(table_name, index_name): sql = 'drop index '+index_name self.sql(sql) @@ -715,24 +721,24 @@ already-determined cols """ # journal table - cols = ','.join(['%s varchar'%x - for x in 'nodeid date tag action params'.split()]) + cols = ','.join(['%s varchar' % x + for x in 'nodeid date tag action params'.split()]) sql = """create table %s__journal ( nodeid integer, date %s, tag varchar(255), action varchar(255), params text)""" % (spec.classname, - self.hyperdb_to_sql_datatype(hyperdb.Date)) + self.hyperdb_to_sql_datatype(hyperdb.Date)) self.sql(sql) self.create_journal_table_indexes(spec) def create_journal_table_indexes(self, spec): # index on nodeid - sql = 'create index %s_journ_idx on %s__journal(nodeid)'%( + sql = 'create index %s_journ_idx on %s__journal(nodeid)' % ( spec.classname, spec.classname) self.sql(sql) def drop_journal_table_indexes(self, classname): - index_name = '%s_journ_idx'%classname - if not self.sql_index_exists('%s__journal'%classname, index_name): + index_name = '%s_journ_idx' % classname + if not self.sql_index_exists('%s__journal' % classname, index_name): return index_sql = 'drop index '+index_name self.sql(index_sql) @@ -742,32 +748,32 @@ given by the spec """ # create the table - sql = 'create table %s_%s (linkid INTEGER, nodeid INTEGER)'%( + sql = 'create table %s_%s (linkid INTEGER, nodeid INTEGER)' % ( spec.classname, ml) self.sql(sql) self.create_multilink_table_indexes(spec, ml) def create_multilink_table_indexes(self, spec, ml): # create index on linkid - index_sql = 'create index %s_%s_l_idx on %s_%s(linkid)'%( + index_sql = 'create index %s_%s_l_idx on %s_%s(linkid)' % ( spec.classname, ml, spec.classname, ml) self.sql(index_sql) # create index on nodeid - index_sql = 'create index %s_%s_n_idx on %s_%s(nodeid)'%( + index_sql = 'create index %s_%s_n_idx on %s_%s(nodeid)' % ( spec.classname, ml, spec.classname, ml) self.sql(index_sql) def drop_multilink_table_indexes(self, classname, ml): l = [ - '%s_%s_l_idx'%(classname, ml), - '%s_%s_n_idx'%(classname, ml) - ] - table_name = '%s_%s'%(classname, ml) + '%s_%s_l_idx' % (classname, ml), + '%s_%s_n_idx' % (classname, ml) + ] + table_name = '%s_%s' % (classname, ml) for index_name in l: if not self.sql_index_exists(table_name, index_name): continue - index_sql = 'drop index %s'%index_name + index_sql = 'drop index %s' % index_name self.sql(index_sql) def create_class(self, spec): @@ -775,7 +781,8 @@ """ if not self.config.RDBMS_ALLOW_CREATE: - raise DatabaseError(_('CREATE operation disallowed: "%s".'%spec.classname)) + raise DatabaseError(_('CREATE operation disallowed: "%s".' % + spec.classname)) cols, mls = self.create_class_table(spec) self.create_journal_table(spec) @@ -791,7 +798,7 @@ """ if not self.config.RDBMS_ALLOW_DROP: - raise DatabaseError(_('DROP operation disallowed: "%s".'%cn)) + raise DatabaseError(_('DROP operation disallowed: "%s".' % cn)) properties = spec[1] # figure the multilinks @@ -807,17 +814,17 @@ # drop journal table and indexes self.drop_journal_table_indexes(cn) - sql = 'drop table %s__journal'%cn + sql = 'drop table %s__journal' % cn self.sql(sql) for ml in mls: # drop multilink table and indexes self.drop_multilink_table_indexes(cn, ml) - sql = 'drop table %s_%s'%(spec.classname, ml) + sql = 'drop table %s_%s' % (spec.classname, ml) self.sql(sql) def drop_class_table(self, cn): - sql = 'drop table _%s'%cn + sql = 'drop table _%s' % cn self.sql(sql) # @@ -861,7 +868,7 @@ try: return self.classes[classname] except KeyError: - raise KeyError('There is no class called "%s"'%classname) + raise KeyError('There is no class called "%s"' % classname) def clear(self): """Delete all database contents. @@ -871,7 +878,7 @@ """ logging.getLogger('roundup.hyperdb.backend').info('clear') for cn in self.classes: - sql = 'delete from _%s'%cn + sql = 'delete from _%s' % cn self.sql(sql) # @@ -879,10 +886,10 @@ # hyperdb_to_sql_value = { - hyperdb.String : str, + hyperdb.String : str, # fractional seconds by default - hyperdb.Date : lambda x: x.formal(sep=' ', sec='%06.3f'), - hyperdb.Link : int, + hyperdb.Date : lambda x: x.formal(sep=' ', sec='%06.3f'), + hyperdb.Link : int, hyperdb.Interval : str, hyperdb.Password : str, hyperdb.Boolean : lambda x: x and 'TRUE' or 'FALSE', @@ -921,8 +928,8 @@ def addnode(self, classname, nodeid, node): """ Add the specified node to its class's db. """ - self.log_debug('addnode %s%s %r'%(classname, - nodeid, node)) + self.log_debug('addnode %s%s %r' % (classname, + nodeid, node)) # determine the column definitions and multilink tables cl = self.classes[classname] @@ -955,7 +962,7 @@ # figure the values to insert vals = [] - for col,dt in cols: + for col, _dt in cols: # this is somewhat dodgy.... if col.endswith('_int__'): # XXX eugh, this test suxxors @@ -976,26 +983,25 @@ vals = tuple(vals) # make sure the ordering is correct for column name -> column value - s = ','.join([self.arg for x in cols]) + ',%s'%self.arg - cols = ','.join([col for col,dt in cols]) + ',id' + s = ','.join([self.arg for x in cols]) + ',%s' % self.arg + cols = ','.join([col for col, dt in cols]) + ',id' # perform the inserts - sql = 'insert into _%s (%s) values (%s)'%(classname, cols, s) + sql = 'insert into _%s (%s) values (%s)' % (classname, cols, s) self.sql(sql, vals) # insert the multilink rows for col in mls: - t = '%s_%s'%(classname, col) + t = '%s_%s' % (classname, col) for entry in node[col]: - sql = 'insert into %s (linkid, nodeid) values (%s,%s)'%(t, - self.arg, self.arg) + sql = 'insert into %s (linkid, nodeid) values (%s,%s)' % ( + t, self.arg, self.arg) self.sql(sql, (entry, nodeid)) def setnode(self, classname, nodeid, values, multilink_changes={}): """ Change the specified node. """ - self.log_debug('setnode %s%s %r' - % (classname, nodeid, values)) + self.log_debug('setnode %s%s %r' % (classname, nodeid, values)) # clear this node out of the cache if it's in there key = (classname, nodeid) @@ -1016,7 +1022,7 @@ # Intervals store the seconds value too cols.append(col) # extra leading '_' added by code below - cols.append('_' +col + '_int__') + cols.append('_' + col + '_int__') else: cols.append(col) cols.sort() @@ -1049,11 +1055,11 @@ # if there's any updates to regular columns, do them if cols: # make sure the ordering is correct for column name -> column value - s = ','.join(['_%s=%s'%(x, self.arg) for x in cols]) + s = ','.join(['_%s=%s' % (x, self.arg) for x in cols]) cols = ','.join(cols) # perform the update - sql = 'update _%s set %s where id=%s'%(classname, s, self.arg) + sql = 'update _%s set %s where id=%s' % (classname, s, self.arg) self.sql(sql, vals) # we're probably coming from an import, not a change @@ -1062,41 +1068,41 @@ prop = props[name] value = values[name] - t = '%s_%s'%(classname, name) + t = '%s_%s' % (classname, name) # clear out previous values for this node # XXX numeric ids - self.sql('delete from %s where nodeid=%s'%(t, self.arg), - (nodeid,)) + self.sql('delete from %s where nodeid=%s' % (t, self.arg), + (nodeid,)) # insert the values for this node for entry in values[name]: - sql = 'insert into %s (linkid, nodeid) values (%s,%s)'%(t, - self.arg, self.arg) + sql = 'insert into %s (linkid, nodeid) values (%s,%s)' % ( + t, self.arg, self.arg) # XXX numeric ids self.sql(sql, (entry, nodeid)) # we have multilink changes to apply for col, (add, remove) in multilink_changes.items(): - tn = '%s_%s'%(classname, col) + tn = '%s_%s' % (classname, col) if add: - sql = 'insert into %s (nodeid, linkid) values (%s,%s)'%(tn, + sql = 'insert into %s (nodeid, linkid) values (%s,%s)' % (tn, self.arg, self.arg) for addid in add: # XXX numeric ids self.sql(sql, (int(nodeid), int(addid))) if remove: s = ','.join([self.arg]*len(remove)) - sql = 'delete from %s where nodeid=%s and linkid in (%s)'%(tn, - self.arg, s) + sql = 'delete from %s where nodeid=%s and linkid in (%s)' % ( + tn, self.arg, s) # XXX numeric ids self.sql(sql, [int(nodeid)] + remove) sql_to_hyperdb_value = { - hyperdb.String : str, - hyperdb.Date : date_to_hyperdb_value, + hyperdb.String : str, + hyperdb.Date : date_to_hyperdb_value, # hyperdb.Link : int, # XXX numeric ids - hyperdb.Link : str, + hyperdb.Link : str, hyperdb.Interval : date.Interval, hyperdb.Password : lambda x: password.Password(encrypted=x), hyperdb.Boolean : _bool_cvt, @@ -1121,13 +1127,13 @@ """ evaluation of single Multilink (lazy eval may have skipped this) """ if propname not in node: - sql = 'select linkid from %s_%s where nodeid=%s'%(classname, - propname, self.arg) + sql = 'select linkid from %s_%s where nodeid=%s' % ( + classname, propname, self.arg) self.sql(sql, (nodeid,)) # extract the first column from the result # XXX numeric ids items = [int(x[0]) for x in self.cursor.fetchall()] - items.sort () + items.sort() node[propname] = [str(x) for x in items] def _materialize_multilinks(self, classname, nodeid, node, props=None): @@ -1155,7 +1161,8 @@ self.stats['cache_hits'] += 1 # return the cached information if fetch_multilinks: - self._materialize_multilinks(classname, nodeid, self.cache[key]) + self._materialize_multilinks(classname, nodeid, + self.cache[key]) return self.cache[key] if __debug__: @@ -1165,15 +1172,15 @@ # figure the columns we're fetching cl = self.classes[classname] cols, mls = self.determine_columns(list(cl.properties.items())) - scols = ','.join([col for col,dt in cols]) + scols = ','.join([col for col, dt in cols]) # perform the basic property fetch - sql = 'select %s from _%s where id=%s'%(scols, classname, self.arg) + sql = 'select %s from _%s where id=%s' % (scols, classname, self.arg) self.sql(sql, (nodeid,)) values = self.sql_fetchone() if values is None: - raise IndexError('no such %s node %s'%(classname, nodeid)) + raise IndexError('no such %s node %s' % (classname, nodeid)) # make up the node node = {} @@ -1205,12 +1212,12 @@ """Remove a node from the database. Called exclusively by the destroy() method on Class. """ - logging.getLogger('roundup.hyperdb.backend').info('destroynode %s%s'%( - classname, nodeid)) + message = 'destroynode %s%s' % (classname, nodeid) + logging.getLogger('roundup.hyperdb.backend').info(message) # make sure the node exists if not self.hasnode(classname, nodeid): - raise IndexError('%s has no node %s'%(classname, nodeid)) + raise IndexError('%s has no node %s' % (classname, nodeid)) # see if we have this node cached if (classname, nodeid) in self.cache: @@ -1222,7 +1229,7 @@ self.transactions.remove(entry) # now do the SQL - sql = 'delete from _%s where id=%s'%(classname, self.arg) + sql = 'delete from _%s where id=%s' % (classname, self.arg) self.sql(sql, (nodeid,)) # remove from multilnks @@ -1230,15 +1237,18 @@ x, mls = self.determine_columns(list(cl.properties.items())) for col in mls: # get the link ids - sql = 'delete from %s_%s where nodeid=%s'%(classname, col, self.arg) + sql = 'delete from %s_%s where nodeid=%s' % (classname, col, + self.arg) self.sql(sql, (nodeid,)) # remove journal entries - sql = 'delete from %s__journal where nodeid=%s'%(classname, self.arg) + sql = 'delete from %s__journal where nodeid=%s' % ( + classname, self.arg) self.sql(sql, (nodeid,)) # cleanup any blob filestorage when we commit - self.transactions.append((FileStorage.destroy, (self, classname, nodeid))) + self.transactions.append((FileStorage.destroy, (self, + classname, nodeid))) def hasnode(self, classname, nodeid): """ Determine if the database has a given node. @@ -1258,19 +1268,19 @@ # Return 1, not True, to match the type of the result of # the SQL operation below. return 1 - sql = 'select count(*) from _%s where id=%s'%(classname, self.arg) + sql = 'select count(*) from _%s where id=%s' % (classname, self.arg) self.sql(sql, (nodeid,)) return int(self.cursor.fetchone()[0]) def countnodes(self, classname): """ Count the number of nodes that exist for a particular Class. """ - sql = 'select count(*) from _%s'%classname + sql = 'select count(*) from _%s' % classname self.sql(sql) return self.cursor.fetchone()[0] def addjournal(self, classname, nodeid, action, params, creator=None, - creation=None): + creation=None): """ Journal the Action 'action' may be: @@ -1297,8 +1307,8 @@ # create the journal entry cols = 'nodeid,date,tag,action,params' - self.log_debug('addjournal %s%s %r %s %s %r'%(classname, - nodeid, journaldate, journaltag, action, params)) + self.log_debug('addjournal %s%s %r %s %s %r' % ( + classname, nodeid, journaldate, journaltag, action, params)) # make the journalled data marshallable if isinstance(params, type({})): @@ -1310,20 +1320,20 @@ journaldate = dc(journaldate) self.save_journal(classname, cols, nodeid, journaldate, - journaltag, action, params) + journaltag, action, params) def setjournal(self, classname, nodeid, journal): """Set the journal to the "journal" list.""" # clear out any existing entries - self.sql('delete from %s__journal where nodeid=%s'%(classname, - self.arg), (nodeid,)) + self.sql('delete from %s__journal where nodeid=%s' % ( + classname, self.arg), (nodeid,)) # create the journal entry cols = 'nodeid,date,tag,action,params' dc = self.to_sql_value(hyperdb.Date) for nodeid, journaldate, journaltag, action, params in journal: - self.log_debug('addjournal %s%s %r %s %s %r'%( + self.log_debug('addjournal %s%s %r %s %s %r' % ( classname, nodeid, journaldate, journaltag, action, params)) @@ -1333,7 +1343,7 @@ params = repr_export(params) self.save_journal(classname, cols, nodeid, dc(journaldate), - journaltag, action, params) + journaltag, action, params) def _journal_marshal(self, params, classname): """Convert the journal params values into safely repr'able and @@ -1358,7 +1368,7 @@ """ # make sure the node exists if not self.hasnode(classname, nodeid): - raise IndexError('%s has no node %s'%(classname, nodeid)) + raise IndexError('%s has no node %s' % (classname, nodeid)) cols = ','.join('nodeid date tag action params'.split()) journal = self.load_journal(classname, cols, nodeid) @@ -1391,14 +1401,14 @@ return res def save_journal(self, classname, cols, nodeid, journaldate, - journaltag, action, params): + journaltag, action, params): """ Save the journal entry to the database """ entry = (nodeid, journaldate, journaltag, action, params) # do the insert a = self.arg - sql = 'insert into %s__journal (%s) values (%s,%s,%s,%s,%s)'%( + sql = 'insert into %s__journal (%s) values (%s,%s,%s,%s,%s)' % ( classname, cols, a, a, a, a, a) self.sql(sql, entry) @@ -1406,7 +1416,7 @@ """ Load the journal from the database """ # now get the journal entries - sql = 'select %s from %s__journal where nodeid=%s order by date'%( + sql = 'select %s from %s__journal where nodeid=%s order by date' % ( cols, classname, self.arg) self.sql(sql, (nodeid,)) return self.cursor.fetchall() @@ -1419,7 +1429,7 @@ # do the delete for classname in self.classes: sql = "delete from %s__journal where date<%s and "\ - "action<>'create'"%(classname, self.arg) + "action<>'create'" % (classname, self.arg) self.sql(sql, (date_stamp,)) def sql_commit(self): @@ -1502,6 +1512,7 @@ self.Otk.close() self.Otk = None + # # The base Class class # @@ -1524,7 +1535,7 @@ """ A dumpable version of the schema that we can store in the database """ - return (self.key, [(x, repr(y)) for x,y in self.properties.items()]) + return (self.key, [(x, repr(y)) for x, y in self.properties.items()]) def enableJournalling(self): """Turn journalling on for this class @@ -1568,10 +1579,10 @@ if self.db.journaltag is None: raise DatabaseError(_('Database open read-only')) - if ('creator' in propvalues or 'actor' in propvalues or - 'creation' in propvalues or 'activity' in propvalues): + if ('creator' in propvalues or 'actor' in propvalues or + 'creation' in propvalues or 'activity' in propvalues): raise KeyError('"creator", "actor", "creation" and ' - '"activity" are reserved') + '"activity" are reserved') # new node's id newid = self.db.newid(self.classname) @@ -1585,17 +1596,17 @@ except KeyError: pass else: - raise ValueError('node with key "%s" exists'%value) + raise ValueError('node with key "%s" exists' % value) # try to handle this property try: prop = self.properties[key] except KeyError: - raise KeyError('"%s" has no property "%s"'%(self.classname, - key)) + raise KeyError('"%s" has no property "%s"' % (self.classname, + key)) if value is not None and isinstance(prop, Link): - if type(value) != type(''): + if not isinstance(value, type('')): raise ValueError('link value must be String') link_class = self.properties[key].classname # if it isn't a number, it's a key @@ -1603,11 +1614,11 @@ try: value = self.db.classes[link_class].lookup(value) except (TypeError, KeyError): - raise IndexError('new property "%s": %s not a %s'%( + raise IndexError('new property "%s": %s not a %s' % ( key, value, link_class)) elif not self.db.getclass(link_class).hasnode(value): - raise IndexError('%s has no node %s'%(link_class, - value)) + raise IndexError('%s has no node %s' % (link_class, + value)) # save off the value propvalues[key] = value @@ -1615,26 +1626,29 @@ # register the link with the newly linked node if self.do_journal and self.properties[key].do_journal: self.db.addjournal(link_class, value, 'link', - (self.classname, newid, key)) + (self.classname, newid, key)) elif isinstance(prop, Multilink): if value is None: value = [] - if not hasattr(value, '__iter__') or type(value) == type(''): - raise TypeError('new property "%s" not an iterable of ids'%key) + if not hasattr(value, '__iter__') or \ + isinstance(value, type('')): + raise TypeError('new property "%s" not an iterable of ids' + % key) # clean up and validate the list of links link_class = self.properties[key].classname l = [] for entry in value: - if type(entry) != type(''): + if not isinstance(entry, type('')): raise ValueError('"%s" multilink value (%r) ' - 'must contain Strings'%(key, value)) + 'must contain Strings' % ( + key, value)) # if it isn't a number, it's a key if not num_re.match(entry): try: entry = self.db.classes[link_class].lookup(entry) except (TypeError, KeyError): - raise IndexError('new property "%s": %s not a %s'%( + raise IndexError('new property "%s": %s not a %s' % ( key, entry, self.properties[key].classname)) l.append(entry) value = l @@ -1643,12 +1657,12 @@ # handle additions for nodeid in value: if not self.db.getclass(link_class).hasnode(nodeid): - raise IndexError('%s has no node %s'%(link_class, - nodeid)) + raise IndexError('%s has no node %s' % (link_class, + nodeid)) # register the link with the newly linked node if self.do_journal and self.properties[key].do_journal: self.db.addjournal(link_class, nodeid, 'link', - (self.classname, newid, key)) + (self.classname, newid, key)) elif isinstance(prop, String): if type(value) != type('') and type(value) != type(u''):
