[pypy-commit] pypy sqlite-cffi: More CFFI sqlite3 wrapper. Only a few user function tests still failing.
jerith
noreply at buildbot.pypy.org
Wed Feb 27 01:46:12 CET 2013
Author: Jeremy Thurgood <firxen at gmail.com>
Branch: sqlite-cffi
Changeset: r61832:826b3efd7edf
Date: 2013-02-27 02:45 +0200
http://bitbucket.org/pypy/pypy/changeset/826b3efd7edf/
Log: More CFFI sqlite3 wrapper. Only a few user function tests still
failing.
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -112,6 +112,8 @@
typedef ... sqlite3;
typedef ... sqlite3_stmt;
+typedef ... sqlite3_context;
+typedef ... sqlite3_value;
typedef int64_t sqlite3_int64;
typedef uint64_t sqlite3_uint64;
@@ -135,7 +137,6 @@
const char *sqlite3_column_name(sqlite3_stmt*, int N);
int sqlite3_get_autocommit(sqlite3*);
int sqlite3_reset(sqlite3_stmt *pStmt);
-int sqlite3_bind_parameter_count(sqlite3_stmt*);
int sqlite3_step(sqlite3_stmt*);
int sqlite3_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);
@@ -144,9 +145,11 @@
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
+int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
@@ -157,6 +160,75 @@
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
+const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+
+void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+int sqlite3_create_collation(
+ sqlite3*,
+ const char *zName,
+ int eTextRep,
+ void*,
+ int(*xCompare)(void*,int,const void*,int,const void*)
+);
+int sqlite3_set_authorizer(
+ sqlite3*,
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+ void *pUserData
+);
+int sqlite3_create_function(
+ sqlite3 *db,
+ const char *zFunctionName,
+ int nArg,
+ int eTextRep,
+ void *pApp,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*)
+);
+void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+
+sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+int sqlite3_bind_parameter_count(sqlite3_stmt*);
+const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+int sqlite3_total_changes(sqlite3*);
+
+int sqlite3_prepare(
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL statement, UTF-8 encoded */
+ int nByte, /* Maximum length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const char **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+
+void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+void sqlite3_result_double(sqlite3_context*, double);
+void sqlite3_result_error(sqlite3_context*, const char*, int);
+void sqlite3_result_error16(sqlite3_context*, const void*, int);
+void sqlite3_result_error_toobig(sqlite3_context*);
+void sqlite3_result_error_nomem(sqlite3_context*);
+void sqlite3_result_error_code(sqlite3_context*, int);
+void sqlite3_result_int(sqlite3_context*, int);
+void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+void sqlite3_result_null(sqlite3_context*);
+void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+void sqlite3_result_text16le(sqlite3_context*,const void*, int,void(*)(void*));
+void sqlite3_result_text16be(sqlite3_context*,const void*, int,void(*)(void*));
+void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+void sqlite3_result_zeroblob(sqlite3_context*, int n);
+
+const void *sqlite3_value_blob(sqlite3_value*);
+int sqlite3_value_bytes(sqlite3_value*);
+int sqlite3_value_bytes16(sqlite3_value*);
+double sqlite3_value_double(sqlite3_value*);
+int sqlite3_value_int(sqlite3_value*);
+sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+const unsigned char *sqlite3_value_text(sqlite3_value*);
+const void *sqlite3_value_text16(sqlite3_value*);
+const void *sqlite3_value_text16le(sqlite3_value*);
+const void *sqlite3_value_text16be(sqlite3_value*);
+int sqlite3_value_type(sqlite3_value*);
+int sqlite3_value_numeric_type(sqlite3_value*);
""")
lib = ffi.verify("""
@@ -201,7 +273,8 @@
globals()[symbol] = getattr(lib, symbol)
-# OLD CTYPES STUFF:
+_SQLITE_TRANSIENT = ffi.cast('void *', lib.SQLITE_TRANSIENT)
+
# pysqlite version information
version = "2.6.0"
@@ -213,40 +286,52 @@
# SQLite version information
sqlite_version = ffi.string(lib.sqlite3_libversion())
+
class Error(StandardError):
pass
+
class Warning(StandardError):
pass
+
class InterfaceError(Error):
pass
+
class DatabaseError(Error):
pass
+
class InternalError(DatabaseError):
pass
+
class OperationalError(DatabaseError):
pass
+
class ProgrammingError(DatabaseError):
pass
+
class IntegrityError(DatabaseError):
pass
+
class DataError(DatabaseError):
pass
+
class NotSupportedError(DatabaseError):
pass
+
def connect(database, **kwargs):
factory = kwargs.get("factory", Connection)
return factory(database, **kwargs)
+
def unicode_text_factory(x):
return unicode(x, 'utf-8')
@@ -273,15 +358,17 @@
class Connection(object):
- def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="",
- check_same_thread=True, factory=None, cached_statements=100):
- #import pdb; pdb.set_trace()
+ def __init__(self, database, timeout=5.0, detect_types=0,
+ isolation_level="", check_same_thread=True, factory=None,
+ cached_statements=100):
db_star = ffi.new('sqlite3 **')
+ if isinstance(database, unicode):
+ database = database.encode("utf-8")
if lib.sqlite3_open(database, db_star) != lib.SQLITE_OK:
raise OperationalError("Could not open database")
self.db = db_star[0]
if timeout is not None:
- timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds
+ timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds
lib.sqlite3_busy_timeout(self.db, timeout)
self.text_factory = unicode_text_factory
@@ -324,9 +411,12 @@
exc = InternalError
elif error_code == lib.SQLITE_NOMEM:
exc = MemoryError
- elif error_code in (lib.SQLITE_ERROR, lib.SQLITE_PERM, lib.SQLITE_ABORT, lib.SQLITE_BUSY, lib.SQLITE_LOCKED,
- lib.SQLITE_READONLY, lib.SQLITE_INTERRUPT, lib.SQLITE_IOERR, lib.SQLITE_FULL, lib.SQLITE_CANTOPEN,
- lib.SQLITE_PROTOCOL, lib.SQLITE_EMPTY, lib.SQLITE_SCHEMA):
+ elif error_code in (
+ lib.SQLITE_ERROR, lib.SQLITE_PERM, lib.SQLITE_ABORT,
+ lib.SQLITE_BUSY, lib.SQLITE_LOCKED, lib.SQLITE_READONLY,
+ lib.SQLITE_INTERRUPT, lib.SQLITE_IOERR, lib.SQLITE_FULL,
+ lib.SQLITE_CANTOPEN, lib.SQLITE_PROTOCOL, lib.SQLITE_EMPTY,
+ lib.SQLITE_SCHEMA):
exc = OperationalError
elif error_code == lib.SQLITE_CORRUPT:
exc = DatabaseError
@@ -347,16 +437,17 @@
self.statement_counter += 1
if self.statement_counter % 100 == 0:
- self.statements = [ref for ref in self.statements if ref() is not None]
+ self.statements = [ref for ref in self.statements
+ if ref() is not None]
def _check_thread(self):
if not hasattr(self, 'thread_ident'):
return
if self.thread_ident != thread_get_ident():
raise ProgrammingError(
- "SQLite objects created in a thread can only be used in that same thread."
- "The object was created in thread id %d and this is thread id %d",
- self.thread_ident, thread_get_ident())
+ "SQLite objects created in a thread can only be used in that "
+ "same thread. The object was created in thread id %d and this "
+ "is thread id %d", self.thread_ident, thread_get_ident())
def _reset_cursors(self):
for cursor_ref in self.cursors:
@@ -404,6 +495,7 @@
def _get_isolation_level(self):
return self._isolation_level
+
def _set_isolation_level(self, val):
if val is None:
self.commit()
@@ -445,7 +537,8 @@
sql = "COMMIT"
statement_star = ffi.new('sqlite3_stmt **')
next_char = ffi.new('char **')
- ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, next_char)
+ ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star,
+ next_char)
try:
if ret != lib.SQLITE_OK:
raise self._get_exception(ret)
@@ -466,18 +559,19 @@
if obj is not None:
obj.reset()
+ sql = "ROLLBACK"
+ statement_star = ffi.new('sqlite3_stmt **')
+ next_char = ffi.new('char **')
+ ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star,
+ next_char)
try:
- sql = "ROLLBACK"
- statement = c_void_p()
- next_char = c_char_p()
- ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char)
if ret != lib.SQLITE_OK:
raise self._get_exception(ret)
- ret = lib.sqlite3_step(statement)
+ ret = lib.sqlite3_step(statement_star[0])
if ret != lib.SQLITE_DONE:
raise self._get_exception(ret)
finally:
- lib.sqlite3_finalize(statement)
+ lib.sqlite3_finalize(statement_star[0])
self._reset_cursors()
def _check_closed(self):
@@ -494,7 +588,7 @@
self.rollback()
def _get_total_changes(self):
- return sqlite.sqlite3_total_changes(self.db)
+ return lib.sqlite3_total_changes(self.db)
total_changes = property(_get_total_changes)
def close(self):
@@ -521,25 +615,22 @@
if callback is None:
del self._collations[name]
- c_collation_callback = cast(None, COLLATION)
+ collation_callback = ffi.NULL
else:
if not callable(callback):
raise TypeError("parameter must be callable")
+ @ffi.callback("int(void*, int, const void*, int, const void*)")
def collation_callback(context, len1, str1, len2, str2):
- text1 = string_at(str1, len1)
- text2 = string_at(str2, len2)
+ text1 = ffi.buffer(str1, len1)[:]
+ text2 = ffi.buffer(str2, len2)[:]
return callback(text1, text2)
- c_collation_callback = COLLATION(collation_callback)
- self._collations[name] = c_collation_callback
+ self._collations[name] = collation_callback
-
- ret = sqlite.sqlite3_create_collation(self.db, name,
- lib.SQLITE_UTF8,
- None,
- c_collation_callback)
+ ret = lib.sqlite3_create_collation(self.db, name, lib.SQLITE_UTF8,
+ ffi.NULL, collation_callback)
if ret != lib.SQLITE_OK:
raise self._get_exception(ret)
@@ -547,11 +638,12 @@
self._check_thread()
self._check_closed()
if callable is None:
- c_progress_handler = cast(None, PROGRESS)
+ progress_handler = ffi.NULL
else:
try:
- c_progress_handler, _ = self.func_cache[callable]
+ progress_handler = self.func_cache[callable]
except KeyError:
+ @ffi.callback("int(void*)")
def progress_handler(userdata):
try:
ret = callable()
@@ -559,34 +651,28 @@
except Exception:
# abort query if error occurred
return 1
- c_progress_handler = PROGRESS(progress_handler)
- self.func_cache[callable] = c_progress_handler, progress_handler
- ret = sqlite.sqlite3_progress_handler(self.db, nsteps,
- c_progress_handler,
- None)
- if ret != lib.SQLITE_OK:
- raise self._get_exception(ret)
+ self.func_cache[callable] = progress_handler
+ lib.sqlite3_progress_handler(self.db, nsteps, progress_handler,
+ ffi.NULL)
def set_authorizer(self, callback):
self._check_thread()
self._check_closed()
try:
- c_authorizer, _ = self.func_cache[callback]
+ authorizer = self.func_cache[callback]
except KeyError:
+ @ffi.callback("int(void*, int, const char*, const char*, "
+ "const char*, const char*)")
def authorizer(userdata, action, arg1, arg2, dbname, source):
try:
return int(callback(action, arg1, arg2, dbname, source))
except Exception:
return lib.SQLITE_DENY
- c_authorizer = AUTHORIZER(authorizer)
+ self.func_cache[callback] = authorizer
- self.func_cache[callback] = c_authorizer, authorizer
-
- ret = sqlite.sqlite3_set_authorizer(self.db,
- c_authorizer,
- None)
+ ret = lib.sqlite3_set_authorizer(self.db, authorizer, ffi.NULL)
if ret != lib.SQLITE_OK:
raise self._get_exception(ret)
@@ -594,17 +680,15 @@
self._check_thread()
self._check_closed()
try:
- c_closure, _ = self.func_cache[callback]
+ closure = self.func_cache[callback]
except KeyError:
+ @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)")
def closure(context, nargs, c_params):
function_callback(callback, context, nargs, c_params)
- c_closure = FUNC(closure)
- self.func_cache[callback] = c_closure, closure
- ret = sqlite.sqlite3_create_function(self.db, name, num_args,
- lib.SQLITE_UTF8, None,
- c_closure,
- cast(None, STEP),
- cast(None, FINAL))
+ self.func_cache[callback] = closure
+ ret = lib.sqlite3_create_function(self.db, name, num_args,
+ lib.SQLITE_UTF8, ffi.NULL,
+ closure, ffi.NULL, ffi.NULL)
if ret != lib.SQLITE_OK:
raise self.OperationalError("Error creating function")
@@ -613,14 +697,13 @@
self._check_closed()
try:
- c_step_callback, c_final_callback, _, _ = self._aggregates[cls]
+ step_callback, final_callback = self._aggregates[cls]
except KeyError:
+ @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)")
def step_callback(context, argc, c_params):
-
- aggregate_ptr = cast(
- sqlite.sqlite3_aggregate_context(
- context, sizeof(c_ssize_t)),
- POINTER(c_ssize_t))
+ res = lib.sqlite3_aggregate_context(context,
+ ffi.sizeof("size_t"))
+ aggregate_ptr = ffi.cast("size_t *", res)
if not aggregate_ptr[0]:
try:
@@ -628,7 +711,7 @@
except Exception:
msg = ("user-defined aggregate's '__init__' "
"method raised error")
- sqlite.sqlite3_result_error(context, msg, len(msg))
+ lib.sqlite3_result_error(context, msg, len(msg))
return
aggregate_id = id(aggregate)
self.aggregate_instances[aggregate_id] = aggregate
@@ -642,14 +725,13 @@
except Exception:
msg = ("user-defined aggregate's 'step' "
"method raised error")
- sqlite.sqlite3_result_error(context, msg, len(msg))
+ lib.sqlite3_result_error(context, msg, len(msg))
+ @ffi.callback("void(sqlite3_context*)")
def final_callback(context):
-
- aggregate_ptr = cast(
- sqlite.sqlite3_aggregate_context(
- context, sizeof(c_ssize_t)),
- POINTER(c_ssize_t))
+ res = lib.sqlite3_aggregate_context(context,
+ ffi.sizeof("size_t"))
+ aggregate_ptr = ffi.cast("size_t", res)
if aggregate_ptr[0]:
aggregate = self.aggregate_instances[aggregate_ptr[0]]
@@ -658,23 +740,17 @@
except Exception:
msg = ("user-defined aggregate's 'finalize' "
"method raised error")
- sqlite.sqlite3_result_error(context, msg, len(msg))
+ lib.sqlite3_result_error(context, msg, len(msg))
else:
_convert_result(context, val)
finally:
del self.aggregate_instances[aggregate_ptr[0]]
- c_step_callback = STEP(step_callback)
- c_final_callback = FINAL(final_callback)
+ self._aggregates[cls] = step_callback, final_callback
- self._aggregates[cls] = (c_step_callback, c_final_callback,
- step_callback, final_callback)
-
- ret = sqlite.sqlite3_create_function(self.db, name, num_args,
- lib.SQLITE_UTF8, None,
- cast(None, FUNC),
- c_step_callback,
- c_final_callback)
+ ret = lib.sqlite3_create_function(self.db, name, num_args,
+ lib.SQLITE_UTF8, ffi.NULL, ffi.NULL,
+ step_callback, final_callback)
if ret != lib.SQLITE_OK:
raise self._get_exception(ret)
@@ -682,17 +758,19 @@
from sqlite3.dump import _iterdump
return _iterdump(self)
- if False and HAS_LOAD_EXTENSION:
+ if False and lib.HAS_LOAD_EXTENSION:
def enable_load_extension(self, enabled):
self._check_thread()
self._check_closed()
- rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled))
+ rc = lib.sqlite3_enable_load_extension(self.db, int(enabled))
if rc != lib.SQLITE_OK:
raise OperationalError("Error enabling load extension")
+
DML, DQL, DDL = range(3)
+
class CursorLock(object):
def __init__(self, cursor):
self.cursor = cursor
@@ -785,7 +863,8 @@
if self.statement.kind == DML:
self.connection._begin()
else:
- raise ProgrammingError("executemany is only for DML statements")
+ raise ProgrammingError(
+ "executemany is only for DML statements")
self.rowcount = 0
for params in many_params:
@@ -803,33 +882,35 @@
if type(sql) is unicode:
sql = sql.encode("utf-8")
self._check_closed()
- statement = c_void_p()
- c_sql = c_char_p(sql)
+ statement_star = ffi.new('sqlite3_stmt **')
+ tail = ffi.new('char **')
self.connection.commit()
while True:
- rc = sqlite.sqlite3_prepare(self.connection.db, c_sql, -1, byref(statement), byref(c_sql))
+ rc = lib.sqlite3_prepare(self.connection.db, sql, -1,
+ statement_star, tail)
+ sql = ffi.string(tail[0])
if rc != lib.SQLITE_OK:
raise self.connection._get_exception(rc)
rc = lib.SQLITE_ROW
while rc == lib.SQLITE_ROW:
- if not statement:
+ if not statement_star[0]:
rc = lib.SQLITE_OK
else:
- rc = lib.sqlite3_step(statement)
+ rc = lib.sqlite3_step(statement_star[0])
if rc != lib.SQLITE_DONE:
- lib.sqlite3_finalize(statement)
+ lib.sqlite3_finalize(statement_star[0])
if rc == lib.SQLITE_OK:
return self
else:
raise self.connection._get_exception(rc)
- rc = lib.sqlite3_finalize(statement)
+ rc = lib.sqlite3_finalize(statement_star[0])
if rc != lib.SQLITE_OK:
raise self.connection._get_exception(rc)
- if not c_sql.value:
+ if not sql:
break
return self
@@ -838,9 +919,9 @@
def _check_reset(self):
if self.reset:
- raise self.connection.InterfaceError("Cursor needed to be reset because "
- "of commit/rollback and can "
- "no longer be fetched from.")
+ raise self.connection.InterfaceError(
+ "Cursor needed to be reset because of commit/rollback and can "
+ "no longer be fetched from.")
# do all statements
def fetchone(self):
@@ -882,7 +963,7 @@
return self._description
def _getlastrowid(self):
- return sqlite.sqlite3_last_insert_rowid(self.connection.db)
+ return lib.sqlite3_last_insert_rowid(self.connection.db)
def close(self):
if not self.connection:
@@ -896,20 +977,21 @@
def setinputsizes(self, *args):
pass
+
def setoutputsize(self, *args):
pass
-
description = property(_getdescription)
lastrowid = property(_getlastrowid)
+
class Statement(object):
def __init__(self, connection, sql):
self.statement = None
if not isinstance(sql, str):
raise ValueError("sql must be a string")
self.con = connection
- self.sql = sql # DEBUG ONLY
+ self.sql = sql # DEBUG ONLY
first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper()
if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"):
self.kind = DML
@@ -929,7 +1011,7 @@
statement_star, next_char)
self.statement = statement_star[0]
if ret == lib.SQLITE_OK and not self.statement:
- # an empty statement, we work around that, as it's the least trouble
+ # an empty statement, we work around that as it's the least trouble
ret = lib.sqlite3_prepare_v2(self.con.db, "select 42", -1,
statement_star, next_char)
self.statement = statement_star[0]
@@ -954,8 +1036,9 @@
converter = None
if self.con.detect_types & PARSE_COLNAMES:
- colname = sqlite.sqlite3_column_name(self.statement, i)
- if colname is not None:
+ colname = lib.sqlite3_column_name(self.statement, i)
+ if colname != ffi.NULL:
+ colname = ffi.string(colname)
type_start = -1
key = None
for pos in range(len(colname)):
@@ -966,9 +1049,11 @@
converter = converters[key.upper()]
if converter is None and self.con.detect_types & PARSE_DECLTYPES:
- decltype = sqlite.sqlite3_column_decltype(self.statement, i)
- if decltype is not None:
- decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER"
+ decltype = lib.sqlite3_column_decltype(self.statement, i)
+ if decltype is not ffi.NULL:
+ # if multiple words, use first,
+ # eg. "INTEGER NOT NULL" => "INTEGER"
+ decltype = ffi.string(decltype).split()[0]
if '(' in decltype:
decltype = decltype[:decltype.index('(')]
converter = converters.get(decltype.upper(), None)
@@ -976,7 +1061,8 @@
self.row_cast_map.append(converter)
def _check_decodable(self, param):
- if self.con.text_factory in (unicode, OptimizedUnicode, unicode_text_factory):
+ if self.con.text_factory in (unicode, OptimizedUnicode,
+ unicode_text_factory):
for c in param:
if ord(c) & 0x80 != 0:
raise self.con.ProgrammingError(
@@ -994,25 +1080,28 @@
param = adapt(param)
if param is None:
- sqlite.sqlite3_bind_null(self.statement, idx)
+ lib.sqlite3_bind_null(self.statement, idx)
elif type(param) in (bool, int, long):
if -2147483648 <= param <= 2147483647:
- sqlite.sqlite3_bind_int(self.statement, idx, param)
+ lib.sqlite3_bind_int(self.statement, idx, param)
else:
- sqlite.sqlite3_bind_int64(self.statement, idx, param)
+ lib.sqlite3_bind_int64(self.statement, idx, param)
elif type(param) is float:
- sqlite.sqlite3_bind_double(self.statement, idx, param)
+ lib.sqlite3_bind_double(self.statement, idx, param)
elif isinstance(param, str):
self._check_decodable(param)
lib.sqlite3_bind_text(self.statement, idx, param, len(param),
- ffi.cast('void *', lib.SQLITE_TRANSIENT))
+ _SQLITE_TRANSIENT)
elif isinstance(param, unicode):
param = param.encode("utf-8")
- lib.sqlite3_bind_text(self.statement, idx, param, len(param), lib.SQLITE_TRANSIENT)
+ lib.sqlite3_bind_text(self.statement, idx, param, len(param),
+ _SQLITE_TRANSIENT)
elif type(param) is buffer:
- sqlite.sqlite3_bind_blob(self.statement, idx, str(param), len(param), lib.SQLITE_TRANSIENT)
+ lib.sqlite3_bind_blob(self.statement, idx, str(param), len(param),
+ _SQLITE_TRANSIENT)
else:
- raise InterfaceError("parameter type %s is not supported" % str(type(param)))
+ raise InterfaceError(
+ "parameter type %s is not supported" % str(type(param)))
def set_params(self, params):
ret = lib.sqlite3_reset(self.statement)
@@ -1036,17 +1125,19 @@
raise ProgrammingError("wrong number of arguments")
for i in range(len(params)):
- self.set_param(i+1, params[i])
+ self.set_param(i + 1, params[i])
else:
- for idx in range(1, lib.sqlite3_bind_parameter_count(self.statement) + 1):
- param_name = sqlite.sqlite3_bind_parameter_name(self.statement, idx)
- if param_name is None:
+ param_count = lib.sqlite3_bind_parameter_count(self.statement)
+ for idx in range(1, param_count + 1):
+ param_name = lib.sqlite3_bind_parameter_name(self.statement,
+ idx)
+ if param_name == ffi.NULL:
raise ProgrammingError("need named parameters")
- param_name = param_name[1:]
+ param_name = ffi.string(param_name)[1:]
try:
param = params[param_name]
except KeyError:
- raise ProgrammingError("missing parameter '%s'" %param)
+ raise ProgrammingError("missing parameter '%s'" % param)
self.set_param(idx, param)
def next(self, cursor):
@@ -1078,14 +1169,14 @@
if converter is None:
if typ == lib.SQLITE_INTEGER:
val = lib.sqlite3_column_int64(self.statement, i)
- if -sys.maxint-1 <= val <= sys.maxint:
+ if -sys.maxint - 1 <= val <= sys.maxint:
val = int(val)
elif typ == lib.SQLITE_FLOAT:
val = lib.sqlite3_column_double(self.statement, i)
elif typ == lib.SQLITE_BLOB:
blob_len = lib.sqlite3_column_bytes(self.statement, i)
blob = lib.sqlite3_column_blob(self.statement, i)
- val = ffi.buffer(blob, blob_len)[:]
+ val = buffer(ffi.buffer(blob, blob_len))
elif typ == lib.SQLITE_NULL:
val = None
elif typ == lib.SQLITE_TEXT:
@@ -1132,10 +1223,12 @@
return None
desc = []
for i in xrange(lib.sqlite3_column_count(self.statement)):
- name = lib.sqlite3_column_name(self.statement, i).split("[")[0].strip()
+ name = lib.sqlite3_column_name(self.statement, i)
+ name = ffi.string(name).split("[")[0].strip()
desc.append((name, None, None, None, None, None, None))
return desc
+
class Row(object):
def __init__(self, cursor, values):
self.description = cursor.description
@@ -1169,6 +1262,7 @@
def __hash__(self):
return hash(tuple(self.description)) ^ hash(tuple(self.values))
+
def _check_remaining_sql(s):
state = "NORMAL"
for char in s:
@@ -1211,24 +1305,25 @@
return 1
return 0
+
def _convert_params(con, nargs, params):
- _params = []
+ _params = []
for i in range(nargs):
- typ = sqlite.sqlite3_value_type(params[i])
+ typ = lib.sqlite3_value_type(params[i])
if typ == lib.SQLITE_INTEGER:
- val = sqlite.sqlite3_value_int64(params[i])
- if -sys.maxint-1 <= val <= sys.maxint:
+ val = lib.sqlite3_value_int64(params[i])
+ if -sys.maxint - 1 <= val <= sys.maxint:
val = int(val)
elif typ == lib.SQLITE_FLOAT:
- val = sqlite.sqlite3_value_double(params[i])
+ val = lib.sqlite3_value_double(params[i])
elif typ == lib.SQLITE_BLOB:
- blob_len = sqlite.sqlite3_value_bytes(params[i])
- blob = sqlite.sqlite3_value_blob(params[i])
- val = buffer(string_at(blob, blob_len))
+ blob_len = lib.sqlite3_value_bytes(params[i])
+ blob = lib.sqlite3_value_blob(params[i])
+ val = ffi.buffer(blob, blob_len)[:]
elif typ == lib.SQLITE_NULL:
val = None
elif typ == lib.SQLITE_TEXT:
- val = sqlite.sqlite3_value_text(params[i])
+ val = lib.sqlite3_value_text(params[i])
# XXX changed from con.text_factory
val = unicode(val, 'utf-8')
else:
@@ -1236,67 +1331,53 @@
_params.append(val)
return _params
+
def _convert_result(con, val):
if val is None:
- sqlite.sqlite3_result_null(con)
+ lib.sqlite3_result_null(con)
elif isinstance(val, (bool, int, long)):
- sqlite.sqlite3_result_int64(con, int(val))
+ lib.sqlite3_result_int64(con, int(val))
elif isinstance(val, str):
# XXX ignoring unicode issue
- sqlite.sqlite3_result_text(con, val, len(val), lib.SQLITE_TRANSIENT)
+ lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
elif isinstance(val, unicode):
val = val.encode('utf-8')
- sqlite.sqlite3_result_text(con, val, len(val), lib.SQLITE_TRANSIENT)
+ lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
elif isinstance(val, float):
- sqlite.sqlite3_result_double(con, val)
+ lib.sqlite3_result_double(con, val)
elif isinstance(val, buffer):
- sqlite.sqlite3_result_blob(con, str(val), len(val), lib.SQLITE_TRANSIENT)
+ lib.sqlite3_result_blob(con, str(val), len(val), _SQLITE_TRANSIENT)
else:
raise NotImplementedError
+
def function_callback(real_cb, context, nargs, c_params):
params = _convert_params(context, nargs, c_params)
try:
val = real_cb(*params)
except Exception:
msg = "user-defined function raised exception"
- sqlite.sqlite3_result_error(context, msg, len(msg))
+ lib.sqlite3_result_error(context, msg, len(msg))
else:
_convert_result(context, val)
-#FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p))
-#STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p))
-#FINAL = CFUNCTYPE(None, c_void_p)
-#sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, FUNC, STEP, FINAL]
-#sqlite.sqlite3_create_function.restype = c_int
-#
-#sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int]
-#sqlite.sqlite3_aggregate_context.restype = c_void_p
-#
-#COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p)
-#sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, COLLATION]
-#sqlite.sqlite3_create_collation.restype = c_int
-#
-#PROGRESS = CFUNCTYPE(c_int, c_void_p)
-#sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, PROGRESS, c_void_p]
-#sqlite.sqlite3_progress_handler.restype = c_int
-#
-#AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p)
-#sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, AUTHORIZER, c_void_p]
-#sqlite.sqlite3_set_authorizer.restype = c_int
converters = {}
adapters = {}
+
class PrepareProtocol(object):
pass
+
def register_adapter(typ, callable):
adapters[typ, PrepareProtocol] = callable
+
def register_converter(name, callable):
converters[name.upper()] = callable
+
def register_adapters_and_converters():
def adapt_date(val):
return val.isoformat()
@@ -1317,15 +1398,16 @@
else:
microseconds = 0
- val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
+ val = datetime.datetime(year, month, day, hours, minutes, seconds,
+ microseconds)
return val
-
register_adapter(datetime.date, adapt_date)
register_adapter(datetime.datetime, adapt_datetime)
register_converter("date", convert_date)
register_converter("timestamp", convert_timestamp)
+
def adapt(val, proto=PrepareProtocol):
# look for an adapter in the registry
adapter = adapters.get((type(val), proto), None)
@@ -1356,6 +1438,7 @@
register_adapters_and_converters()
+
def OptimizedUnicode(s):
try:
val = unicode(s, "ascii").encode("ascii")
More information about the pypy-commit
mailing list