| OLD | NEW |
| (Empty) |
| 1 # -*- test-case-name: twisted.test.test_reflector -*- | |
| 2 # Copyright (c) 2001-2007 Twisted Matrix Laboratories. | |
| 3 # See LICENSE for details. | |
| 4 | |
| 5 | |
| 6 import weakref, warnings | |
| 7 | |
| 8 from twisted.enterprise.util import DBError | |
| 9 | |
| 10 class Reflector: | |
| 11 """ | |
| 12 DEPRECATED. | |
| 13 | |
| 14 Base class for enterprise reflectors. This implements row caching. | |
| 15 """ | |
| 16 populated = 0 | |
| 17 | |
| 18 def __init__(self, rowClasses): | |
| 19 """ | |
| 20 Initialize me against a database. | |
| 21 | |
| 22 @param rowClasses: a list of row class objects that describe the | |
| 23 database schema. | |
| 24 """ | |
| 25 warnings.warn("twisted.enterprise.reflector is deprecated since " | |
| 26 "Twisted 8.0", category=DeprecationWarning, stacklevel=2) | |
| 27 # does not hold references to cached rows. | |
| 28 self.rowCache = weakref.WeakValueDictionary() | |
| 29 self.rowClasses = rowClasses | |
| 30 self.schema = {} | |
| 31 self._populate() | |
| 32 | |
| 33 def __getstate__(self): | |
| 34 d = self.__dict__.copy() | |
| 35 del d['rowCache'] | |
| 36 return d | |
| 37 | |
| 38 def __setstate__(self, state): | |
| 39 self.__dict__ = state | |
| 40 self.rowCache = weakref.WeakValueDictionary() | |
| 41 self._populate() | |
| 42 | |
| 43 def _populate(self): | |
| 44 """Implement me to populate schema information for the reflector. | |
| 45 """ | |
| 46 raise DBError("not implemented") | |
| 47 | |
| 48 def populateSchemaFor(self, tableInfo): | |
| 49 """This is called once for each registered rowClass to add it | |
| 50 and its foreign key relationships for that rowClass to the | |
| 51 schema.""" | |
| 52 | |
| 53 self.schema[ tableInfo.rowTableName ] = tableInfo | |
| 54 | |
| 55 # add the foreign key to the foreign table. | |
| 56 for foreignTableName, childColumns, parentColumns, containerMethod, auto
Load in tableInfo.rowForeignKeys: | |
| 57 self.schema[foreignTableName].addForeignKey(childColumns, | |
| 58 parentColumns, tableInfo
.rowClass, | |
| 59 containerMethod, autoLoa
d) | |
| 60 | |
| 61 def getTableInfo(self, rowObject): | |
| 62 """Get a TableInfo record about a particular instance. | |
| 63 | |
| 64 This record contains various information about the instance's | |
| 65 class as registered with this reflector. | |
| 66 | |
| 67 @param rowObject: a L{RowObject} instance of a class previously | |
| 68 registered with me. | |
| 69 @raises twisted.enterprise.row.DBError: raised if this class was not | |
| 70 previously registered. | |
| 71 """ | |
| 72 try: | |
| 73 return self.schema[rowObject.rowTableName] | |
| 74 except KeyError: | |
| 75 raise DBError("class %s was not registered with %s" % ( | |
| 76 rowObject.__class__, self)) | |
| 77 | |
| 78 def buildWhereClause(self, relationship, row): | |
| 79 """util method used by reflectors. builds a where clause to link a row t
o another table. | |
| 80 """ | |
| 81 whereClause = [] | |
| 82 for i in range(0,len(relationship.childColumns)): | |
| 83 value = getattr(row, relationship.parentColumns[i][0]) | |
| 84 whereClause.append( [relationship.childColumns[i][0], EQUAL, value]
) | |
| 85 return whereClause | |
| 86 | |
| 87 def addToParent(self, parentRow, rows, tableName): | |
| 88 """util method used by reflectors. adds these rows to the parent row obj
ect. | |
| 89 If a rowClass does not have a containerMethod, then a list attribute "ch
ildRows" | |
| 90 will be used. | |
| 91 """ | |
| 92 parentInfo = self.getTableInfo(parentRow) | |
| 93 relationship = parentInfo.getRelationshipFor(tableName) | |
| 94 if not relationship: | |
| 95 raise DBError("no relationship from %s to %s" % ( parentRow.rowTable
Name, tableName) ) | |
| 96 | |
| 97 if not relationship.containerMethod: | |
| 98 if hasattr(parentRow, "childRows"): | |
| 99 for row in rows: | |
| 100 if row not in parentRow.childRows: | |
| 101 parentRow.childRows.append(row) | |
| 102 else: | |
| 103 parentRow.childRows = rows | |
| 104 return | |
| 105 | |
| 106 if not hasattr(parentRow, relationship.containerMethod): | |
| 107 raise DBError("parent row (%s) doesnt have container method <%s>!" %
(parentRow, relationship.containerMethod)) | |
| 108 | |
| 109 meth = getattr(parentRow, relationship.containerMethod) | |
| 110 for row in rows: | |
| 111 meth(row) | |
| 112 | |
| 113 ####### Row Cache ######## | |
| 114 | |
| 115 def addToCache(self, rowObject): | |
| 116 """NOTE: Should this be recursive?! requires better container knowledge.
..""" | |
| 117 self.rowCache[ rowObject.getKeyTuple() ] = rowObject | |
| 118 | |
| 119 def findInCache(self, rowClass, kw): | |
| 120 keys = [] | |
| 121 keys.append(rowClass.rowTableName) | |
| 122 for keyName, keyType in rowClass.rowKeyColumns: | |
| 123 keys.append( kw[keyName] ) | |
| 124 keyTuple = tuple(keys) | |
| 125 return self.rowCache.get(keyTuple) | |
| 126 | |
| 127 def removeFromCache(self, rowObject): | |
| 128 """NOTE: should this be recursive!??""" | |
| 129 key = rowObject.getKeyTuple() | |
| 130 if self.rowCache.has_key(key): | |
| 131 del self.rowCache[key] | |
| 132 | |
| 133 ####### Row Operations ######## | |
| 134 | |
| 135 def loadObjectsFrom(self, tableName, parent=None, data=None, | |
| 136 whereClause=[], loadChildren=1): | |
| 137 """Implement me to load objects from the database. | |
| 138 | |
| 139 @param whereClause: a list of tuples of (columnName, conditional, value) | |
| 140 so it can be parsed by all types of reflectors. eg.:: | |
| 141 whereClause = [("name", EQUALS, "fred"), ("age", GREATERTHAN, 18)] | |
| 142 """ | |
| 143 raise DBError("not implemented") | |
| 144 | |
| 145 def updateRow(self, rowObject): | |
| 146 """update this rowObject to the database. | |
| 147 """ | |
| 148 raise DBError("not implemented") | |
| 149 | |
| 150 def insertRow(self, rowObject): | |
| 151 """insert a new row for this object instance. | |
| 152 """ | |
| 153 raise DBError("not implemented") | |
| 154 | |
| 155 def deleteRow(self, rowObject): | |
| 156 """delete the row for this object from the database. | |
| 157 """ | |
| 158 raise DBError("not implemented") | |
| 159 | |
| 160 # conditionals | |
| 161 EQUAL = 0 | |
| 162 LESSTHAN = 1 | |
| 163 GREATERTHAN = 2 | |
| 164 LIKE = 3 | |
| 165 | |
| 166 | |
| 167 __all__ = ['Reflector', 'EQUAL', 'LESSTHAN', 'GREATERTHAN', 'LIKE'] | |
| OLD | NEW |