1
# -*- test-case-name: twisted.test.test_reflector -*-
2
# Copyright (c) 2001-2007 Twisted Matrix Laboratories.
3
# See LICENSE for details.
9
A (R)elational (O)bject (W)rapper.
11
This is an extremely thin wrapper.
13
Maintainer: Dave Peticolas
18
from twisted.enterprise.util import DBError, NOQUOTE, getKeyColumn, dbTypeMap
23
I represent a row in a table in a relational database.
25
My class is "populated" by a Reflector object. After I am
26
populated, instances of me are able to interact with a particular
29
You should use a class derived from this class for each database
32
reflector.loadObjectsFrom() is used to create sets of
33
instance of objects of this class from database tables.
35
Once created, the "key column" attributes cannot be changed.
38
Class Attributes that users must supply::
40
rowKeyColumns # list of key columns in form: [(columnName, typeName)]
41
rowTableName # name of database table
42
rowColumns # list of the columns in the table with the correct
43
# case.this will be used to create member variables.
44
rowFactoryMethod # method to create an instance of this class.
45
# HACK: must be in a list!!! [factoryMethod] (optional)
46
rowForeignKeys # keys to other tables (optional)
49
populated = 0 # set on the class when the class is "populated" with SQL
50
dirty = 0 # set on an instance when the instance is out-of-sync with the database
56
warnings.warn("twisted.enterprise.row is deprecated since Twisted 8.0",
57
category=DeprecationWarning, stacklevel=2)
59
def assignKeyAttr(self, attrName, value):
60
"""Assign to a key attribute.
62
This cannot be done through normal means to protect changing
66
for keyColumn, type in self.rowKeyColumns:
67
if keyColumn == attrName:
70
raise DBError("%s is not a key columns." % attrName)
71
self.__dict__[attrName] = value
73
def findAttribute(self, attrName):
74
"""Find an attribute by caseless name.
76
for attr, type in self.rowColumns:
77
if attr.lower() == attrName.lower():
78
return getattr(self, attr)
79
raise DBError("Unable to find attribute %s" % attrName)
81
def __setattr__(self, name, value):
82
"""Special setattr to prevent changing of key values.
85
if getKeyColumn(self.__class__, name):
86
raise DBError("cannot assign value <%s> to key column attribute <%s> of RowObject class" % (value,name))
88
if name in self.rowColumns:
89
if value != self.__dict__.get(name,None) and not self.dirty:
92
self.__dict__[name] = value
94
def createDefaultAttributes(self):
95
"""Populate instance with default attributes.
97
This is used when creating a new instance NOT from the
100
for attr in self.rowColumns:
101
if getKeyColumn(self.__class__, attr):
103
for column, ctype, typeid in self.dbColumns:
104
if column.lower(column) == attr.lower():
105
q = dbTypeMap.get(ctype, None)
107
setattr(self, attr, 0)
109
setattr(self, attr, "")
111
def setDirty(self, flag):
112
"""Use this to set the 'dirty' flag.
114
(note: this avoids infinite recursion in __setattr__, and
115
prevents the 'dirty' flag )
117
self.__dict__["dirty"] = flag
119
def getKeyTuple(self):
121
keys.append(self.rowTableName)
122
for keyName, keyType in self.rowKeyColumns:
123
keys.append( getattr(self, keyName) )
127
__all__ = ['RowObject']