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.registry as registry
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
class FunDBRecord(object): class FunDBRecord(dbi.Record):
__metaclass__ = dbi.Record
__fields__ = [ __fields__ = [
'by', 'by',
'text', 'text',

View File

@ -48,8 +48,7 @@ import supybot.privmsgs as privmsgs
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
class NewsRecord(object): class NewsRecord(dbi.Record):
__metaclass__ = dbi.Record
__fields__ = [ __fields__ = [
'subject', 'subject',
'text', 'text',
@ -119,6 +118,8 @@ class SqliteNewsDB(object):
subject, text, added_at, expires, by) subject, text, added_at, expires, by)
db.commit() 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): def get(self, channel, id=None, old=False):
db = self._getDb(channel) db = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()

View File

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

View File

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

View File

@ -53,8 +53,7 @@ conf.registerGlobalValue(conf.supybot.plugins.Quotes, 'requireRegistration',
registry.Boolean(False, """Determines whether the bot should require people registry.Boolean(False, """Determines whether the bot should require people
trying to use this plugin to be registered.""")) trying to use this plugin to be registered."""))
class QuoteRecord(object): class QuoteRecord(dbi.Record):
__metaclass__ = dbi.Record
__fields__ = [ __fields__ = [
'at', 'at',
'by', 'by',
@ -136,6 +135,10 @@ class SqliteQuotesDB(object):
(id, by, at, text) = cursor.fetchone() (id, by, at, text) = cursor.fetchone()
return QuoteRecord(id, by=by, at=int(at), text=text) 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): def search(self, channel, **kwargs):
criteria = [] criteria = []
formats = [] formats = []

View File

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