Changed dbi.Record not to use a metaclass.

This commit is contained in:
Jeremy Fincher 2004-09-24 20:05:34 +00:00
parent ec7ba362c4
commit 5753195f45
6 changed files with 46 additions and 56 deletions

View File

@ -52,8 +52,7 @@ import supybot.privmsgs as privmsgs
import supybot.registry as registry
import supybot.callbacks as callbacks
class FunDBRecord(object):
__metaclass__ = dbi.Record
class FunDBRecord(dbi.Record):
__fields__ = [
'by',
'text',

View File

@ -48,8 +48,7 @@ import supybot.privmsgs as privmsgs
import supybot.callbacks as callbacks
class NewsRecord(object):
__metaclass__ = dbi.Record
class NewsRecord(dbi.Record):
__fields__ = [
'subject',
'text',
@ -119,6 +118,8 @@ class SqliteNewsDB(object):
subject, text, added_at, expires, by)
db.commit()
# XXX This should change only to support id, and the old functionality
# should move out to another method.
def get(self, channel, id=None, old=False):
db = self._getDb(channel)
cursor = db.cursor()

View File

@ -80,8 +80,7 @@ class Ignores(registry.SpaceSeparatedListOfStrings):
conf.registerUserValue(conf.users.plugins.Note, 'ignores', Ignores([], ''))
class NoteRecord(object):
__metaclass__ = dbi.Record
class NoteRecord(dbi.Record):
__fields__ = [
'frm',
'to',

View File

@ -67,8 +67,7 @@ conf.registerChannelValue(conf.supybot.plugins.Project, 'default',
registry.String('', """Determines what the default project for this channel
is."""))
class Record(object):
__metaclass__ = dbi.Record
class Record(dbi.Record):
__fields__ = [
'desc',
'by',

View File

@ -53,8 +53,7 @@ conf.registerGlobalValue(conf.supybot.plugins.Quotes, 'requireRegistration',
registry.Boolean(False, """Determines whether the bot should require people
trying to use this plugin to be registered."""))
class QuoteRecord(object):
__metaclass__ = dbi.Record
class QuoteRecord(dbi.Record):
__fields__ = [
'at',
'by',
@ -136,6 +135,10 @@ class SqliteQuotesDB(object):
(id, by, at, text) = cursor.fetchone()
return QuoteRecord(id, by=by, at=int(at), text=text)
# XXX This needs to be modified to accept a predicate, and the creation of
# the predicate moved to the plugin. One plugin, many database
# implementations -- we don't want to burden every database implementation
# to do all this work.
def search(self, channel, **kwargs):
criteria = []
formats = []

View File

@ -300,8 +300,13 @@ class DB(object):
yield record
def random(self):
# XXX This can be optimized not to deserialize each record.
return random.choice(self)
def size(self):
# XXX Likewise as above.
return ilen(self)
def flush(self):
self.map.flush()
@ -314,63 +319,47 @@ Mappings = {
}
class Record(type):
"""__fields should be a list of two-tuples, (name, converter) or
(name, (converter, default))."""
def __new__(cls, clsname, bases, dict):
defaults = {}
converters = {}
fields = []
for name in dict['__fields__']:
class Record(object):
def __init__(self, id=None, **kwargs):
if id is not None:
assert isinstance(id, int), 'id must be an integer.'
self.id = id
self.fields = []
self.defaults = {}
self.converters = {}
for name in self.__fields__:
if isinstance(name, tuple):
(name, spec) = name
else:
spec = utils.safeEval
assert name != 'convert' and name != 'id'
fields.append(name)
assert name != 'id'
self.fields.append(name)
if isinstance(spec, tuple):
(converter, default) = spec
else:
converter = spec
default = None
defaults[name] = default
converters[name] = converter
del dict['__fields__']
self.defaults[name] = default
self.converters[name] = converter
seen = sets.Set()
for (name, value) in kwargs.iteritems():
assert name in self.fields, 'name must be a record value.'
seen.add(name)
setattr(self, name, value)
for name in self.fields:
if name not in seen:
setattr(self, name, self.defaults[name])
def __init__(self, id=None, convert=False, **kwargs):
if id is not None:
assert isinstance(id, int), 'id must be an integer.'
self.id = id
set = sets.Set()
for (name, value) in kwargs.iteritems():
assert name in fields, 'name must be a record value.'
set.add(name)
if convert:
setattr(self, name, converters[name](value))
else:
setattr(self, name, value)
for name in fields:
if name not in set:
setattr(self, name, defaults[name])
def serialize(self):
return csv.join([repr(getattr(self, name)) for name in self.fields])
def serialize(self):
return csv.join([repr(getattr(self, name)) for name in fields])
def deserialize(self, s):
unseenRecords = sets.Set(fields)
for (name, strValue) in zip(fields, csv.split(s)):
setattr(self, name, converters[name](strValue))
unseenRecords.remove(name)
for name in unseenRecords:
setattr(self, record, defaults[record])
dict['__init__'] = __init__
dict['serialize'] = serialize
dict['deserialize'] = deserialize
return type.__new__(cls, clsname, bases, dict)
def deserialize(self, s):
unseenRecords = sets.Set(self.fields)
for (name, strValue) in zip(self.fields, csv.split(s)):
setattr(self, name, self.converters[name](strValue))
unseenRecords.remove(name)
for name in unseenRecords:
setattr(self, record, self.defaults[record])
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: