~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/enterprise/reflector.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, autoLoad in tableInfo.rowForeignKeys:
 
57
            self.schema[foreignTableName].addForeignKey(childColumns,
 
58
                                                        parentColumns, tableInfo.rowClass,
 
59
                                                        containerMethod, autoLoad)
 
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 to 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 object.
 
89
        If a rowClass does not have a containerMethod, then a list attribute "childRows"
 
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.rowTableName, 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']