[pypy-commit] pypy sqlite-cffi: port some sqlite fixes/cleanups from default
bdkearns
noreply at buildbot.pypy.org
Fri Mar 8 02:18:42 CET 2013
Author: Brian Kearns <bdkearns at gmail.com>
Branch: sqlite-cffi
Changeset: r62198:b37a4cb55f8a
Date: 2013-03-07 19:54 -0500
http://bitbucket.org/pypy/pypy/changeset/b37a4cb55f8a/
Log: port some sqlite fixes/cleanups from default
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -24,10 +24,22 @@
# Note: This software has been modified for use in PyPy.
from collections import OrderedDict
+from functools import wraps
import datetime
+import string
import sys
import weakref
-from threading import _get_ident as thread_get_ident
+from threading import _get_ident as _thread_get_ident
+
+if sys.version_info[0] >= 3:
+ StandardError = Exception
+ long = int
+ xrange = range
+ basestring = unicode = str
+ buffer = memoryview
+ _BLOB_TYPE = bytes
+else:
+ _BLOB_TYPE = buffer
from cffi import FFI
@@ -346,11 +358,21 @@
return factory(database, **kwargs)
-def unicode_text_factory(x):
+def _unicode_text_factory(x):
return unicode(x, 'utf-8')
+if sys.version_info[0] < 3:
+ def OptimizedUnicode(s):
+ try:
+ val = unicode(s, "ascii").encode("ascii")
+ except UnicodeDecodeError:
+ val = unicode(s, "utf-8")
+ return val
+else:
+ OptimizedUnicode = _unicode_text_factory
-class StatementCache(object):
+
+class _StatementCache(object):
def __init__(self, connection, maxcount):
self.connection = connection
self.maxcount = maxcount
@@ -364,7 +386,7 @@
self.cache[sql] = stat
if len(self.cache) > self.maxcount:
self.cache.popitem(0)
- #
+
if stat.in_use:
stat = Statement(self.connection, sql)
stat.set_row_factory(row_factory)
@@ -377,7 +399,7 @@
cached_statements=100):
db_star = ffi.new('sqlite3 **')
if isinstance(database, unicode):
- database = database.encode("utf-8")
+ 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]
@@ -385,14 +407,14 @@
timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds
lib.sqlite3_busy_timeout(self.db, timeout)
- self.text_factory = unicode_text_factory
+ self.text_factory = _unicode_text_factory
self.closed = False
self.statements = []
self.statement_counter = 0
self.row_factory = None
self._isolation_level = isolation_level
self.detect_types = detect_types
- self.statement_cache = StatementCache(self, cached_statements)
+ self.statement_cache = _StatementCache(self, cached_statements)
self.cursors = []
@@ -412,7 +434,49 @@
self.aggregate_instances = {}
self._collations = {}
if check_same_thread:
- self.thread_ident = thread_get_ident()
+ self.thread_ident = _thread_get_ident()
+
+ def close(self):
+ self._check_thread()
+ if self.closed:
+ return
+ for statement in self.statements:
+ obj = statement()
+ if obj is not None:
+ obj.finalize()
+
+ self.closed = True
+ ret = lib.sqlite3_close(self.db)
+ self._reset_cursors()
+ if ret != lib.SQLITE_OK:
+ raise self._get_exception(ret)
+
+ def _check_closed(self):
+ if getattr(self, 'closed', True):
+ raise ProgrammingError("Cannot operate on a closed database.")
+
+ def _check_closed_wrap(func):
+ @wraps(func)
+ def wrapper(self, *args, **kwargs):
+ self._check_closed()
+ return func(self, *args, **kwargs)
+ return wrapper
+
+ 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())
+
+ def _check_thread_wrap(func):
+ @wraps(func)
+ def wrapper(self, *args, **kwargs):
+ self._check_thread()
+ return func(self, *args, **kwargs)
+ return wrapper
def _get_exception(self, error_code=None):
if error_code is None:
@@ -454,21 +518,19 @@
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())
-
def _reset_cursors(self):
for cursor_ref in self.cursors:
cursor = cursor_ref()
if cursor:
cursor.reset = True
+ @_check_thread_wrap
+ @_check_closed_wrap
+ def __call__(self, sql):
+ if not isinstance(sql, basestring):
+ raise Warning("SQL is of wrong type. Must be string or unicode.")
+ return self.statement_cache.get(sql, self.row_factory)
+
def cursor(self, factory=None):
self._check_thread()
self._check_closed()
@@ -479,63 +541,41 @@
cur.row_factory = self.row_factory
return cur
+ def execute(self, *args):
+ cur = self.cursor()
+ return cur.execute(*args)
+
def executemany(self, *args):
- self._check_closed()
- cur = Cursor(self)
- if self.row_factory is not None:
- cur.row_factory = self.row_factory
+ cur = self.cursor()
return cur.executemany(*args)
- def execute(self, *args):
- self._check_closed()
- cur = Cursor(self)
- if self.row_factory is not None:
- cur.row_factory = self.row_factory
- return cur.execute(*args)
-
def executescript(self, *args):
- self._check_closed()
- cur = Cursor(self)
- if self.row_factory is not None:
- cur.row_factory = self.row_factory
+ cur = self.cursor()
return cur.executescript(*args)
- def __call__(self, sql):
- self._check_closed()
- if not isinstance(sql, (str, unicode)):
- raise Warning("SQL is of wrong type. Must be string or unicode.")
- statement = self.statement_cache.get(sql, self.row_factory)
- return statement
-
- def _get_isolation_level(self):
- return self._isolation_level
-
- def _set_isolation_level(self, val):
- if val is None:
- self.commit()
- if isinstance(val, unicode):
- val = str(val)
- self._isolation_level = val
- isolation_level = property(_get_isolation_level, _set_isolation_level)
+ def iterdump(self):
+ from sqlite3.dump import _iterdump
+ return _iterdump(self)
def _begin(self):
self._check_closed()
if self._isolation_level is None:
return
- if lib.sqlite3_get_autocommit(self.db):
- sql = "BEGIN " + self._isolation_level
- 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:
- if ret != lib.SQLITE_OK:
- raise self._get_exception(ret)
- ret = lib.sqlite3_step(statement_star[0])
- if ret != lib.SQLITE_DONE:
- raise self._get_exception(ret)
- finally:
- lib.sqlite3_finalize(statement_star[0])
+ if not lib.sqlite3_get_autocommit(self.db):
+ return
+ sql = "BEGIN " + self._isolation_level
+ 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:
+ if ret != lib.SQLITE_OK:
+ raise self._get_exception(ret)
+ ret = lib.sqlite3_step(statement_star[0])
+ if ret != lib.SQLITE_DONE:
+ raise self._get_exception(ret)
+ finally:
+ lib.sqlite3_finalize(statement_star[0])
def commit(self):
self._check_thread()
@@ -548,10 +588,9 @@
if obj is not None:
obj.reset()
- sql = "COMMIT"
statement_star = ffi.new('sqlite3_stmt **')
next_char = ffi.new('char **')
- ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star,
+ ret = lib.sqlite3_prepare_v2(self.db, b"COMMIT", -1, statement_star,
next_char)
try:
if ret != lib.SQLITE_OK:
@@ -573,10 +612,9 @@
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,
+ ret = lib.sqlite3_prepare_v2(self.db, b"ROLLBACK", -1, statement_star,
next_char)
try:
if ret != lib.SQLITE_OK:
@@ -588,10 +626,6 @@
lib.sqlite3_finalize(statement_star[0])
self._reset_cursors()
- def _check_closed(self):
- if getattr(self, 'closed', True):
- raise ProgrammingError("Cannot operate on a closed database.")
-
def __enter__(self):
return self
@@ -601,30 +635,88 @@
else:
self.rollback()
- def _get_total_changes(self):
- return lib.sqlite3_total_changes(self.db)
- total_changes = property(_get_total_changes)
+ @_check_thread_wrap
+ @_check_closed_wrap
+ def create_function(self, name, num_args, callback):
+ try:
+ 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)
+ 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")
- def close(self):
- self._check_thread()
- if self.closed:
- return
- for statement in self.statements:
- obj = statement()
- if obj is not None:
- obj.finalize()
+ @_check_thread_wrap
+ @_check_closed_wrap
+ def create_aggregate(self, name, num_args, cls):
+ try:
+ step_callback, final_callback = self._aggregates[cls]
+ except KeyError:
+ @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)")
+ def step_callback(context, argc, c_params):
+ res = lib.sqlite3_aggregate_context(context,
+ ffi.sizeof("size_t"))
+ aggregate_ptr = ffi.cast("size_t[1]", res)
- self.closed = True
- ret = lib.sqlite3_close(self.db)
- self._reset_cursors()
+ if not aggregate_ptr[0]:
+ try:
+ aggregate = cls()
+ except Exception:
+ msg = (b"user-defined aggregate's '__init__' "
+ b"method raised error")
+ lib.sqlite3_result_error(context, msg, len(msg))
+ return
+ aggregate_id = id(aggregate)
+ self.aggregate_instances[aggregate_id] = aggregate
+ aggregate_ptr[0] = aggregate_id
+ else:
+ aggregate = self.aggregate_instances[aggregate_ptr[0]]
+
+ params = _convert_params(context, argc, c_params)
+ try:
+ aggregate.step(*params)
+ except Exception:
+ msg = (b"user-defined aggregate's 'step' "
+ b"method raised error")
+ lib.sqlite3_result_error(context, msg, len(msg))
+
+ @ffi.callback("void(sqlite3_context*)")
+ def final_callback(context):
+ res = lib.sqlite3_aggregate_context(context,
+ ffi.sizeof("size_t"))
+ aggregate_ptr = ffi.cast("size_t[1]", res)
+
+ if aggregate_ptr[0]:
+ aggregate = self.aggregate_instances[aggregate_ptr[0]]
+ try:
+ val = aggregate.finalize()
+ except Exception:
+ msg = (b"user-defined aggregate's 'finalize' "
+ b"method raised error")
+ lib.sqlite3_result_error(context, msg, len(msg))
+ else:
+ _convert_result(context, val)
+ finally:
+ del self.aggregate_instances[aggregate_ptr[0]]
+
+ self._aggregates[cls] = step_callback, 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)
+ @_check_thread_wrap
+ @_check_closed_wrap
def create_collation(self, name, callback):
- self._check_thread()
- self._check_closed()
name = name.upper()
- if not name.replace('_', '').isalnum():
+ if not all(c in string.ascii_uppercase + string.digits + '_' for c in name):
raise ProgrammingError("invalid character in collation name")
if callback is None:
@@ -648,9 +740,28 @@
if ret != lib.SQLITE_OK:
raise self._get_exception(ret)
+ @_check_thread_wrap
+ @_check_closed_wrap
+ def set_authorizer(self, callback):
+ try:
+ 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
+ self.func_cache[callback] = authorizer
+
+ ret = lib.sqlite3_set_authorizer(self.db, authorizer, ffi.NULL)
+ if ret != lib.SQLITE_OK:
+ raise self._get_exception(ret)
+
+ @_check_thread_wrap
+ @_check_closed_wrap
def set_progress_handler(self, callable, nsteps):
- self._check_thread()
- self._check_closed()
if callable is None:
progress_handler = ffi.NULL
else:
@@ -670,113 +781,26 @@
lib.sqlite3_progress_handler(self.db, nsteps, progress_handler,
ffi.NULL)
- def set_authorizer(self, callback):
- self._check_thread()
+ def __get_total_changes(self):
self._check_closed()
+ return lib.sqlite3_total_changes(self.db)
+ total_changes = property(__get_total_changes)
- try:
- 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
- self.func_cache[callback] = authorizer
+ def __get_isolation_level(self):
+ return self._isolation_level
- ret = lib.sqlite3_set_authorizer(self.db, authorizer, ffi.NULL)
- if ret != lib.SQLITE_OK:
- raise self._get_exception(ret)
-
- def create_function(self, name, num_args, callback):
- self._check_thread()
- self._check_closed()
- try:
- 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)
- 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")
-
- def create_aggregate(self, name, num_args, cls):
- self._check_thread()
- self._check_closed()
-
- try:
- step_callback, final_callback = self._aggregates[cls]
- except KeyError:
- @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)")
- def step_callback(context, argc, c_params):
- res = lib.sqlite3_aggregate_context(context,
- ffi.sizeof("size_t"))
- aggregate_ptr = ffi.cast("size_t[1]", res)
-
- if not aggregate_ptr[0]:
- try:
- aggregate = cls()
- except Exception:
- msg = ("user-defined aggregate's '__init__' "
- "method raised error")
- lib.sqlite3_result_error(context, msg, len(msg))
- return
- aggregate_id = id(aggregate)
- self.aggregate_instances[aggregate_id] = aggregate
- aggregate_ptr[0] = aggregate_id
- else:
- aggregate = self.aggregate_instances[aggregate_ptr[0]]
-
- params = _convert_params(context, argc, c_params)
- try:
- aggregate.step(*params)
- except Exception:
- msg = ("user-defined aggregate's 'step' "
- "method raised error")
- lib.sqlite3_result_error(context, msg, len(msg))
-
- @ffi.callback("void(sqlite3_context*)")
- def final_callback(context):
- res = lib.sqlite3_aggregate_context(context,
- ffi.sizeof("size_t"))
- aggregate_ptr = ffi.cast("size_t[1]", res)
-
- if aggregate_ptr[0]:
- aggregate = self.aggregate_instances[aggregate_ptr[0]]
- try:
- val = aggregate.finalize()
- except Exception:
- msg = ("user-defined aggregate's 'finalize' "
- "method raised error")
- lib.sqlite3_result_error(context, msg, len(msg))
- else:
- _convert_result(context, val)
- finally:
- del self.aggregate_instances[aggregate_ptr[0]]
-
- self._aggregates[cls] = step_callback, 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)
-
- def iterdump(self):
- from sqlite3.dump import _iterdump
- return _iterdump(self)
+ def __set_isolation_level(self, val):
+ if val is None:
+ self.commit()
+ if isinstance(val, unicode):
+ val = str(val)
+ self._isolation_level = val
+ isolation_level = property(__get_isolation_level, __set_isolation_level)
if hasattr(lib, 'sqlite3_enable_load_extension'):
+ @_check_thread_wrap
+ @_check_closed_wrap
def enable_load_extension(self, enabled):
- self._check_thread()
- self._check_closed()
-
rc = lib.sqlite3_enable_load_extension(self.db, int(enabled))
if rc != lib.SQLITE_OK:
raise OperationalError("Error enabling load extension")
@@ -1074,43 +1098,44 @@
self.row_cast_map.append(converter)
- def _check_decodable(self, param):
- if self.con.text_factory in (unicode, OptimizedUnicode,
- unicode_text_factory):
- for c in param:
- if ord(c) & 0x80 != 0:
- raise self.con.ProgrammingError(
+ if sys.version_info[0] < 3:
+ def __check_decodable(self, param):
+ if self.con.text_factory in (unicode, OptimizedUnicode,
+ _unicode_text_factory):
+ for c in param:
+ if ord(c) & 0x80 != 0:
+ raise self.con.ProgrammingError(
"You must not use 8-bit bytestrings unless "
"you use a text_factory that can interpret "
"8-bit bytestrings (like text_factory = str). "
"It is highly recommended that you instead "
"just switch your application to Unicode strings.")
- def set_param(self, idx, param):
+ def __set_param(self, idx, param):
cvt = converters.get(type(param))
if cvt is not None:
- cvt = param = cvt(param)
+ param = cvt(param)
param = adapt(param)
if param is None:
lib.sqlite3_bind_null(self.statement, idx)
- elif type(param) in (bool, int, long):
+ elif isinstance(param, (bool, int, long)):
if -2147483648 <= param <= 2147483647:
lib.sqlite3_bind_int(self.statement, idx, param)
else:
lib.sqlite3_bind_int64(self.statement, idx, param)
- elif type(param) is float:
+ elif isinstance(param, float):
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),
- _SQLITE_TRANSIENT)
elif isinstance(param, unicode):
param = param.encode("utf-8")
lib.sqlite3_bind_text(self.statement, idx, param, len(param),
_SQLITE_TRANSIENT)
- elif type(param) is buffer:
+ elif isinstance(param, str):
+ self.__check_decodable(param)
+ lib.sqlite3_bind_text(self.statement, idx, param, len(param),
+ _SQLITE_TRANSIENT)
+ elif isinstance(param, (buffer, bytes)):
lib.sqlite3_bind_blob(self.statement, idx, str(param), len(param),
_SQLITE_TRANSIENT)
else:
@@ -1139,7 +1164,7 @@
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:
param_count = lib.sqlite3_bind_parameter_count(self.statement)
for idx in range(1, param_count + 1):
@@ -1152,7 +1177,7 @@
param = params[param_name]
except KeyError:
raise ProgrammingError("missing parameter '%s'" % param)
- self.set_param(idx, param)
+ self.__set_param(idx, param)
def next(self, cursor):
self.con._check_closed()
@@ -1181,23 +1206,21 @@
converter = self.row_cast_map[i]
if converter is None:
- if typ == lib.SQLITE_INTEGER:
+ if typ == lib.SQLITE_NULL:
+ val = None
+ elif typ == lib.SQLITE_INTEGER:
val = lib.sqlite3_column_int64(self.statement, i)
- 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 = buffer(ffi.buffer(blob, blob_len))
- elif typ == lib.SQLITE_NULL:
- val = None
elif typ == lib.SQLITE_TEXT:
+ text = lib.sqlite3_column_text(self.statement, i)
text_len = lib.sqlite3_column_bytes(self.statement, i)
- text = lib.sqlite3_column_text(self.statement, i)
val = ffi.buffer(text, text_len)[:]
val = self.con.text_factory(val)
+ elif typ == lib.SQLITE_BLOB:
+ blob = lib.sqlite3_column_blob(self.statement, i)
+ blob_len = lib.sqlite3_column_bytes(self.statement, i)
+ val = _BLOB_TYPE(ffi.buffer(blob, blob_len))
else:
blob = lib.sqlite3_column_blob(self.statement, i)
if not blob:
@@ -1324,22 +1347,19 @@
_params = []
for i in range(nargs):
typ = lib.sqlite3_value_type(params[i])
- if typ == lib.SQLITE_INTEGER:
+ if typ == lib.SQLITE_NULL:
+ val = None
+ elif typ == lib.SQLITE_INTEGER:
val = lib.sqlite3_value_int64(params[i])
- if -sys.maxint - 1 <= val <= sys.maxint:
- val = int(val)
elif typ == lib.SQLITE_FLOAT:
val = lib.sqlite3_value_double(params[i])
- elif typ == lib.SQLITE_BLOB:
- blob_len = lib.sqlite3_value_bytes(params[i])
- blob = lib.sqlite3_value_blob(params[i])
- val = buffer(ffi.buffer(blob, blob_len))
- elif typ == lib.SQLITE_NULL:
- val = None
elif typ == lib.SQLITE_TEXT:
val = lib.sqlite3_value_text(params[i])
- # XXX changed from con.text_factory
val = unicode(ffi.string(val), 'utf-8')
+ elif typ == lib.SQLITE_BLOB:
+ blob = lib.sqlite3_value_blob(params[i])
+ blob_len = lib.sqlite3_value_bytes(params[i])
+ val = _BLOB_TYPE(ffi.buffer(blob, blob_len))
else:
raise NotImplementedError
_params.append(val)
@@ -1351,26 +1371,25 @@
lib.sqlite3_result_null(con)
elif isinstance(val, (bool, int, long)):
lib.sqlite3_result_int64(con, int(val))
- elif isinstance(val, str):
- # XXX ignoring unicode issue
- lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
+ elif isinstance(val, float):
+ lib.sqlite3_result_double(con, val)
elif isinstance(val, unicode):
val = val.encode('utf-8')
lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
- elif isinstance(val, float):
- lib.sqlite3_result_double(con, val)
- elif isinstance(val, buffer):
+ elif isinstance(val, str):
+ lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
+ elif isinstance(val, (buffer, bytes)):
lib.sqlite3_result_blob(con, str(val), len(val), _SQLITE_TRANSIENT)
else:
raise NotImplementedError
-def function_callback(real_cb, context, nargs, c_params):
+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"
+ msg = b"user-defined function raised exception"
lib.sqlite3_result_error(context, msg, len(msg))
else:
_convert_result(context, val)
@@ -1411,10 +1430,8 @@
microseconds = int(timepart_full[1])
else:
microseconds = 0
-
- val = datetime.datetime(year, month, day, hours, minutes, seconds,
- microseconds)
- return val
+ return datetime.datetime(year, month, day, hours, minutes, seconds,
+ microseconds)
register_adapter(datetime.date, adapt_date)
register_adapter(datetime.datetime, adapt_datetime)
@@ -1451,11 +1468,3 @@
return val
register_adapters_and_converters()
-
-
-def OptimizedUnicode(s):
- try:
- val = unicode(s, "ascii").encode("ascii")
- except UnicodeDecodeError:
- val = unicode(s, "utf-8")
- return val
More information about the pypy-commit
mailing list