0001from sqlobject.dbconnection import DBAPI
0002from sqlobject.col import popKey
0003
0004sqlite = None
0005using_sqlite2 = False
0006
0007class SQLiteConnection(DBAPI):
0008
0009 supportTransactions = True
0010 dbName = 'sqlite'
0011 schemes = [dbName]
0012
0013 def __init__(self, filename, autoCommit=1, **kw):
0014 global sqlite
0015 global using_sqlite2
0016 if sqlite is None:
0017 try:
0018 from pysqlite2 import dbapi2 as sqlite
0019 using_sqlite2 = True
0020 except ImportError:
0021 import sqlite
0022 using_sqlite2 = False
0023 self.module = sqlite
0024 self.filename = filename
0025
0026 opts = {}
0027 if using_sqlite2:
0028 if autoCommit:
0029 opts["isolation_level"] = None
0030 if 'encoding' in kw:
0031 import warnings
0032 warnings.warn(DeprecationWarning("pysqlite2 does not support the encoding option"))
0033 opts["detect_types"] = sqlite.PARSE_DECLTYPES
0034 for col_type in "text", "char", "varchar":
0035 sqlite.register_converter(col_type, stop_pysqlite2_converting_strings_to_unicode)
0036 sqlite.register_converter(col_type.upper(), stop_pysqlite2_converting_strings_to_unicode)
0037 else:
0038 opts['autocommit'] = autoCommit
0039 if 'encoding' in kw:
0040 opts['encoding'] = popKey(kw, 'encoding')
0041 if 'mode' in kw:
0042 opts['mode'] = int(popKey(kw, 'mode'), 0)
0043 if 'timeout' in kw:
0044 opts['timeout'] = float(popKey(kw, 'timeout'))
0045
0046
0047 self._conn = sqlite.connect(self.filename, **opts)
0048 DBAPI.__init__(self, **kw)
0049
0050 def connectionFromURI(cls, uri):
0051 user, password, host, port, path, args = cls._parseURI(uri)
0052 assert host is None, (
0053 "SQLite can only be used locally (with a URI like "
0054 "sqlite:///file or sqlite:/file, not %r)" % uri)
0055 assert user is None and password is None, (
0056 "You may not provide usernames or passwords for SQLite "
0057 "databases")
0058 if path == "/:memory:": path = ":memory:"
0059 return cls(filename=path, **args)
0060 connectionFromURI = classmethod(connectionFromURI)
0061
0062 def uri(self):
0063 return 'sqlite:///%s' % self.filename
0064
0065 def _setAutoCommit(self, conn, auto):
0066 if using_sqlite2:
0067 if auto:
0068 conn.isolation_level = None
0069 else:
0070 conn.isolation_level = ""
0071 else:
0072 conn.autocommit = auto
0073
0074 def _setIsolationLevel(self, conn, level):
0075 if not using_sqlite2:
0076 return
0077 conn.isolation_level = level
0078
0079 def makeConnection(self):
0080 return self._conn
0081
0082 def _queryInsertID(self, conn, soInstance, id, names, values):
0083 table = soInstance.sqlmeta.table
0084 idName = soInstance.sqlmeta.idName
0085 c = conn.cursor()
0086 if id is not None:
0087 names = [idName] + names
0088 values = [id] + values
0089 q = self._insertSQL(table, names, values)
0090 if self.debug:
0091 self.printDebug(conn, q, 'QueryIns')
0092 c.execute(q)
0093
0094 if id is None:
0095 id = int(c.lastrowid)
0096 if self.debugOutput:
0097 self.printDebug(conn, id, 'QueryIns', 'result')
0098 return id
0099
0100 def _insertSQL(self, table, names, values):
0101 if not names:
0102 assert not values
0103
0104
0105 return ("INSERT INTO %s VALUES (NULL)" % table)
0106 else:
0107 return DBAPI._insertSQL(self, table, names, values)
0108
0109 def _queryAddLimitOffset(self, query, start, end):
0110 if not start:
0111 return "%s LIMIT %i" % (query, end)
0112 if not end:
0113 return "%s LIMIT 0 OFFSET %i" % (query, start)
0114 return "%s LIMIT %i OFFSET %i" % (query, end-start, start)
0115
0116 def createColumn(self, soClass, col):
0117 return col.sqliteCreateSQL()
0118
0119 def createIDColumn(self, soClass):
0120 return '%s INTEGER PRIMARY KEY' % soClass.sqlmeta.idName
0121
0122 def joinSQLType(self, join):
0123 return 'INT NOT NULL'
0124
0125 def tableExists(self, tableName):
0126 result = self.queryOne("SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = '%s'" % tableName)
0127
0128 return not not result
0129
0130 def createIndexSQL(self, soClass, index):
0131 return index.sqliteCreateIndexSQL(soClass)
0132
0133def stop_pysqlite2_converting_strings_to_unicode(s):
0134 return s