| OLD | NEW |
| (Empty) |
| 1 # -*- test-case-name: twisted.test.test_enterprise -*- | |
| 2 # Copyright (c) 2001-2008 Twisted Matrix Laboratories. | |
| 3 # See LICENSE for details. | |
| 4 | |
| 5 | |
| 6 import warnings, types | |
| 7 | |
| 8 from twisted.python.versions import Version, getVersionString | |
| 9 from twisted.python.deprecate import deprecated | |
| 10 from twisted.enterprise.adbapi import _safe | |
| 11 | |
| 12 # Common deprecation decorator used for all deprecations. | |
| 13 _deprecatedVersion = Version("Twisted", 8, 0, 0) | |
| 14 _releasedDeprecation = deprecated(_deprecatedVersion) | |
| 15 | |
| 16 warnings.warn( | |
| 17 "twisted.enterprise.util is deprecated since %s." % ( | |
| 18 getVersionString(_deprecatedVersion),), | |
| 19 category=DeprecationWarning) | |
| 20 | |
| 21 NOQUOTE = 1 | |
| 22 USEQUOTE = 2 | |
| 23 | |
| 24 dbTypeMap = { | |
| 25 "bigint": NOQUOTE, | |
| 26 "bool": USEQUOTE, | |
| 27 "boolean": USEQUOTE, | |
| 28 "bytea": USEQUOTE, | |
| 29 "date": USEQUOTE, | |
| 30 "int2": NOQUOTE, | |
| 31 "int4": NOQUOTE, | |
| 32 "int8": NOQUOTE, | |
| 33 "int": NOQUOTE, | |
| 34 "integer": NOQUOTE, | |
| 35 "float4": NOQUOTE, | |
| 36 "float8": NOQUOTE, | |
| 37 "numeric": NOQUOTE, | |
| 38 "real": NOQUOTE, | |
| 39 "smallint": NOQUOTE, | |
| 40 "char": USEQUOTE, | |
| 41 "text": USEQUOTE, | |
| 42 "time": USEQUOTE, | |
| 43 "timestamp": USEQUOTE, | |
| 44 "varchar": USEQUOTE | |
| 45 } | |
| 46 | |
| 47 class DBError(Exception): | |
| 48 pass | |
| 49 | |
| 50 | |
| 51 | |
| 52 ### Utility functions | |
| 53 | |
| 54 def getKeyColumn(rowClass, name): | |
| 55 lcname = name.lower() | |
| 56 for keyColumn, type in rowClass.rowKeyColumns: | |
| 57 if lcname == keyColumn.lower(): | |
| 58 return name | |
| 59 return None | |
| 60 getKeyColumn = _releasedDeprecation(getKeyColumn) | |
| 61 | |
| 62 | |
| 63 | |
| 64 def quote(value, typeCode, string_escaper=_safe): | |
| 65 """Add quotes for text types and no quotes for integer types. | |
| 66 NOTE: uses Postgresql type codes. | |
| 67 """ | |
| 68 q = dbTypeMap.get(typeCode, None) | |
| 69 if q is None: | |
| 70 raise DBError("Type %s not known" % typeCode) | |
| 71 if value is None: | |
| 72 return 'null' | |
| 73 if q == NOQUOTE: | |
| 74 return str(value) | |
| 75 elif q == USEQUOTE: | |
| 76 if typeCode.startswith('bool'): | |
| 77 if value: | |
| 78 value = '1' | |
| 79 else: | |
| 80 value = '0' | |
| 81 if typeCode == "bytea": | |
| 82 l = ["'"] | |
| 83 for c in value: | |
| 84 i = ord(c) | |
| 85 if i == 0: | |
| 86 l.append("\\\\000") | |
| 87 elif i == 92: | |
| 88 l.append(c * 4) | |
| 89 elif 32 <= i <= 126: | |
| 90 l.append(c) | |
| 91 else: | |
| 92 l.append("\\%03o" % i) | |
| 93 l.append("'") | |
| 94 return "".join(l) | |
| 95 if not isinstance(value, types.StringType) and \ | |
| 96 not isinstance(value, types.UnicodeType): | |
| 97 value = str(value) | |
| 98 return "'%s'" % string_escaper(value) | |
| 99 quote = _releasedDeprecation(quote) | |
| 100 | |
| 101 | |
| 102 def safe(text): | |
| 103 """ | |
| 104 Make a string safe to include in an SQL statement. | |
| 105 """ | |
| 106 return _safe(text) | |
| 107 | |
| 108 safe = _releasedDeprecation(safe) | |
| 109 | |
| 110 | |
| 111 def makeKW(rowClass, args): | |
| 112 """Utility method to construct a dictionary for the attributes | |
| 113 of an object from set of args. This also fixes the case of column names. | |
| 114 """ | |
| 115 kw = {} | |
| 116 for i in range(0,len(args)): | |
| 117 columnName = rowClass.dbColumns[i][0].lower() | |
| 118 for attr in rowClass.rowColumns: | |
| 119 if attr.lower() == columnName: | |
| 120 kw[attr] = args[i] | |
| 121 break | |
| 122 return kw | |
| 123 makeKW = _releasedDeprecation(makeKW) | |
| 124 | |
| 125 | |
| 126 def defaultFactoryMethod(rowClass, data, kw): | |
| 127 """Used by loadObjects to create rowObject instances. | |
| 128 """ | |
| 129 newObject = rowClass() | |
| 130 newObject.__dict__.update(kw) | |
| 131 return newObject | |
| 132 defaultFactoryMethod = _releasedDeprecation(defaultFactoryMethod) | |
| 133 | |
| 134 ### utility classes | |
| 135 | |
| 136 class _TableInfo: | |
| 137 """(internal) | |
| 138 | |
| 139 Info about a table/class and it's relationships. Also serves as a container
for | |
| 140 generated SQL. | |
| 141 """ | |
| 142 def __init__(self, rc): | |
| 143 self.rowClass = rc | |
| 144 self.rowTableName = rc.rowTableName | |
| 145 self.rowKeyColumns = rc.rowKeyColumns | |
| 146 self.rowColumns = rc.rowColumns | |
| 147 | |
| 148 if hasattr(rc, "rowForeignKeys"): | |
| 149 self.rowForeignKeys = rc.rowForeignKeys | |
| 150 else: | |
| 151 self.rowForeignKeys = [] | |
| 152 | |
| 153 if hasattr(rc, "rowFactoryMethod"): | |
| 154 if rc.rowFactoryMethod: | |
| 155 self.rowFactoryMethod = rc.rowFactoryMethod | |
| 156 else: | |
| 157 self.rowFactoryMethod = [defaultFactoryMethod] | |
| 158 else: | |
| 159 self.rowFactoryMethod = [defaultFactoryMethod] | |
| 160 | |
| 161 self.updateSQL = None | |
| 162 self.deleteSQL = None | |
| 163 self.insertSQL = None | |
| 164 self.relationships = [] | |
| 165 self.dbColumns = [] | |
| 166 | |
| 167 def addForeignKey(self, childColumns, parentColumns, childRowClass, containe
rMethod, autoLoad): | |
| 168 """This information is attached to the "parent" table | |
| 169 childColumns - columns of the "child" table | |
| 170 parentColumns - columns of the "parent" table, the one being joi
ned to... the "foreign" table | |
| 171 """ | |
| 172 self.relationships.append( _TableRelationship(childColumns, parentColumn
s, | |
| 173 childRowClass, containerMe
thod, autoLoad) ) | |
| 174 | |
| 175 def getRelationshipFor(self, tableName): | |
| 176 for relationship in self.relationships: | |
| 177 if relationship.childRowClass.rowTableName == tableName: | |
| 178 return relationship | |
| 179 return None | |
| 180 | |
| 181 class _TableRelationship: | |
| 182 """(Internal) | |
| 183 | |
| 184 A foreign key relationship between two tables. | |
| 185 """ | |
| 186 def __init__(self, | |
| 187 childColumns, | |
| 188 parentColumns, | |
| 189 childRowClass, | |
| 190 containerMethod, | |
| 191 autoLoad): | |
| 192 self.childColumns = childColumns | |
| 193 self.parentColumns = parentColumns | |
| 194 self.childRowClass = childRowClass | |
| 195 self.containerMethod = containerMethod | |
| 196 self.autoLoad = autoLoad | |
| 197 | |
| 198 | |
| 199 __all__ = ['NOQUOTE', 'USEQUOTE', 'dbTypeMap', 'DBError', 'getKeyColumn', | |
| 200 'safe', 'quote'] | |
| OLD | NEW |