| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
""" |
|---|
| 7 |
DEPRECATED. |
|---|
| 8 |
|
|---|
| 9 |
A (R)elational (O)bject (W)rapper. |
|---|
| 10 |
|
|---|
| 11 |
This is an extremely thin wrapper. |
|---|
| 12 |
|
|---|
| 13 |
Maintainer: Dave Peticolas |
|---|
| 14 |
""" |
|---|
| 15 |
|
|---|
| 16 |
import warnings |
|---|
| 17 |
|
|---|
| 18 |
from twisted.enterprise.util import DBError, NOQUOTE, getKeyColumn, dbTypeMap |
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
class RowObject: |
|---|
| 22 |
""" |
|---|
| 23 |
I represent a row in a table in a relational database. |
|---|
| 24 |
|
|---|
| 25 |
My class is "populated" by a Reflector object. After I am |
|---|
| 26 |
populated, instances of me are able to interact with a particular |
|---|
| 27 |
database table. |
|---|
| 28 |
|
|---|
| 29 |
You should use a class derived from this class for each database |
|---|
| 30 |
table. |
|---|
| 31 |
|
|---|
| 32 |
reflector.loadObjectsFrom() is used to create sets of |
|---|
| 33 |
instance of objects of this class from database tables. |
|---|
| 34 |
|
|---|
| 35 |
Once created, the "key column" attributes cannot be changed. |
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
Class Attributes that users must supply:: |
|---|
| 39 |
|
|---|
| 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) |
|---|
| 47 |
""" |
|---|
| 48 |
|
|---|
| 49 |
populated = 0 |
|---|
| 50 |
dirty = 0 |
|---|
| 51 |
|
|---|
| 52 |
def __init__(self): |
|---|
| 53 |
""" |
|---|
| 54 |
DEPRECATED. |
|---|
| 55 |
""" |
|---|
| 56 |
warnings.warn("twisted.enterprise.row is deprecated since Twisted 8.0", |
|---|
| 57 |
category=DeprecationWarning, stacklevel=2) |
|---|
| 58 |
|
|---|
| 59 |
def assignKeyAttr(self, attrName, value): |
|---|
| 60 |
"""Assign to a key attribute. |
|---|
| 61 |
|
|---|
| 62 |
This cannot be done through normal means to protect changing |
|---|
| 63 |
keys of db objects. |
|---|
| 64 |
""" |
|---|
| 65 |
found = 0 |
|---|
| 66 |
for keyColumn, type in self.rowKeyColumns: |
|---|
| 67 |
if keyColumn == attrName: |
|---|
| 68 |
found = 1 |
|---|
| 69 |
if not found: |
|---|
| 70 |
raise DBError("%s is not a key columns." % attrName) |
|---|
| 71 |
self.__dict__[attrName] = value |
|---|
| 72 |
|
|---|
| 73 |
def findAttribute(self, attrName): |
|---|
| 74 |
"""Find an attribute by caseless name. |
|---|
| 75 |
""" |
|---|
| 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) |
|---|
| 80 |
|
|---|
| 81 |
def __setattr__(self, name, value): |
|---|
| 82 |
"""Special setattr to prevent changing of key values. |
|---|
| 83 |
""" |
|---|
| 84 |
|
|---|
| 85 |
if getKeyColumn(self.__class__, name): |
|---|
| 86 |
raise DBError("cannot assign value <%s> to key column attribute <%s> of RowObject class" % (value,name)) |
|---|
| 87 |
|
|---|
| 88 |
if name in self.rowColumns: |
|---|
| 89 |
if value != self.__dict__.get(name,None) and not self.dirty: |
|---|
| 90 |
self.setDirty(1) |
|---|
| 91 |
|
|---|
| 92 |
self.__dict__[name] = value |
|---|
| 93 |
|
|---|
| 94 |
def createDefaultAttributes(self): |
|---|
| 95 |
"""Populate instance with default attributes. |
|---|
| 96 |
|
|---|
| 97 |
This is used when creating a new instance NOT from the |
|---|
| 98 |
database. |
|---|
| 99 |
""" |
|---|
| 100 |
for attr in self.rowColumns: |
|---|
| 101 |
if getKeyColumn(self.__class__, attr): |
|---|
| 102 |
continue |
|---|
| 103 |
for column, ctype, typeid in self.dbColumns: |
|---|
| 104 |
if column.lower(column) == attr.lower(): |
|---|
| 105 |
q = dbTypeMap.get(ctype, None) |
|---|
| 106 |
if q == NOQUOTE: |
|---|
| 107 |
setattr(self, attr, 0) |
|---|
| 108 |
else: |
|---|
| 109 |
setattr(self, attr, "") |
|---|
| 110 |
|
|---|
| 111 |
def setDirty(self, flag): |
|---|
| 112 |
"""Use this to set the 'dirty' flag. |
|---|
| 113 |
|
|---|
| 114 |
(note: this avoids infinite recursion in __setattr__, and |
|---|
| 115 |
prevents the 'dirty' flag ) |
|---|
| 116 |
""" |
|---|
| 117 |
self.__dict__["dirty"] = flag |
|---|
| 118 |
|
|---|
| 119 |
def getKeyTuple(self): |
|---|
| 120 |
keys = [] |
|---|
| 121 |
keys.append(self.rowTableName) |
|---|
| 122 |
for keyName, keyType in self.rowKeyColumns: |
|---|
| 123 |
keys.append( getattr(self, keyName) ) |
|---|
| 124 |
return tuple(keys) |
|---|
| 125 |
|
|---|
| 126 |
|
|---|
| 127 |
__all__ = ['RowObject'] |
|---|