Mercurial > p > roundup > code
diff roundup/backends/rdbms_common.py @ 6965:98d72d4bb489
flake8 fixes
Added str type as alias for missing unicode type in python3. Replace
type(x) == type(y) with isinstance(x, (type_of_y, or other type))
which is usually str or unicode (hence need for unicode def).
Used De Morgan's to convert things like:
type(value) != type('') and type(value) != type(u'')
into
not isinstance(value, (str, unicode))
a couple of variable name replacements.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 13 Sep 2022 16:19:52 -0400 |
| parents | cb2ed1e8c852 |
| children | 05d81de0d92d |
line wrap: on
line diff
--- a/roundup/backends/rdbms_common.py Tue Sep 13 00:40:36 2022 -0400 +++ b/roundup/backends/rdbms_common.py Tue Sep 13 16:19:52 2022 -0400 @@ -52,29 +52,37 @@ __docformat__ = 'restructuredtext' # standard python modules -import os, time, re, weakref, copy, logging, datetime +import copy +import datetime +import logging +import os +import re +import time + +from hashlib import md5 # 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 -from roundup.i18n import _ - -# support +from roundup.anypy.strings import b2s, bs2b, us2s, repr_export, eval_import from roundup.backends.blobfiles import FileStorage from roundup.backends.indexer_common import get_indexer from roundup.backends.indexer_common import Indexer as CommonIndexer from roundup.backends.sessions_rdbms import Sessions, OneTimeKeys from roundup.date import Range - +from roundup.hyperdb import String, Password, Date, Interval, Link, \ + Multilink, DatabaseError, Boolean, Number, Integer +from roundup.i18n import _ from roundup.mlink_expr import compile_expression -from roundup.anypy.strings import b2s, bs2b, us2s, repr_export, eval_import - -from hashlib import md5 # dummy value meaning "argument not passed" _marker = [] +# python 3 doesn't have a unicode type +try: + unicode # noqa: F821 +except NameError: + unicode = str + def _num_cvt(num): num = str(num) @@ -141,7 +149,7 @@ ranges = self.ranges singles = self.singles - if not singles and not ranges: return "(1=0)", [] + if not singles and not ranges: return "(1=0)", [] # noqa: E701 if ranges: between = '%s BETWEEN %s AND %s' % ( @@ -272,7 +280,7 @@ """ while True: row = self.cursor.fetchone() - if not row: break + if not row: break # noqa: E701 yield row def search_stringquote(self, value): @@ -428,8 +436,9 @@ for cn, klass in self.classes.items(): 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) @@ -542,14 +551,14 @@ implements_double_precision = True hyperdb_to_sql_datatypes = { - hyperdb.String : 'TEXT', - hyperdb.Date : 'TIMESTAMP', - hyperdb.Link : 'INTEGER', - hyperdb.Interval : 'VARCHAR(255)', - hyperdb.Password : 'VARCHAR(255)', - hyperdb.Boolean : 'BOOLEAN', - hyperdb.Number : 'REAL', - hyperdb.Integer : 'INTEGER', + hyperdb.String : 'TEXT', # noqa: E203 + hyperdb.Date : 'TIMESTAMP', # noqa: E203 + hyperdb.Link : 'INTEGER', # noqa: E203 + hyperdb.Interval : 'VARCHAR(255)', # noqa: E203 + hyperdb.Password : 'VARCHAR(255)', # noqa: E203 + hyperdb.Boolean : 'BOOLEAN', # noqa: E203 + hyperdb.Number : 'REAL', # noqa: E203 + hyperdb.Integer : 'INTEGER', # noqa: E203 } def hyperdb_to_sql_datatype(self, propclass, prop=None): @@ -620,7 +629,7 @@ if not self.config.RDBMS_ALLOW_ALTER: raise DatabaseError(_( - 'ALTER operation disallowed: %(old)r -> %(new)r.'% { + 'ALTER operation disallowed: %(old)r -> %(new)r.' % { 'old': old_spec, 'new': new_spec})) logger = logging.getLogger('roundup.hyperdb.backend') @@ -796,12 +805,11 @@ already-determined cols """ # journal table - 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)) + action varchar(255), params text)""" % ( + spec.classname, + self.hyperdb_to_sql_datatype(hyperdb.Date)) self.sql(sql) self.create_journal_table_indexes(spec) @@ -917,17 +925,21 @@ """ cn = cl.classname if cn in self.classes: - raise ValueError(_('Class "%s" already defined.'%cn)) + raise ValueError(_('Class "%s" already defined.' % cn)) self.classes[cn] = cl # add default Edit and View permissions - self.security.addPermission(name="Create", klass=cn, + self.security.addPermission( + name="Create", klass=cn, description="User is allowed to create "+cn) - self.security.addPermission(name="Edit", klass=cn, + self.security.addPermission( + name="Edit", klass=cn, description="User is allowed to edit "+cn) - self.security.addPermission(name="View", klass=cn, + self.security.addPermission( + name="View", klass=cn, description="User is allowed to access "+cn) - self.security.addPermission(name="Retire", klass=cn, + self.security.addPermission( + name="Retire", klass=cn, description="User is allowed to retire "+cn) def getclasses(self): @@ -961,16 +973,18 @@ # hyperdb_to_sql_value = { - hyperdb.String : str, + hyperdb.String : str, # noqa: E203 # fractional seconds by default - 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', - hyperdb.Number : lambda x: x, - hyperdb.Integer : lambda x: x, - hyperdb.Multilink : lambda x: x, # used in journal marshalling + hyperdb.Date : lambda x: x.formal(sep=' ', # noqa: E203 + sec='%06.3f'), + hyperdb.Link : int, # noqa: E203 + hyperdb.Interval : str, # noqa: E203 + hyperdb.Password : str, # noqa: E203 + hyperdb.Boolean : lambda x: x and 'TRUE' or 'FALSE', # noqa: E203 + hyperdb.Number : lambda x: x, # noqa: E203 + hyperdb.Integer : lambda x: x, # noqa: E203 + # used in journal marshalling + hyperdb.Multilink : lambda x: x, # noqa: E203 } def to_sql_value(self, propklass): @@ -1073,9 +1087,10 @@ t, self.arg, self.arg) self.sql(sql, (entry, nodeid)) - def setnode(self, classname, nodeid, values, multilink_changes={}): + def setnode(self, classname, nodeid, values, multilink_changes=None): """ Change the specified node. """ + if multilink_changes is None: multilink_changes = {} # noqa: E701 self.log_debug('setnode %s%s %r' % (classname, nodeid, values)) # clear this node out of the cache if it's in there @@ -1161,8 +1176,8 @@ for col, (add, remove) in multilink_changes.items(): tn = '%s_%s' % (classname, col) if add: - sql = 'insert into %s (nodeid, linkid) values (%s,%s)' % (tn, - self.arg, self.arg) + 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))) @@ -1174,16 +1189,17 @@ self.sql(sql, [int(nodeid)] + remove) sql_to_hyperdb_value = { - hyperdb.String : us2s, - hyperdb.Date : date_to_hyperdb_value, -# hyperdb.Link : int, # XXX numeric ids - hyperdb.Link : str, - hyperdb.Interval : date.Interval, - hyperdb.Password : lambda x: password.Password(encrypted=x), - hyperdb.Boolean : _bool_cvt, - hyperdb.Number : _num_cvt, - hyperdb.Integer : int, - hyperdb.Multilink : lambda x: x, # used in journal marshalling + hyperdb.String : us2s, # noqa: E203 + hyperdb.Date : date_to_hyperdb_value, # noqa: E203 + # hyperdb.Link : int, # XXX numeric ids + hyperdb.Link : str, # noqa: E203 + hyperdb.Interval : date.Interval, # noqa: E203 + hyperdb.Password : lambda x: password.Password(encrypted=x), # noqa: E203 + hyperdb.Boolean : _bool_cvt, # noqa: E203 + hyperdb.Number : _num_cvt, # noqa: E203 + hyperdb.Integer : int, # noqa: E203 + # used in journal marshalling + hyperdb.Multilink : lambda x: x, # noqa: E203 } def to_hyperdb_value(self, propklass): @@ -1203,22 +1219,22 @@ """ if propname not in node: prop = self.getclass(classname).properties[propname] - tn = prop.table_name + tn = prop.table_name lid = prop.linkid_name nid = prop.nodeid_name - w = '' + w = '' joi = '' if prop.computed: if isinstance(prop.rev_property, Link): - w = ' and %s.__retired__=0'%tn + w = ' and %s.__retired__=0' % tn else: tn2 = '_' + prop.classname joi = ', %s' % tn2 - w = ' and %s.%s=%s.id and %s.__retired__=0'%(tn, lid, - tn2, tn2) + w = ' and %s.%s=%s.id and %s.__retired__=0' % ( + tn, lid, tn2, tn2) cursor = self.sql_new_cursor(name='_materialize_multilink') - sql = 'select %s from %s%s where %s=%s%s' %(lid, tn, joi, nid, - self.arg, w) + sql = 'select %s from %s%s where %s=%s%s' % (lid, tn, joi, nid, + self.arg, w) self.sql(sql, (nodeid,), cursor) # Reduce this to only the first row (the ID), this can save a # lot of space for large query results (not using fetchall) @@ -1644,7 +1660,8 @@ database """ return (self.key, - [(x, repr(y)) for x, y in self.properties.items() if not y.computed]) + [(x, repr(y)) for x, y in + self.properties.items() if not y.computed]) def enableJournalling(self): """Turn journalling on for this class @@ -1689,14 +1706,14 @@ raise DatabaseError(_('Database open read-only')) if ('creator' in propvalues or 'actor' in propvalues or - 'creation' in propvalues or 'activity' in propvalues): + 'creation' in propvalues or 'activity' in propvalues): raise KeyError('"creator", "actor", "creation" and ' '"activity" are reserved') for p in propvalues: prop = self.properties[p] if prop.computed: - raise KeyError('"%s" is a computed property'%p) + raise KeyError('"%s" is a computed property' % p) # new node's id newid = self.db.newid(self.classname) @@ -1779,48 +1796,48 @@ (self.classname, newid, key)) elif isinstance(prop, String): - if type(value) != type('') and type(value) != type(u''): - raise TypeError('new property "%s" not a string'%key) + if not isinstance(value, (str, unicode)): + raise TypeError('new property "%s" not a string' % key) if prop.indexme: self.db.indexer.add_text((self.classname, newid, key), - value) + value) elif isinstance(prop, Password): if not isinstance(value, password.Password): - raise TypeError('new property "%s" not a Password'%key) + raise TypeError('new property "%s" not a Password' % key) elif isinstance(prop, Date): if value is not None and not isinstance(value, date.Date): - raise TypeError('new property "%s" not a Date'%key) + raise TypeError('new property "%s" not a Date' % key) elif isinstance(prop, Interval): if value is not None and not isinstance(value, date.Interval): - raise TypeError('new property "%s" not an Interval'%key) + raise TypeError('new property "%s" not an Interval' % key) elif value is not None and isinstance(prop, Number): try: float(value) except ValueError: - raise TypeError('new property "%s" not numeric'%key) + raise TypeError('new property "%s" not numeric' % key) elif value is not None and isinstance(prop, Integer): try: int(value) except ValueError: - raise TypeError('new property "%s" not integer'%key) + raise TypeError('new property "%s" not integer' % key) elif value is not None and isinstance(prop, Boolean): try: int(value) except ValueError: - raise TypeError('new property "%s" not boolean'%key) + raise TypeError('new property "%s" not boolean' % key) # make sure there's data where there needs to be for key, prop in self.properties.items(): if key in propvalues: continue if key == self.key: - raise ValueError('key property "%s" is required'%key) + raise ValueError('key property "%s" is required' % key) if isinstance(prop, Multilink): propvalues[key] = [] else: @@ -1851,9 +1868,9 @@ # handle common case -- that property is in dict -- first # if None and one of creator/creation actor/activity return None if propname in d: - r = d [propname] + r = d[propname] # return copy of our list - if isinstance (r, list): + if isinstance(r, list): return r[:] if r is not None: return r @@ -1919,10 +1936,10 @@ if not propvalues: return propvalues - 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') if 'id' in propvalues: raise KeyError('"id" is reserved') @@ -1930,7 +1947,7 @@ for p in propvalues: prop = self.properties[p] if prop.computed: - raise KeyError('"%s" is a computed property'%p) + raise KeyError('"%s" is a computed property' % p) if self.db.journaltag is None: raise DatabaseError(_('Database open read-only')) @@ -1961,7 +1978,7 @@ except KeyError: pass else: - raise ValueError('node with key "%s" exists'%value) + raise ValueError('node with key "%s" exists' % value) # this will raise the KeyError if the property isn't valid # ... we don't use getprops() here because we only care about @@ -1969,7 +1986,7 @@ try: prop = self.properties[propname] except KeyError: - raise KeyError('"%s" has no property named "%s"'%( + raise KeyError('"%s" has no property named "%s"' % ( self.classname, propname)) # if the value's the same as the existing value, no sense in @@ -1984,52 +2001,54 @@ if isinstance(prop, Link): link_class = prop.classname # if it isn't a number, it's a key - if value is not None and not isinstance(value, type('')): - raise ValueError('property "%s" link value be a string'%( + if value is not None and not isinstance(value, str): + raise ValueError('property "%s" link value be a string' % ( propname)) - if isinstance(value, type('')) and not num_re.match(value): + if isinstance(value, str) and not num_re.match(value): 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' % ( propname, value, prop.classname)) if (value is not None and 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)) if self.do_journal and prop.do_journal: # register the unlink with the old linked node if node[propname] is not None: - self.db.addjournal(link_class, node[propname], + self.db.addjournal( + link_class, node[propname], ''"unlink", (self.classname, nodeid, propname)) # register the link with the newly linked node if value is not None: self.db.addjournal(link_class, value, ''"link", - (self.classname, nodeid, propname)) + (self.classname, nodeid, propname)) elif isinstance(prop, Multilink): if value is None: value = [] - if not hasattr(value, '__iter__') or type(value) == type(''): + if not hasattr(value, '__iter__') or isinstance(value, str): raise TypeError('new property "%s" not an iterable of' - ' ids'%propname) + ' ids' % propname) link_class = self.properties[propname].classname l = [] for entry in value: # if it isn't a number, it's a key - if type(entry) != type(''): + if not isinstance(entry, str): raise ValueError('new property "%s" link value ' - 'must be a string'%propname) + 'must be a string' % propname) 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'%( - propname, entry, - self.properties[propname].classname)) + raise IndexError( + 'new property "%s": %s not a %s' % ( + propname, entry, + self.properties[propname].classname)) l.append(entry) value = l propvalues[propname] = value @@ -2049,7 +2068,7 @@ # register the unlink with the old linked node if self.do_journal and self.properties[propname].do_journal: self.db.addjournal(link_class, id, 'unlink', - (self.classname, nodeid, propname)) + (self.classname, nodeid, propname)) l.remove(id) remove.append(id) @@ -2065,12 +2084,12 @@ # result in a SQL query, it is more efficient to # avoid the check if possible. if not self.db.getclass(link_class).hasnode(id): - raise IndexError('%s has no node %s'%(link_class, - id)) + raise IndexError('%s has no node %s' % (link_class, + id)) # register the link with the newly linked node if self.do_journal and self.properties[propname].do_journal: self.db.addjournal(link_class, id, 'link', - (self.classname, nodeid, propname)) + (self.classname, nodeid, propname)) l.append(id) add.append(id) @@ -2085,48 +2104,50 @@ journalvalues[propname] = tuple(l) elif isinstance(prop, String): - if value is not None and type(value) != type('') and type(value) != type(u''): - raise TypeError('new property "%s" not a string'%propname) + if value is not None and not isinstance(value, (str, unicode)): + raise TypeError( + 'new property "%s" not a string' % propname) if prop.indexme: - if value is None: value = '' - self.db.indexer.add_text((self.classname, nodeid, propname), - value) + if value is None: value = '' # noqa: E701 + self.db.indexer.add_text( + (self.classname, nodeid, propname), value) elif isinstance(prop, Password): if not isinstance(value, password.Password): - raise TypeError('new property "%s" not a Password'%propname) + raise TypeError( + 'new property "%s" not a Password' % propname) propvalues[propname] = value journalvalues[propname] = \ current and password.JournalPassword(current) elif value is not None and isinstance(prop, Date): if not isinstance(value, date.Date): - raise TypeError('new property "%s" not a Date'% propname) + raise TypeError('new property "%s" not a Date' % propname) propvalues[propname] = value elif value is not None and isinstance(prop, Interval): if not isinstance(value, date.Interval): raise TypeError('new property "%s" not an ' - 'Interval'%propname) + 'Interval' % propname) propvalues[propname] = value elif value is not None and isinstance(prop, Number): try: float(value) except ValueError: - raise TypeError('new property "%s" not numeric'%propname) + raise TypeError('new property "%s" not numeric' % propname) elif value is not None and isinstance(prop, Integer): try: int(value) except ValueError: - raise TypeError('new property "%s" not integer'%propname) + raise TypeError('new property "%s" not integer' % propname) elif value is not None and isinstance(prop, Boolean): try: int(value) except ValueError: - raise TypeError('new property "%s" not boolean'%propname) + raise TypeError('new property "%s" not boolean' % propname) # record quiet properties to omit from history/changelog if prop.quiet: @@ -2174,8 +2195,8 @@ # use the arg for __retired__ to cope with any odd database type # conversion (hello, sqlite) - sql = 'update _%s set __retired__=%s where id=%s'%(self.classname, - self.db.arg, self.db.arg) + sql = 'update _%s set __retired__=%s where id=%s' % ( + self.classname, self.db.arg, self.db.arg) self.db.sql(sql, (nodeid, nodeid)) if self.do_journal: self.db.addjournal(self.classname, nodeid, ''"retired", None) @@ -2194,18 +2215,18 @@ # check if key property was overrided key = self.getkey() try: - id = self.lookup(node[key]) + self.lookup(node[key]) except KeyError: pass else: raise KeyError("Key property (%s) of retired node clashes " - "with existing one (%s)" % (key, node[key])) + "with existing one (%s)" % (key, node[key])) self.fireAuditors('restore', nodeid, None) # use the arg for __retired__ to cope with any odd database type # conversion (hello, sqlite) - sql = 'update _%s set __retired__=%s where id=%s'%(self.classname, - self.db.arg, self.db.arg) + sql = 'update _%s set __retired__=%s where id=%s' % ( + self.classname, self.db.arg, self.db.arg) self.db.sql(sql, (0, nodeid)) if self.do_journal: self.db.addjournal(self.classname, nodeid, ''"restored", None) @@ -2215,8 +2236,8 @@ def is_retired(self, nodeid): """Return true if the node is rerired """ - sql = 'select __retired__ from _%s where id=%s'%(self.classname, - self.db.arg) + sql = 'select __retired__ from _%s where id=%s' % (self.classname, + self.db.arg) self.db.sql(sql, (nodeid,)) return int(self.db.sql_fetchone()[0]) > 0 @@ -2275,19 +2296,20 @@ otherwise a KeyError is raised. """ if not self.key: - raise TypeError('No key property set for class %s'%self.classname) + raise TypeError('No key property set for class %s' % + self.classname) # use the arg to handle any odd database type conversion (hello, # sqlite) - sql = "select id from _%s where _%s=%s and __retired__=%s"%( + sql = "select id from _%s where _%s=%s and __retired__=%s" % ( self.classname, self.key, self.db.arg, self.db.arg) self.db.sql(sql, (str(keyvalue), 0)) # see if there was a result that's not retired row = self.db.sql_fetchone() if not row: - raise KeyError('No key (%s) value "%s" for "%s"'%(self.key, - keyvalue, self.classname)) + raise KeyError('No key (%s) value "%s" for "%s"' % ( + self.key, keyvalue, self.classname)) # return the id # XXX numeric ids @@ -2314,11 +2336,12 @@ # validate the args props = self.getprops() - for propname, nodeids in propspec.items(): + for propname, _nodeids in propspec.items(): # check the prop is OK prop = props[propname] if not isinstance(prop, Link) and not isinstance(prop, Multilink): - raise TypeError("'%s' not a Link/Multilink property"%propname) + raise TypeError("'%s' not a Link/Multilink property" % + propname) # first, links a = self.db.arg @@ -2328,26 +2351,26 @@ for prop, values in propspec.items(): if not isinstance(props[prop], hyperdb.Link): continue - if type(values) is type({}) and len(values) == 1: + if isinstance(values, dict) and len(values) == 1: values = list(values)[0] - if type(values) is type(''): + if isinstance(values, str): allvalues += (values,) - where.append('_%s = %s'%(prop, a)) + where.append('_%s = %s' % (prop, a)) elif values is None: - where.append('_%s is NULL'%prop) + where.append('_%s is NULL' % prop) else: values = list(values) s = '' if None in values: values.remove(None) - s = '_%s is NULL or '%prop + s = '_%s is NULL or ' % prop allvalues += tuple(values) - s += '_%s in (%s)'%(prop, ','.join([a]*len(values))) - where.append('(' + s +')') + s += '_%s in (%s)' % (prop, ','.join([a]*len(values))) + where.append('(' + s + ')') if where: allvalues = (0, ) + allvalues sql.append("""select id from _%s where __retired__=%s - and %s"""%(self.classname, a, ' and '.join(where))) + and %s""" % (self.classname, a, ' and '.join(where))) # now multilinks for prop, values in propspec.items(): @@ -2370,15 +2393,15 @@ allvalues += (0, ) dis = 'distinct ' ord = ' order by %s.id' % cn - if type(values) is type(''): + if isinstance(values, str): allvalues += (values,) s = a else: allvalues += tuple(values) s = ','.join([a]*len(values)) sql.append("""select %s%s.id from %s, %s where %s.__retired__=%s - %sand %s.id = %s.%s and %s.%s in (%s)%s"""%(dis, cn, cn, - tn, cn, a, ret, cn, tn, nn, tn, ln, s, ord)) + %sand %s.id = %s.%s and %s.%s in (%s)%s""" % ( + dis, cn, cn, tn, cn, a, ret, cn, tn, nn, tn, ln, s, ord)) if not sql: return [] @@ -2401,13 +2424,14 @@ for propname in requirements: prop = self.properties[propname] if not isinstance(prop, String): - raise TypeError("'%s' not a String property"%propname) + raise TypeError("'%s' not a String property" % propname) where.append(propname) args.append(requirements[propname].lower()) # generate the where clause - s = ' and '.join(['lower(_%s)=%s'%(col, self.db.arg) for col in where]) - sql = 'select id from _%s where %s and __retired__=%s'%( + s = ' and '.join(['lower(_%s)=%s' % (col, + self.db.arg) for col in where]) + sql = 'select id from _%s where %s and __retired__=%s' % ( self.classname, s, self.db.arg) args.append(0) self.db.sql(sql, tuple(args)) @@ -2433,11 +2457,11 @@ compare = '>' else: compare = '=' - sql = 'select id from _%s where __retired__%s%s'%(self.classname, - compare, self.db.arg) + sql = 'select id from _%s where __retired__%s%s' % ( + self.classname, compare, self.db.arg) else: args = () - sql = 'select id from _%s'%self.classname + sql = 'select id from _%s' % self.classname self.db.sql(sql, args) # XXX numeric ids ids = [str(x[0]) for x in self.db.cursor.fetchall()] @@ -2450,21 +2474,21 @@ backend. """ multilink_table = proptree.propclass.table_name - nodeid_name = proptree.propclass.nodeid_name - linkid_name = proptree.propclass.linkid_name + nodeid_name = proptree.propclass.nodeid_name + linkid_name = proptree.propclass.linkid_name if parentname is None: parentname = '_' + proptree.parent.classname w = '' if proptree.need_retired: - w = ' where %s.__retired__=0'%(multilink_table) + w = ' where %s.__retired__=0' % (multilink_table) if proptree.need_child_retired: tn1 = multilink_table tn2 = '_' + proptree.classname - w = ', %s where %s.%s=%s.id and %s.__retired__=0'%(tn2, - tn1, linkid_name, tn2, tn2) - return '%s.id not in (select %s from %s%s)'%(parentname, nodeid_name, - multilink_table, w) + w = ', %s where %s.%s=%s.id and %s.__retired__=0' % ( + tn2, tn1, linkid_name, tn2, tn2) + return '%s.id not in (select %s from %s%s)' % ( + parentname, nodeid_name, multilink_table, w) def _filter_multilink_expression_fallback(self, proptree, expr): '''This is a fallback for database that do not support @@ -2496,7 +2520,7 @@ elif proptree.need_child_retired: tn2 = '_' + proptree.classname j = ' LEFT OUTER JOIN %s ON %s.id = m.%s' % (tn2, tn2, lid) - w = ' and %s.__retired__=0'%(tn2) + w = ' and %s.__retired__=0' % (tn2) s = '%s.id' % tn2 stmnt = "SELECT c.id, %s FROM _%s as c " \ @@ -2512,12 +2536,12 @@ last_id = nodeid else: # we have all multilink items -> evaluate! - if is_valid(kws): append(last_id) + if is_valid(kws): append(last_id) # noqa: E701 last_id, kws = nodeid, [] if kw is not None: kws.append(int(kw)) - if last_id is not None and is_valid(kws): + if last_id is not None and is_valid(kws): append(last_id) # we have ids of the classname table @@ -2542,6 +2566,7 @@ lambda_atom = lambda n: atom if n.x >= 0 else atom_nil values = [] w = expr.generate(lambda_atom) + def collect_values(n): if n.x >= 0: values.append(n.x) @@ -2559,15 +2584,15 @@ d[entry] = entry l = [] if None in d or not d: - if None in d: del d[None] - l.append('_%s._%s is NULL'%(pln, prp)) + if None in d: del d[None] # noqa: E701 + l.append('_%s._%s is NULL' % (pln, prp)) if d: v = list(d) s = ','.join([self.db.arg for x in v]) - l.append('(_%s._%s in (%s))'%(pln, prp, s)) + l.append('(_%s._%s in (%s))' % (pln, prp, s)) args = v if l: - where = '(' + ' or '.join(l) +')' + where = '(' + ' or '.join(l) + ')' return where, args def _filter_multilink_expression(self, proptree, v): @@ -2595,16 +2620,17 @@ w = j = '' if proptree.need_retired: - w = ' and %s.__retired__=0'%(multilink_table) + w = ' and %s.__retired__=0' % (multilink_table) elif proptree.need_child_retired: tn1 = multilink_table tn2 = '_' + proptree.classname j = ', %s' % tn2 - w = ' and %s.%s=%s.id and %s.__retired__=0'%(tn1, lid, tn2, tn2) + w = ' and %s.%s=%s.id and %s.__retired__=0' % ( + tn1, lid, tn2, tn2) atom = \ "%s IN(SELECT %s FROM %s%s WHERE %s=a.id%s)" % ( - self.db.arg, lid, multilink_table, j, nid, w) + self.db.arg, lid, multilink_table, j, nid, w) atom_nil = self._subselect(proptree, 'a') lambda_atom = lambda n: atom if n.x >= 0 else atom_nil @@ -2612,10 +2638,11 @@ intron = \ "_%(classname)s.id in (SELECT id " \ "FROM _%(classname)s AS a WHERE %(condition)s) " % { - 'classname' : classname, - 'condition' : expr.generate(lambda_atom) } + 'classname': classname, + 'condition': expr.generate(lambda_atom)} values = [] + def collect_values(n): if n.x >= 0: values.append(n.x) @@ -2625,22 +2652,22 @@ except: # fallback behavior when expression parsing above fails orclause = '' - if '-1' in v : - v = [x for x in v if int (x) > 0] + if '-1' in v: + v = [x for x in v if int(x) > 0] orclause = self._subselect(proptree) where = [] where.append("%s.%s in (%s)" % (multilink_table, lid, - ','.join([self.db.arg] * len(v)))) - where.append('_%s.id=%s.%s'%(classname, multilink_table, nid)) - where = ' and '.join (where) - if orclause : - where = '((' + ' or '.join ((where + ')', orclause)) + ')' + ','.join([self.db.arg] * len(v)))) + where.append('_%s.id=%s.%s' % (classname, multilink_table, nid)) + where = ' and '.join(where) + if orclause: + where = '((' + ' or '.join((where + ')', orclause)) + ')' return where, v - def _filter_sql (self, search_matches, filterspec, srt=[], grp=[], retr=0, - retired=False, exact_match_spec={}, limit=None, - offset=None): + def _filter_sql(self, search_matches, filterspec, srt=[], grp=[], retr=0, + retired=False, exact_match_spec={}, limit=None, + offset=None): """ Compute the proptree and the SQL/ARGS for a filter. For argument description see filter below. We return a 3-tuple, the proptree, the sql and the sql-args @@ -2663,13 +2690,13 @@ # figure the WHERE clause from the filterspec use_distinct = False # Do we need a distinct clause? - sortattr = self._sortattr (group = grp, sort = srt) + sortattr = self._sortattr(group=grp, sort=srt) proptree = self._proptree(filterspec, exact_match_spec, sortattr, retr) mlseen = 0 for pt in reversed(proptree.sortattr): p = pt while p.parent: - if isinstance (p.propclass, Multilink): + if isinstance(p.propclass, Multilink): mlseen = True if mlseen: p.sort_ids_needed = True @@ -2679,9 +2706,7 @@ pt.attr_sort_done = pt.tree_sort_done = True proptree.compute_sort_done() - cols = ['_%s.id'%icn] - mlsort = [] - rhsnum = 0 + cols = ['_%s.id' % icn] for p in proptree: rc = ac = oc = None cn = p.classname @@ -2692,10 +2717,10 @@ v = p.val propclass = p.propclass if p.parent == proptree and p.name == 'id' \ - and 'retrieve' in p.need_for: + and 'retrieve' in p.need_for: p.sql_idx = 0 if 'sort' in p.need_for or 'retrieve' in p.need_for: - rc = oc = ac = '_%s._%s'%(pln, k) + rc = oc = ac = '_%s._%s' % (pln, k) if isinstance(propclass, Multilink): if 'search' in p.need_for: # if we joining with Multilink tables we need distinct @@ -2706,15 +2731,15 @@ frum.append(tn) if p.children or p.need_child_retired: frum.append('_%s as _%s' % (cn, ln)) - where.append('%s.%s=_%s.id'%(tn, lid, ln)) + where.append('%s.%s=_%s.id' % (tn, lid, ln)) if p.need_child_retired: - where.append('_%s.__retired__=0'%(ln)) + where.append('_%s.__retired__=0' % (ln)) # Note: need the where-clause if p has # children that compute additional restrictions - if (not p.has_values - or (not isinstance(v, type([])) and v != '-1') - or p.children): - where.append('_%s.id=%s.%s'%(pln, tn, nid)) + if (not p.has_values or + (not isinstance(v, type([])) and v != '-1') or + p.children): + where.append('_%s.id=%s.%s' % (pln, tn, nid)) if v in ('-1', ['-1'], []): # only match rows that have count(linkid)=0 in the # corresponding multilink table) @@ -2728,11 +2753,11 @@ where.append(w) args += arg else: - where.append('%s.%s=%s'%(tn, lid, a)) + where.append('%s.%s=%s' % (tn, lid, a)) args.append(v) # Don't match retired nodes if rev_multilink if p.need_retired: - where.append('%s.__retired__=0'%(tn)) + where.append('%s.__retired__=0' % (tn)) if 'sort' in p.need_for: assert not p.attr_sort_done and not p.sort_ids_needed elif k == 'id': @@ -2744,13 +2769,13 @@ if not v: return None s = ','.join([a for x in v]) - where.append('_%s.%s in (%s)'%(pln, k, s)) + where.append('_%s.%s in (%s)' % (pln, k, s)) args = args + v else: - where.append('_%s.%s=%s'%(pln, k, a)) + where.append('_%s.%s=%s' % (pln, k, a)) args.append(v) if 'sort' in p.need_for or 'retrieve' in p.need_for: - rc = oc = ac = '_%s.id'%pln + rc = oc = ac = '_%s.id' % pln elif isinstance(propclass, String): if 'search' in p.need_for: exact = [] @@ -2775,16 +2800,16 @@ w = [] for vv, ex in zip(v, exact): if ex: - w.append("_%s._%s %s %s"%( + w.append("_%s._%s %s %s" % ( pln, k, self.case_sensitive_equal, a)) args.append(vv) else: - w.append("_%s._%s %s %s ESCAPE %s"%( + w.append("_%s._%s %s %s ESCAPE %s" % ( pln, k, self.case_insensitive_like, a, a)) args.extend((vv, '\\')) - where.append ('(' + ' and '.join(w) + ')') + where.append('(' + ' and '.join(w) + ')') if 'sort' in p.need_for: - oc = ac = 'lower(_%s._%s)'%(pln, k) + oc = ac = 'lower(_%s._%s)' % (pln, k) elif isinstance(propclass, Link): if 'search' in p.need_for: if p.children: @@ -2792,7 +2817,7 @@ frum.append('_%s as _%s' % (cn, ln)) c = [x for x in p.children if 'search' in x.need_for] if c: - where.append('_%s._%s=_%s.id'%(pln, k, ln)) + where.append('_%s._%s=_%s.id' % (pln, k, ln)) if p.has_values: if isinstance(v, type([])): w, arg = self._filter_link_expression(p, v) @@ -2802,26 +2827,26 @@ else: if v in ('-1', None): v = None - where.append('_%s._%s is NULL'%(pln, k)) + where.append('_%s._%s is NULL' % (pln, k)) else: - where.append('_%s._%s=%s'%(pln, k, a)) + where.append('_%s._%s=%s' % (pln, k, a)) args.append(v) if 'sort' in p.need_for: lp = p.cls.labelprop() - oc = ac = '_%s._%s'%(pln, k) + oc = ac = '_%s._%s' % (pln, k) if lp != 'id': if p.tree_sort_done: loj.append( - 'LEFT OUTER JOIN _%s as _%s on _%s._%s=_%s.id'%( - cn, ln, pln, k, ln)) - oc = '_%s._%s'%(ln, lp) + 'LEFT OUTER JOIN _%s as _%s on _%s._%s=_%s.id' % ( + cn, ln, pln, k, ln)) + oc = '_%s._%s' % (ln, lp) if 'retrieve' in p.need_for: - rc = '_%s._%s'%(pln, k) + rc = '_%s._%s' % (pln, k) elif isinstance(propclass, Date) and 'search' in p.need_for: dc = self.db.to_sql_value(hyperdb.Date) if isinstance(v, type([])): s = ','.join([a for x in v]) - where.append('_%s._%s in (%s)'%(pln, k, s)) + where.append('_%s._%s in (%s)' % (pln, k, s)) args = args + [dc(date.Date(x)) for x in v] else: try: @@ -2830,19 +2855,19 @@ for d in v.split(','): w1 = [] if d == '-': - wh.append('_%s._%s is NULL'%(pln, k)) + wh.append('_%s._%s is NULL' % (pln, k)) continue # Try to filter on range of dates date_rng = propclass.range_from_raw(d, self.db) if date_rng.from_value: - w1.append('_%s._%s >= %s'%(pln, k, a)) + w1.append('_%s._%s >= %s' % (pln, k, a)) ar.append(dc(date_rng.from_value)) if date_rng.to_value: - w1.append('_%s._%s <= %s'%(pln, k, a)) + w1.append('_%s._%s <= %s' % (pln, k, a)) ar.append(dc(date_rng.to_value)) - wh.append (' and '.join (w1)) - where.append ('(' + ' or '.join (wh) + ')') - args.extend (ar) + wh.append(' and '.join(w1)) + where.append('(' + ' or '.join(wh) + ')') + args.extend(ar) except ValueError: # If range creation fails - ignore that search parameter pass @@ -2851,50 +2876,52 @@ if 'search' in p.need_for: if isinstance(v, type([])): s = ','.join([a for x in v]) - where.append('_%s.__%s_int__ in (%s)'%(pln, k, s)) + where.append('_%s.__%s_int__ in (%s)' % (pln, k, s)) args = args + [date.Interval(x).as_seconds() for x in v] else: try: # Try to filter on range of intervals date_rng = Range(v, date.Interval) if date_rng.from_value: - where.append('_%s.__%s_int__ >= %s'%(pln, k, a)) + where.append('_%s.__%s_int__ >= %s' % ( + pln, k, a)) args.append(date_rng.from_value.as_seconds()) if date_rng.to_value: - where.append('_%s.__%s_int__ <= %s'%(pln, k, a)) + where.append('_%s.__%s_int__ <= %s' % ( + pln, k, a)) args.append(date_rng.to_value.as_seconds()) except ValueError: # If range creation fails - ignore search parameter pass if 'sort' in p.need_for: - oc = ac = '_%s.__%s_int__'%(pln,k) + oc = ac = '_%s.__%s_int__' % (pln, k) if 'retrieve' in p.need_for: - rc = '_%s._%s'%(pln,k) + rc = '_%s._%s' % (pln, k) elif isinstance(propclass, Boolean) and 'search' in p.need_for: - if type(v) == type(""): + if isinstance(v, str): v = v.split(',') - if type(v) != type([]): + if not isinstance(v, list): v = [v] bv = [] for val in v: - if type(val) is type(''): - bv.append(propclass.from_raw (val)) + if isinstance(val, str): + bv.append(propclass.from_raw(val)) else: bv.append(bool(val)) if len(bv) == 1: - where.append('_%s._%s=%s'%(pln, k, a)) + where.append('_%s._%s=%s' % (pln, k, a)) args = args + bv else: s = ','.join([a for x in v]) - where.append('_%s._%s in (%s)'%(pln, k, s)) + where.append('_%s._%s in (%s)' % (pln, k, s)) args = args + bv elif 'search' in p.need_for: if isinstance(v, type([])): s = ','.join([a for x in v]) - where.append('_%s._%s in (%s)'%(pln, k, s)) + where.append('_%s._%s in (%s)' % (pln, k, s)) args = args + v else: - where.append('_%s._%s=%s'%(pln, k, a)) + where.append('_%s._%s=%s' % (pln, k, a)) args.append(v) if oc: if p.sort_ids_needed: @@ -2904,8 +2931,8 @@ cols.append(ac) if p.tree_sort_done and p.sort_direction: # Don't select top-level id or multilink twice - if (not p.sort_ids_needed or ac != oc) and (p.name != 'id' - or p.parent != proptree): + if (not p.sort_ids_needed or ac != oc) and ( + p.name != 'id' or p.parent != proptree): if rc == oc: p.sql_idx = len(cols) cols.append(oc) @@ -2919,7 +2946,7 @@ if 'retrieve' in p.need_for and p.sql_idx is None: assert(rc) p.sql_idx = len(cols) - cols.append (rc) + cols.append(rc) props = self.getprops() @@ -2928,12 +2955,12 @@ op = '=' if retired: op = '!=' - where.append('_%s.__retired__%s0'%(icn, op)) + where.append('_%s.__retired__%s0' % (icn, op)) # add results of full text search if search_matches is not None: s = ','.join([a for x in search_matches]) - where.append('_%s.id in (%s)'%(icn, s)) + where.append('_%s.id in (%s)' % (icn, s)) args = args + [x for x in search_matches] # construct the SQL @@ -2945,7 +2972,7 @@ where = '' if use_distinct: # Avoid dupes - cols[0] = 'distinct(_%s.id)'%icn + cols[0] = 'distinct(_%s.id)' % icn order = [] # keep correct sequence of order attributes. @@ -2954,7 +2981,7 @@ continue order.extend(sa.orderby) if order: - order = ' order by %s'%(','.join(order)) + order = ' order by %s' % (','.join(order)) else: order = '' @@ -2968,7 +2995,7 @@ offset = '' cols = ','.join(cols) loj = ' '.join(loj) - sql = 'select %s from %s %s %s%s%s%s'%( + sql = 'select %s from %s %s %s%s%s%s' % ( cols, frum, loj, where, order, limit, offset) args = tuple(args) __traceback_info__ = (sql, args) @@ -2998,10 +3025,10 @@ if __debug__: start_t = time.time() - sq = self._filter_sql (search_matches, filterspec, sort, group, - retired=retired, - exact_match_spec=exact_match_spec, - limit=limit, offset=offset) + sq = self._filter_sql(search_matches, filterspec, sort, group, + retired=retired, + exact_match_spec=exact_match_spec, + limit=limit, offset=offset) # nothing to match? if sq is None: return [] @@ -3024,9 +3051,9 @@ for p in proptree: if hasattr(p, 'auxcol'): p.sort_ids = [row[p.auxcol] for row in l] - p.sort_result = p._sort_repr \ - (p.propclass.sort_repr, p.sort_ids) - l = proptree.sort ([str(row[0]) for row in l]) + p.sort_result = p._sort_repr( + p.propclass.sort_repr, p.sort_ids) + l = proptree.sort([str(row[0]) for row in l]) if __debug__: self.db.stats['filtering'] += (time.time() - start_t) @@ -3057,7 +3084,7 @@ for p in proptree: if 'retrieve' in p.need_for: cn = p.parent.classname - ptid = p.parent.id # not the nodeid! + ptid = p.parent.id # not the nodeid! key = (cn, ptid) if key not in classes: classes[key] = {} @@ -3067,9 +3094,9 @@ p.to_hyperdb = self.db.to_hyperdb_value(p.propclass.__class__) while True: row = cursor.fetchone() - if not row: break + if not row: break # noqa: E701 # populate cache with current items - for (classname, ptid), pt in classes.items(): + for (classname, _ptid), pt in classes.items(): nodeid = str(row[pt['id'].sql_idx]) key = (classname, nodeid) if key in self.db.cache: @@ -3098,11 +3125,11 @@ start_t = time.time() self.db.sql(sql) - l = self.db.sql_fetchall() + results = self.db.sql_fetchall() if __debug__: self.db.stats['filtering'] += (time.time() - start_t) - return l + return results def count(self): """Get the number of nodes in this class. @@ -3148,7 +3175,7 @@ for prop, propclass in self.getprops().items(): if isinstance(propclass, String) and propclass.indexme: self.db.indexer.add_text((self.classname, nodeid, prop), - str(self.get(nodeid, prop))) + str(self.get(nodeid, prop))) # # import / export support @@ -3158,7 +3185,7 @@ specified by propnames for the given node. """ properties = self.getprops() - l = [] + return_list = [] for prop in propnames: proptype = properties[prop] value = self.get(nodeid, prop) @@ -3171,9 +3198,9 @@ value = value.get_tuple() elif isinstance(proptype, hyperdb.Password): value = str(value) - l.append(repr_export(value)) - l.append(repr_export(self.is_retired(nodeid))) - return l + return_list.append(repr_export(value)) + return_list.append(repr_export(self.is_retired(nodeid))) + return return_list def import_list(self, propnames, proplist): """ Import a node - all information including "id" is present and @@ -3193,7 +3220,7 @@ # make the new node's property map d = {} retire = 0 - if not "id" in propnames: + if "id" not in propnames: newid = self.db.newid(self.classname) else: newid = eval_import(proplist[propnames.index("id")]) @@ -3231,10 +3258,10 @@ value = us2s(value) if not isinstance(value, str): raise TypeError('new property "%(propname)s" not a ' - 'string: %(value)r'%locals()) + 'string: %(value)r' % locals()) if prop.indexme: self.db.indexer.add_text((self.classname, newid, propname), - value) + value) d[propname] = value # get a new id if necessary @@ -3246,7 +3273,7 @@ # use the arg for __retired__ to cope with any odd database type # conversion (hello, sqlite) - retired_sql = 'update _%s set __retired__=%s where id=%s'%( + retired_sql = 'update _%s set __retired__=%s where id=%s' % ( self.classname, self.db.arg, self.db.arg) # insert new node or update existing? @@ -3254,9 +3281,9 @@ try: has_node = self.hasnode(newid) if not has_node: - self.db.addnode(self.classname, newid, d) # insert + self.db.addnode(self.classname, newid, d) # insert else: - self.db.setnode(self.classname, newid, d) # update + self.db.setnode(self.classname, newid, d) # update self.db.checkpoint_data() # Blech, different db's return different exceptions # so I can't list them here as some might not be defined @@ -3266,22 +3293,22 @@ # undo the fixup and pass on the error. except Exception as e: # nosec logger.info('Attempting to handle import exception ' - 'for id %s: %s' % (newid,e)) + 'for id %s: %s' % (newid, e)) keyname = self.db.user.getkey() if has_node or not keyname: # Not an integrity error raise self.db.restore_connection_on_error() activeid = self.db.user.lookup(d[keyname]) - self.db.sql(retired_sql, (-1, activeid)) # clear the active node + self.db.sql(retired_sql, (-1, activeid)) # clear the active node # this can only happen on an addnode, so retry try: # if this raises an error, let it propagate upward - self.db.addnode(self.classname, newid, d) # insert + self.db.addnode(self.classname, newid, d) # insert except Exception: # undo the database change - self.db.sql(retired_sql, (0, activeid)) # clear the active node - raise # propagate + self.db.sql(retired_sql, (0, activeid)) # clear active node + raise # propagate logger.info('Successfully handled import exception ' 'for id %s which conflicted with %s' % ( newid, activeid)) @@ -3307,9 +3334,9 @@ properties = self.getprops() r = [] for nodeid in self.getnodeids(): - for nodeid, date, user, action, params in self.history(nodeid, - enforceperm=False, skipquiet=False): - date = date.get_tuple() + for nodeid, date_, user, action, params in self.history( + nodeid, enforceperm=False, skipquiet=False): + date_ = date_.get_tuple() if action == 'set': export_data = {} for propname, value in params.items(): @@ -3332,10 +3359,11 @@ elif action == 'create' and params: # old tracker with data stored in the create! params = {} - l = [nodeid, date, user, action, params] + l = [nodeid, date_, user, action, params] r.append(list(map(repr_export, l))) return r + class FileClass(hyperdb.FileClass, Class): """This class defines a large chunk of data. To support this, it has a mandatory String property "content" which is typically saved off @@ -3378,7 +3406,7 @@ if bytes != str and isinstance(content, bytes): index_content = content.decode('utf-8', errors='ignore') self.db.indexer.add_text((self.classname, newid, 'content'), - index_content, mime_type) + index_content, mime_type) # store off the content as a file self.db.storefile(self.classname, newid, None, bs2b(content)) @@ -3399,17 +3427,21 @@ return b2s(self.db.getfile(self.classname, nodeid, None)) except IOError as strerror: # BUG: by catching this we donot see an error in the log. - return 'ERROR reading file: %s%s\n%s\n%s'%( + return 'ERROR reading file: %s%s\n%s\n%s' % ( self.classname, nodeid, poss_msg, strerror) - except UnicodeDecodeError as e: + except UnicodeDecodeError: # if content is not text (e.g. jpeg file) we get # unicode error trying to convert to string in python 3. # trap it and supply an error message. Include md5sum # of content as this string is included in the etag # calculation of the object. return ('%s%s is not text, retrieve using ' - 'binary_content property. mdsum: %s')%(self.classname, - nodeid, md5(self.db.getfile(self.classname, nodeid, None)).hexdigest()) # nosec - bandit md5 use ok + 'binary_content property. mdsum: %s') % ( + self.classname, nodeid, + md5(self.db.getfile( + self.classname, + nodeid, + None)).hexdigest()) # nosec - bandit md5 use ok elif propname == 'binary_content': return self.db.getfile(self.classname, nodeid, None) @@ -3443,7 +3475,7 @@ if bytes != str and isinstance(content, bytes): index_content = content.decode('utf-8', errors='ignore') self.db.indexer.add_text((self.classname, itemid, 'content'), - index_content, mime_type) + index_content, mime_type) propvalues['content'] = content # fire reactors @@ -3464,7 +3496,7 @@ index_content = index_content.decode('utf-8', errors='ignore') self.db.indexer.add_text((self.classname, nodeid, 'content'), - index_content, mime_type) + index_content, mime_type) elif isinstance(propclass, hyperdb.String) and propclass.indexme: # index them under (classname, nodeid, property) try: @@ -3474,6 +3506,7 @@ continue self.db.indexer.add_text((self.classname, nodeid, prop), value) + # XXX deviation from spec - was called ItemClass class IssueClass(Class, roundupdb.IssueClass): # Overridden methods:
