T
Tim Lesher
I'm writing a database helper class that represents records in a SQL
database as objects. I want to be able to instantiate the objects
(from the database), play with their values locally, then lazily
commit the changes all at once (via an explicit commit call). Other
than the call to Commit(), I don't want clients of this class to have
to think about the fact that there's a database behind it all--there are
some interesting and non-obvious dependencies on the particular values
that are committed together, and I want to hide that in the Commit() call.
I'm going to have a number of these, so I wanted to come up with a
solution that's short on glue code and can easily be aggregated into
all the classes that represent record types. This is what I've come
up with:
# Simple currying class, no kwargs
class curry:
def __init__(self, fun, *args):
self.fun = fun
self.pending = args[:]
def __call__(self, *args):
return self.fun(*(self.pending + args))
# Simple table: two columns, "title" and "description"
class SomeRecordType(object):
def __init__(self, title, description):
self.__modifications = {}
# Avoid triggering propset on init
self.__dict__['title'] = title
self.__dict__['description'] = description
def __getValue(name, self):
try:
return self.__modifications[name]
except KeyError:
return self.__dict__[name]
def __setValue(name, self, newValue):
self.modifications[name] = newValue
name = property(curry(__getValue, 'title'),
curry(__setValue, 'title'))
description = property(curry(__getValue, 'description'),
curry(__setValue, 'description'))
def Commit(self):
if self.modifications != {}:
# - snip - Do database commit and clear modifications
self.__dict__.update(self.modifications)
self.modifications = {}
So I can do this:
foo = myDb.LookupTitleRecord('some title')
print foo.description # 'foo'
foo.description = 'bar' # not updated in the DB yet
print foo.description # 'bar'
foo.Commit() # now updated in the DB
Are there any pitfalls to doing this? Am I being dazzled by the shiny
new toy that is currying? Is there another simple solution, or a
refinement of this one, that I'm not seeing?
Thanks.
database as objects. I want to be able to instantiate the objects
(from the database), play with their values locally, then lazily
commit the changes all at once (via an explicit commit call). Other
than the call to Commit(), I don't want clients of this class to have
to think about the fact that there's a database behind it all--there are
some interesting and non-obvious dependencies on the particular values
that are committed together, and I want to hide that in the Commit() call.
I'm going to have a number of these, so I wanted to come up with a
solution that's short on glue code and can easily be aggregated into
all the classes that represent record types. This is what I've come
up with:
# Simple currying class, no kwargs
class curry:
def __init__(self, fun, *args):
self.fun = fun
self.pending = args[:]
def __call__(self, *args):
return self.fun(*(self.pending + args))
# Simple table: two columns, "title" and "description"
class SomeRecordType(object):
def __init__(self, title, description):
self.__modifications = {}
# Avoid triggering propset on init
self.__dict__['title'] = title
self.__dict__['description'] = description
def __getValue(name, self):
try:
return self.__modifications[name]
except KeyError:
return self.__dict__[name]
def __setValue(name, self, newValue):
self.modifications[name] = newValue
name = property(curry(__getValue, 'title'),
curry(__setValue, 'title'))
description = property(curry(__getValue, 'description'),
curry(__setValue, 'description'))
def Commit(self):
if self.modifications != {}:
# - snip - Do database commit and clear modifications
self.__dict__.update(self.modifications)
self.modifications = {}
So I can do this:
foo = myDb.LookupTitleRecord('some title')
print foo.description # 'foo'
foo.description = 'bar' # not updated in the DB yet
print foo.description # 'bar'
foo.Commit() # now updated in the DB
Are there any pitfalls to doing this? Am I being dazzled by the shiny
new toy that is currying? Is there another simple solution, or a
refinement of this one, that I'm not seeing?
Thanks.