sqlobject 3.13.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. sqlobject/__init__.py +15 -0
  2. sqlobject/__version__.py +8 -0
  3. sqlobject/boundattributes.py +124 -0
  4. sqlobject/cache.py +376 -0
  5. sqlobject/classregistry.py +138 -0
  6. sqlobject/col.py +2187 -0
  7. sqlobject/compat.py +59 -0
  8. sqlobject/conftest.py +64 -0
  9. sqlobject/constraints.py +77 -0
  10. sqlobject/converters.py +278 -0
  11. sqlobject/dbconnection.py +1137 -0
  12. sqlobject/dberrors.py +54 -0
  13. sqlobject/declarative.py +211 -0
  14. sqlobject/events.py +365 -0
  15. sqlobject/firebird/__init__.py +8 -0
  16. sqlobject/firebird/firebirdconnection.py +463 -0
  17. sqlobject/include/__init__.py +1 -0
  18. sqlobject/include/hashcol.py +109 -0
  19. sqlobject/include/tests/__init__.py +1 -0
  20. sqlobject/include/tests/test_hashcol.py +84 -0
  21. sqlobject/index.py +189 -0
  22. sqlobject/inheritance/__init__.py +551 -0
  23. sqlobject/inheritance/iteration.py +106 -0
  24. sqlobject/inheritance/tests/__init__.py +1 -0
  25. sqlobject/inheritance/tests/test_aggregates.py +23 -0
  26. sqlobject/inheritance/tests/test_asdict.py +48 -0
  27. sqlobject/inheritance/tests/test_deep_inheritance.py +114 -0
  28. sqlobject/inheritance/tests/test_destroy_cascade.py +23 -0
  29. sqlobject/inheritance/tests/test_foreignKey.py +94 -0
  30. sqlobject/inheritance/tests/test_indexes.py +42 -0
  31. sqlobject/inheritance/tests/test_inheritance.py +164 -0
  32. sqlobject/inheritance/tests/test_inheritance_tree.py +50 -0
  33. sqlobject/joins.py +656 -0
  34. sqlobject/main.py +1880 -0
  35. sqlobject/manager/__init__.py +1 -0
  36. sqlobject/manager/command.py +1309 -0
  37. sqlobject/maxdb/__init__.py +8 -0
  38. sqlobject/maxdb/maxdbconnection.py +320 -0
  39. sqlobject/maxdb/readme.txt +27 -0
  40. sqlobject/mssql/__init__.py +8 -0
  41. sqlobject/mssql/mssqlconnection.py +417 -0
  42. sqlobject/mysql/__init__.py +8 -0
  43. sqlobject/mysql/mysqlconnection.py +562 -0
  44. sqlobject/postgres/__init__.py +8 -0
  45. sqlobject/postgres/pgconnection.py +619 -0
  46. sqlobject/sqlbuilder.py +1655 -0
  47. sqlobject/sqlite/__init__.py +8 -0
  48. sqlobject/sqlite/sqliteconnection.py +418 -0
  49. sqlobject/sresults.py +377 -0
  50. sqlobject/styles.py +174 -0
  51. sqlobject/sybase/__init__.py +8 -0
  52. sqlobject/sybase/sybaseconnection.py +183 -0
  53. sqlobject/tests/__init__.py +1 -0
  54. sqlobject/tests/dbtest.py +363 -0
  55. sqlobject/tests/test_ForeignKey.py +133 -0
  56. sqlobject/tests/test_ForeignKey_cascade.py +150 -0
  57. sqlobject/tests/test_NoneValuedResultItem.py +33 -0
  58. sqlobject/tests/test_SQLMultipleJoin.py +65 -0
  59. sqlobject/tests/test_SQLRelatedJoin.py +114 -0
  60. sqlobject/tests/test_SingleJoin.py +30 -0
  61. sqlobject/tests/test_aggregates.py +75 -0
  62. sqlobject/tests/test_aliases.py +49 -0
  63. sqlobject/tests/test_asdict.py +18 -0
  64. sqlobject/tests/test_auto.py +218 -0
  65. sqlobject/tests/test_basic.py +359 -0
  66. sqlobject/tests/test_blob.py +34 -0
  67. sqlobject/tests/test_boundattributes.py +67 -0
  68. sqlobject/tests/test_cache.py +57 -0
  69. sqlobject/tests/test_class_hash.py +22 -0
  70. sqlobject/tests/test_columns_order.py +18 -0
  71. sqlobject/tests/test_combining_joins.py +47 -0
  72. sqlobject/tests/test_comparison.py +24 -0
  73. sqlobject/tests/test_compat.py +10 -0
  74. sqlobject/tests/test_complex_sorting.py +77 -0
  75. sqlobject/tests/test_constraints.py +43 -0
  76. sqlobject/tests/test_converters.py +276 -0
  77. sqlobject/tests/test_create_drop.py +29 -0
  78. sqlobject/tests/test_csvexport.py +101 -0
  79. sqlobject/tests/test_csvimport.py +21 -0
  80. sqlobject/tests/test_cyclic_reference.py +55 -0
  81. sqlobject/tests/test_datetime.py +171 -0
  82. sqlobject/tests/test_dbconnection.py +17 -0
  83. sqlobject/tests/test_decimal.py +63 -0
  84. sqlobject/tests/test_declarative.py +83 -0
  85. sqlobject/tests/test_default_style.py +65 -0
  86. sqlobject/tests/test_delete.py +74 -0
  87. sqlobject/tests/test_distinct.py +36 -0
  88. sqlobject/tests/test_empty.py +22 -0
  89. sqlobject/tests/test_enum.py +75 -0
  90. sqlobject/tests/test_events.py +142 -0
  91. sqlobject/tests/test_exceptions.py +40 -0
  92. sqlobject/tests/test_expire.py +29 -0
  93. sqlobject/tests/test_groupBy.py +45 -0
  94. sqlobject/tests/test_identity.py +29 -0
  95. sqlobject/tests/test_indexes.py +100 -0
  96. sqlobject/tests/test_inheritance.py +35 -0
  97. sqlobject/tests/test_joins.py +160 -0
  98. sqlobject/tests/test_joins_conditional.py +143 -0
  99. sqlobject/tests/test_jsonbcol.py +53 -0
  100. sqlobject/tests/test_jsoncol.py +56 -0
  101. sqlobject/tests/test_lazy.py +165 -0
  102. sqlobject/tests/test_md5.py +13 -0
  103. sqlobject/tests/test_mysql.py +50 -0
  104. sqlobject/tests/test_new_joins.py +165 -0
  105. sqlobject/tests/test_parse_uri.py +147 -0
  106. sqlobject/tests/test_paste.py +92 -0
  107. sqlobject/tests/test_perConnection.py +20 -0
  108. sqlobject/tests/test_pickle.py +42 -0
  109. sqlobject/tests/test_picklecol.py +44 -0
  110. sqlobject/tests/test_postgres.py +82 -0
  111. sqlobject/tests/test_reparent_sqlmeta.py +33 -0
  112. sqlobject/tests/test_schema.py +30 -0
  113. sqlobject/tests/test_select.py +218 -0
  114. sqlobject/tests/test_select_through.py +63 -0
  115. sqlobject/tests/test_setters.py +23 -0
  116. sqlobject/tests/test_slice.py +59 -0
  117. sqlobject/tests/test_sorting.py +80 -0
  118. sqlobject/tests/test_sqlbuilder.py +134 -0
  119. sqlobject/tests/test_sqlbuilder_dbspecific.py +66 -0
  120. sqlobject/tests/test_sqlbuilder_importproxy.py +55 -0
  121. sqlobject/tests/test_sqlbuilder_joins_instances.py +90 -0
  122. sqlobject/tests/test_sqlite.py +160 -0
  123. sqlobject/tests/test_sqlmeta_idName.py +52 -0
  124. sqlobject/tests/test_sqlobject_admin.py +38 -0
  125. sqlobject/tests/test_string_id.py +79 -0
  126. sqlobject/tests/test_style.py +36 -0
  127. sqlobject/tests/test_subqueries.py +142 -0
  128. sqlobject/tests/test_transactions.py +122 -0
  129. sqlobject/tests/test_unicode.py +84 -0
  130. sqlobject/tests/test_uuidcol.py +40 -0
  131. sqlobject/tests/test_validation.py +125 -0
  132. sqlobject/tests/test_views.py +159 -0
  133. sqlobject/util/__init__.py +1 -0
  134. sqlobject/util/csvexport.py +210 -0
  135. sqlobject/util/csvimport.py +366 -0
  136. sqlobject/util/moduleloader.py +35 -0
  137. sqlobject/util/threadinglocal.py +6 -0
  138. sqlobject/versioning/__init__.py +120 -0
  139. sqlobject/versioning/test/__init__.py +0 -0
  140. sqlobject/versioning/test/test_version.py +183 -0
  141. sqlobject/views.py +151 -0
  142. sqlobject/wsgi_middleware.py +109 -0
  143. sqlobject-3.13.1.data/scripts/sqlobject-admin +36 -0
  144. sqlobject-3.13.1.data/scripts/sqlobject-convertOldURI +19 -0
  145. sqlobject-3.13.1.dist-info/METADATA +177 -0
  146. sqlobject-3.13.1.dist-info/RECORD +149 -0
  147. sqlobject-3.13.1.dist-info/WHEEL +6 -0
  148. sqlobject-3.13.1.dist-info/entry_points.txt +4 -0
  149. sqlobject-3.13.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,8 @@
1
+ from sqlobject.dbconnection import registerConnection
2
+
3
+
4
+ def builder():
5
+ from . import sqliteconnection
6
+ return sqliteconnection.SQLiteConnection
7
+
8
+ registerConnection(['sqlite'], builder)
@@ -0,0 +1,418 @@
1
+ import base64
2
+ import os
3
+ try:
4
+ from _thread import get_ident
5
+ except ImportError:
6
+ from thread import get_ident
7
+ from threading import enumerate as enumerate_threads
8
+ try:
9
+ from urllib import quote
10
+ except ImportError:
11
+ from urllib.parse import quote
12
+ from sqlobject import col
13
+ from sqlobject import dberrors
14
+ from sqlobject.dbconnection import DBAPI, Boolean
15
+
16
+
17
+ sqlite2_Binary = None
18
+
19
+
20
+ class ErrorMessage(str):
21
+ def __new__(cls, e):
22
+ obj = str.__new__(cls, e.args[0])
23
+ obj.code = None
24
+ obj.module = e.__module__
25
+ obj.exception = e.__class__.__name__
26
+ return obj
27
+
28
+
29
+ class SQLiteConnection(DBAPI):
30
+
31
+ supportTransactions = True
32
+ dbName = 'sqlite'
33
+ schemes = [dbName]
34
+
35
+ def __init__(self, filename, autoCommit=1, **kw):
36
+ import sqlite3 as sqlite
37
+ sqlite.encode = base64.b64encode
38
+ sqlite.decode = base64.b64decode
39
+ self.module = sqlite
40
+ self.filename = filename # full path to sqlite-db-file
41
+ self._memory = filename == ':memory:'
42
+ # connection options
43
+ opts = {}
44
+ if autoCommit:
45
+ opts["isolation_level"] = None
46
+ global sqlite2_Binary
47
+ if sqlite2_Binary is None:
48
+ sqlite2_Binary = sqlite.Binary
49
+ sqlite.Binary = lambda s: sqlite2_Binary(sqlite.encode(s))
50
+ if 'factory' in kw:
51
+ factory = kw.pop('factory')
52
+ if isinstance(factory, str):
53
+ factory = globals()[factory]
54
+ opts['factory'] = factory(sqlite)
55
+ if 'timeout' in kw:
56
+ opts['timeout'] = float(kw.pop('timeout'))
57
+ if 'check_same_thread' in kw:
58
+ opts["check_same_thread"] = Boolean(kw.pop('check_same_thread'))
59
+ # use only one connection for sqlite - supports multiple)
60
+ # cursors per connection
61
+ self._connOptions = opts
62
+ self.use_table_info = Boolean(kw.pop("use_table_info", True))
63
+ DBAPI.__init__(self, **kw)
64
+ self._threadPool = {}
65
+ self._threadOrigination = {}
66
+ if self._memory:
67
+ self.makeMemoryConnection()
68
+
69
+ @classmethod
70
+ def _connectionFromParams(cls, user, password, host, port, path, args):
71
+ assert host is None and port is None, (
72
+ "SQLite can only be used locally (with a URI like "
73
+ "sqlite:/file or sqlite:///file, not sqlite://%s%s)" %
74
+ (host, port and ':%r' % port or ''))
75
+ assert user is None and password is None, (
76
+ "You may not provide usernames or passwords for SQLite "
77
+ "databases")
78
+ if path == "/:memory:":
79
+ path = ":memory:"
80
+ return cls(filename=path, **args)
81
+
82
+ def oldUri(self):
83
+ path = self.filename
84
+ if path == ":memory:":
85
+ path = "/:memory:"
86
+ else:
87
+ path = "//" + path
88
+ return 'sqlite:%s' % path
89
+
90
+ def uri(self):
91
+ path = self.filename
92
+ if path == ":memory:":
93
+ path = "/:memory:"
94
+ else:
95
+ if path.startswith('/'):
96
+ path = "//" + path
97
+ else:
98
+ path = "///" + path
99
+ path = quote(path)
100
+ return 'sqlite:%s' % path
101
+
102
+ def getConnection(self):
103
+ # SQLite can't share connections between threads, and so can't
104
+ # pool connections. Since we are isolating threads here, we
105
+ # don't have to worry about locking as much.
106
+ if self._memory:
107
+ conn = self.makeConnection()
108
+ self._connectionNumbers[id(conn)] = self._connectionCount
109
+ self._connectionCount += 1
110
+ return conn
111
+ self._releaseUnusedConnections()
112
+ threadid = get_ident()
113
+ if (self._pool is not None and threadid in self._threadPool):
114
+ conn = self._threadPool[threadid]
115
+ del self._threadPool[threadid]
116
+ if conn in self._pool:
117
+ self._pool.remove(conn)
118
+ else:
119
+ conn = self.makeConnection()
120
+ if self._pool is not None:
121
+ self._threadOrigination[id(conn)] = threadid
122
+ self._connectionNumbers[id(conn)] = self._connectionCount
123
+ self._connectionCount += 1
124
+ if self.debug:
125
+ s = 'ACQUIRE'
126
+ if self._pool is not None:
127
+ s += ' pool=[%s]' % ', '.join(
128
+ [str(self._connectionNumbers[id(v)]) for v in self._pool])
129
+ self.printDebug(conn, s, 'Pool')
130
+ return conn
131
+
132
+ def releaseConnection(self, conn, explicit=False):
133
+ if self._memory:
134
+ return
135
+ threadid = self._threadOrigination.get(id(conn))
136
+ DBAPI.releaseConnection(self, conn, explicit=explicit)
137
+ if (self._pool is not None and threadid
138
+ and threadid not in self._threadPool):
139
+ self._threadPool[threadid] = conn
140
+ else:
141
+ if self._pool and conn in self._pool:
142
+ self._pool.remove(conn)
143
+ if threadid:
144
+ del self._threadOrigination[id(conn)]
145
+ del self._threadPool[threadid]
146
+ conn.close()
147
+
148
+ def _setAutoCommit(self, conn, auto):
149
+ if auto:
150
+ conn.isolation_level = None
151
+ else:
152
+ conn.isolation_level = ""
153
+
154
+ def _setIsolationLevel(self, conn, level):
155
+ conn.isolation_level = level
156
+
157
+ def makeMemoryConnection(self):
158
+ self._memoryConn = self.module.connect(
159
+ self.filename, **self._connOptions)
160
+ # Convert text data from SQLite to str, not unicode -
161
+ # SQLObject converts it to unicode itself.
162
+ self._memoryConn.text_factory = str
163
+
164
+ def makeConnection(self):
165
+ if self._memory:
166
+ return self._memoryConn
167
+ conn = self.module.connect(self.filename, **self._connOptions)
168
+ conn.text_factory = str # Convert text data to str, not unicode
169
+ return conn
170
+
171
+ def _releaseUnusedConnections(self):
172
+ """Release connections from threads that're no longer active"""
173
+ thread_ids = set(t.ident for t in enumerate_threads())
174
+ tp_set = set(self._threadPool)
175
+ unused_connections = [
176
+ self._threadPool[tid] for tid in tp_set - thread_ids
177
+ ]
178
+ for unused_connection in unused_connections:
179
+ try:
180
+ self.releaseConnection(unused_connection, explicit=True)
181
+ except self.module.ProgrammingError:
182
+ pass # Ignore error in `conn.close()` from a different thread
183
+
184
+ def close(self):
185
+ DBAPI.close(self)
186
+ self._threadPool = {}
187
+ self._threadOrigination = {}
188
+ if self._memory:
189
+ self._memoryConn.close()
190
+ self.makeMemoryConnection()
191
+
192
+ def _executeRetry(self, conn, cursor, query):
193
+ if self.debug:
194
+ self.printDebug(conn, query, 'QueryR')
195
+ try:
196
+ return cursor.execute(query)
197
+ except self.module.OperationalError as e:
198
+ raise dberrors.OperationalError(ErrorMessage(e))
199
+ except self.module.IntegrityError as e:
200
+ msg = ErrorMessage(e)
201
+ if msg.startswith('column') and msg.endswith('not unique') \
202
+ or msg.startswith('UNIQUE constraint failed:'):
203
+ raise dberrors.DuplicateEntryError(msg)
204
+ else:
205
+ raise dberrors.IntegrityError(msg)
206
+ except self.module.InternalError as e:
207
+ raise dberrors.InternalError(ErrorMessage(e))
208
+ except self.module.ProgrammingError as e:
209
+ raise dberrors.ProgrammingError(ErrorMessage(e))
210
+ except self.module.DataError as e:
211
+ raise dberrors.DataError(ErrorMessage(e))
212
+ except self.module.NotSupportedError as e:
213
+ raise dberrors.NotSupportedError(ErrorMessage(e))
214
+ except self.module.DatabaseError as e:
215
+ raise dberrors.DatabaseError(ErrorMessage(e))
216
+ except self.module.InterfaceError as e:
217
+ raise dberrors.InterfaceError(ErrorMessage(e))
218
+ except self.module.Warning as e:
219
+ raise Warning(ErrorMessage(e))
220
+ except self.module.Error as e:
221
+ raise dberrors.Error(ErrorMessage(e))
222
+
223
+ def _queryInsertID(self, conn, soInstance, id, names, values):
224
+ table = soInstance.sqlmeta.table
225
+ idName = soInstance.sqlmeta.idName
226
+ c = conn.cursor()
227
+ if id is not None:
228
+ names = [idName] + names
229
+ values = [id] + values
230
+ q = self._insertSQL(table, names, values)
231
+ if self.debug:
232
+ self.printDebug(conn, q, 'QueryIns')
233
+ self._executeRetry(conn, c, q)
234
+ # lastrowid is a DB-API extension from "PEP 0249":
235
+ if id is None:
236
+ id = int(c.lastrowid)
237
+ c.close()
238
+ if self.debugOutput:
239
+ self.printDebug(conn, id, 'QueryIns', 'result')
240
+ return id
241
+
242
+ def _insertSQL(self, table, names, values):
243
+ if not names:
244
+ assert not values
245
+ # INSERT INTO table () VALUES () isn't allowed in
246
+ # SQLite (though it is in other databases)
247
+ return ("INSERT INTO %s VALUES (NULL)" % table)
248
+ else:
249
+ return DBAPI._insertSQL(self, table, names, values)
250
+
251
+ @classmethod
252
+ def _queryAddLimitOffset(cls, query, start, end):
253
+ if not start:
254
+ return "%s LIMIT %i" % (query, end)
255
+ if not end:
256
+ return "%s LIMIT 0 OFFSET %i" % (query, start)
257
+ return "%s LIMIT %i OFFSET %i" % (query, end - start, start)
258
+
259
+ def createColumn(self, soClass, col):
260
+ return col.sqliteCreateSQL()
261
+
262
+ def createReferenceConstraint(self, soClass, col):
263
+ return None
264
+
265
+ def createIDColumn(self, soClass):
266
+ return self._createIDColumn(soClass.sqlmeta)
267
+
268
+ def _createIDColumn(self, sqlmeta):
269
+ if sqlmeta.idType is str:
270
+ return '%s TEXT PRIMARY KEY' % sqlmeta.idName
271
+ if sqlmeta.idType is not int:
272
+ raise TypeError('sqlmeta.idType must be int or str, not %r'
273
+ % sqlmeta.idType)
274
+ return '%s INTEGER PRIMARY KEY AUTOINCREMENT' % sqlmeta.idName
275
+
276
+ def joinSQLType(self, join):
277
+ return 'INT NOT NULL'
278
+
279
+ def tableExists(self, tableName):
280
+ result = self.queryOne(
281
+ "SELECT tbl_name FROM sqlite_master "
282
+ "WHERE type='table' AND tbl_name = '%s'" % tableName)
283
+ # turn it into a boolean:
284
+ return not not result
285
+
286
+ def createIndexSQL(self, soClass, index):
287
+ return index.sqliteCreateIndexSQL(soClass)
288
+
289
+ def addColumn(self, tableName, column):
290
+ self.query('ALTER TABLE %s ADD COLUMN %s' %
291
+ (tableName,
292
+ column.sqliteCreateSQL()))
293
+ self.query('VACUUM')
294
+
295
+ def delColumn(self, sqlmeta, column):
296
+ self.recreateTableWithoutColumn(sqlmeta, column)
297
+
298
+ def recreateTableWithoutColumn(self, sqlmeta, column):
299
+ new_name = sqlmeta.table + '_ORIGINAL'
300
+ self.query('ALTER TABLE %s RENAME TO %s' % (sqlmeta.table, new_name))
301
+ cols = [self._createIDColumn(sqlmeta)] + \
302
+ [self.createColumn(None, col)
303
+ for col in sqlmeta.columnList if col.name != column.name]
304
+ cols = ",\n".join([" %s" % c for c in cols])
305
+ self.query('CREATE TABLE %s (\n%s\n)' % (sqlmeta.table, cols))
306
+ all_columns = ', '.join(
307
+ [sqlmeta.idName] + [col.dbName for col in sqlmeta.columnList])
308
+ self.query('INSERT INTO %s (%s) SELECT %s FROM %s' % (
309
+ sqlmeta.table, all_columns, all_columns, new_name))
310
+ self.query('DROP TABLE %s' % new_name)
311
+
312
+ def columnsFromSchema(self, tableName, soClass):
313
+ if self.use_table_info:
314
+ return self._columnsFromSchemaTableInfo(tableName, soClass)
315
+ else:
316
+ return self._columnsFromSchemaParse(tableName, soClass)
317
+
318
+ def _columnsFromSchemaTableInfo(self, tableName, soClass):
319
+ colData = self.queryAll("PRAGMA table_info(%s)" % tableName)
320
+ results = []
321
+ for index, field, t, nullAllowed, default, key in colData:
322
+ if field == soClass.sqlmeta.idName:
323
+ continue
324
+ colClass, kw = self.guessClass(t)
325
+ if default == 'NULL':
326
+ nullAllowed = True
327
+ default = None
328
+ kw['name'] = soClass.sqlmeta.style.dbColumnToPythonAttr(field)
329
+ kw['dbName'] = field
330
+ kw['notNone'] = not nullAllowed
331
+ kw['default'] = default
332
+ # @@ skip key...
333
+ # @@ skip extra...
334
+ results.append(colClass(**kw))
335
+ return results
336
+
337
+ def _columnsFromSchemaParse(self, tableName, soClass):
338
+ colData = self.queryOne(
339
+ "SELECT sql FROM sqlite_master WHERE type='table' AND name='%s'" %
340
+ tableName)
341
+ if not colData:
342
+ raise ValueError(
343
+ 'The table %s was not found in the database. Load failed.' %
344
+ tableName)
345
+ colData = colData[0].split('(', 1)[1].strip()[:-2]
346
+ while True:
347
+ start = colData.find('(')
348
+ if start == -1:
349
+ break
350
+ end = colData.find(')', start)
351
+ if end == -1:
352
+ break
353
+ colData = colData[:start] + colData[end + 1:]
354
+ results = []
355
+ for colDesc in colData.split(','):
356
+ parts = colDesc.strip().split(' ', 2)
357
+ field = parts[0].strip()
358
+ # skip comments
359
+ if field.startswith('--'):
360
+ continue
361
+ # get rid of enclosing quotes
362
+ if field[0] == field[-1] == '"':
363
+ field = field[1:-1]
364
+ if field == getattr(soClass.sqlmeta, 'idName', 'id'):
365
+ continue
366
+ colClass, kw = self.guessClass(parts[1].strip())
367
+ if len(parts) == 2:
368
+ index_info = ''
369
+ else:
370
+ index_info = parts[2].strip().upper()
371
+ kw['name'] = soClass.sqlmeta.style.dbColumnToPythonAttr(field)
372
+ kw['dbName'] = field
373
+ import re
374
+ nullble = re.search(r'(\b\S*)\sNULL', index_info)
375
+ default = re.search(
376
+ r"DEFAULT\s((?:\d[\dA-FX.]*)|(?:'[^']*')|(?:#[^#]*#))",
377
+ index_info)
378
+ kw['notNone'] = nullble and nullble.group(1) == 'NOT'
379
+ kw['default'] = default and default.group(1)
380
+ # @@ skip key...
381
+ # @@ skip extra...
382
+ results.append(colClass(**kw))
383
+ return results
384
+
385
+ def guessClass(self, t):
386
+ t = t.upper()
387
+ if t.find('INT') >= 0:
388
+ return col.IntCol, {}
389
+ elif t.find('TEXT') >= 0 or t.find('CHAR') >= 0 or t.find('CLOB') >= 0:
390
+ return col.StringCol, {'length': 2 ** 32 - 1}
391
+ elif t.find('BLOB') >= 0:
392
+ return col.BLOBCol, {"length": 2 ** 32 - 1}
393
+ elif t.find('REAL') >= 0 or t.find('FLOAT') >= 0:
394
+ return col.FloatCol, {}
395
+ elif t.find('DECIMAL') >= 0:
396
+ return col.DecimalCol, {'size': None, 'precision': None}
397
+ elif t.find('BOOL') >= 0:
398
+ return col.BoolCol, {}
399
+ else:
400
+ return col.Col, {}
401
+
402
+ def listTables(self):
403
+ return [v[0] for v in self.queryAll(
404
+ "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")]
405
+
406
+ def listDatabases(self):
407
+ # The pragma returns a list of (index, name, filename)
408
+ return [v[1] for v in self.queryAll("PRAGMA database_list")]
409
+
410
+ def createEmptyDatabase(self):
411
+ if self._memory:
412
+ return
413
+ open(self.filename, 'w').close()
414
+
415
+ def dropDatabase(self):
416
+ if self._memory:
417
+ return
418
+ os.unlink(self.filename)