Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: 
Changeset: r62981:d4cd0aad9244
Date: 2013-04-03 20:53 +0200
http://bitbucket.org/pypy/pypy/changeset/d4cd0aad9244/

Log:    remerge sqlite-cffi. Now with all tests passing

diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -23,9 +23,6 @@
 #
 # Note: This software has been modified for use in PyPy.
 
-from ctypes import c_void_p, c_int, c_double, c_int64, c_char_p, c_char, cdll
-from ctypes import POINTER, byref, string_at, CFUNCTYPE, cast
-from ctypes import sizeof, c_ssize_t
 from collections import OrderedDict
 from functools import wraps
 import datetime
@@ -44,210 +41,264 @@
 else:
     _BLOB_TYPE = buffer
 
+from cffi import FFI as _FFI
 
-def load_library(names):
-    for name in names:
-        try:
-            return cdll.LoadLibrary(name)
-        except OSError:
-            pass
-    else:
-        raise ImportError("Could not load C-library, tried: %s" % (names,))
+_ffi = _FFI()
 
-_lib = load_library(
-    "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split())
-del load_library
+_ffi.cdef("""
+#define SQLITE_OK ...
+#define SQLITE_ERROR ...
+#define SQLITE_INTERNAL ...
+#define SQLITE_PERM ...
+#define SQLITE_ABORT ...
+#define SQLITE_BUSY ...
+#define SQLITE_LOCKED ...
+#define SQLITE_NOMEM ...
+#define SQLITE_READONLY ...
+#define SQLITE_INTERRUPT ...
+#define SQLITE_IOERR ...
+#define SQLITE_CORRUPT ...
+#define SQLITE_NOTFOUND ...
+#define SQLITE_FULL ...
+#define SQLITE_CANTOPEN ...
+#define SQLITE_PROTOCOL ...
+#define SQLITE_EMPTY ...
+#define SQLITE_SCHEMA ...
+#define SQLITE_TOOBIG ...
+#define SQLITE_CONSTRAINT ...
+#define SQLITE_MISMATCH ...
+#define SQLITE_MISUSE ...
+#define SQLITE_NOLFS ...
+#define SQLITE_AUTH ...
+#define SQLITE_FORMAT ...
+#define SQLITE_RANGE ...
+#define SQLITE_NOTADB ...
+#define SQLITE_ROW ...
+#define SQLITE_DONE ...
+#define SQLITE_INTEGER ...
+#define SQLITE_FLOAT ...
+#define SQLITE_BLOB ...
+#define SQLITE_NULL ...
+#define SQLITE_TEXT ...
+#define SQLITE3_TEXT ...
 
-##########################################
-# BEGIN Wrapped SQLite C API and constants
-##########################################
+#define SQLITE_TRANSIENT ...
+#define SQLITE_UTF8 ...
 
-_lib.SQLITE_OK = 0
-_lib.SQLITE_ERROR = 1
-_lib.SQLITE_INTERNAL = 2
-_lib.SQLITE_PERM = 3
-_lib.SQLITE_ABORT = 4
-_lib.SQLITE_BUSY = 5
-_lib.SQLITE_LOCKED = 6
-_lib.SQLITE_NOMEM = 7
-_lib.SQLITE_READONLY = 8
-_lib.SQLITE_INTERRUPT = 9
-_lib.SQLITE_IOERR = 10
-_lib.SQLITE_CORRUPT = 11
-_lib.SQLITE_NOTFOUND = 12
-_lib.SQLITE_FULL = 13
-_lib.SQLITE_CANTOPEN = 14
-_lib.SQLITE_PROTOCOL = 15
-_lib.SQLITE_EMPTY = 16
-_lib.SQLITE_SCHEMA = 17
-_lib.SQLITE_TOOBIG = 18
-_lib.SQLITE_CONSTRAINT = 19
-_lib.SQLITE_MISMATCH = 20
-_lib.SQLITE_MISUSE = 21
-_lib.SQLITE_NOLFS = 22
-_lib.SQLITE_AUTH = 23
-_lib.SQLITE_FORMAT = 24
-_lib.SQLITE_RANGE = 25
-_lib.SQLITE_NOTADB = 26
-_lib.SQLITE_ROW = 100
-_lib.SQLITE_DONE = 101
+#define SQLITE_DENY ...
+#define SQLITE_IGNORE ...
 
-_lib.SQLITE_INTEGER = 1
-_lib.SQLITE_FLOAT = 2
-_lib.SQLITE_TEXT = 3
-_lib.SQLITE_BLOB = 4
-_lib.SQLITE_NULL = 5
+#define SQLITE_CREATE_INDEX ...
+#define SQLITE_CREATE_TABLE ...
+#define SQLITE_CREATE_TEMP_INDEX ...
+#define SQLITE_CREATE_TEMP_TABLE ...
+#define SQLITE_CREATE_TEMP_TRIGGER ...
+#define SQLITE_CREATE_TEMP_VIEW ...
+#define SQLITE_CREATE_TRIGGER ...
+#define SQLITE_CREATE_VIEW ...
+#define SQLITE_DELETE ...
+#define SQLITE_DROP_INDEX ...
+#define SQLITE_DROP_TABLE ...
+#define SQLITE_DROP_TEMP_INDEX ...
+#define SQLITE_DROP_TEMP_TABLE ...
+#define SQLITE_DROP_TEMP_TRIGGER ...
+#define SQLITE_DROP_TEMP_VIEW ...
+#define SQLITE_DROP_TRIGGER ...
+#define SQLITE_DROP_VIEW ...
+#define SQLITE_INSERT ...
+#define SQLITE_PRAGMA ...
+#define SQLITE_READ ...
+#define SQLITE_SELECT ...
+#define SQLITE_TRANSACTION ...
+#define SQLITE_UPDATE ...
+#define SQLITE_ATTACH ...
+#define SQLITE_DETACH ...
+#define SQLITE_ALTER_TABLE ...
+#define SQLITE_REINDEX ...
+#define SQLITE_ANALYZE ...
+#define SQLITE_CREATE_VTABLE ...
+#define SQLITE_DROP_VTABLE ...
+#define SQLITE_FUNCTION ...
 
-_lib.SQLITE_UTF8 = 1
+const char *sqlite3_libversion(void);
 
-_lib.SQLITE_TRANSIENT = cast(-1, c_void_p)
+typedef ... sqlite3;
+typedef ... sqlite3_stmt;
+typedef ... sqlite3_context;
+typedef ... sqlite3_value;
+typedef int64_t sqlite3_int64;
+typedef uint64_t sqlite3_uint64;
 
-SQLITE_OK       = _lib.SQLITE_OK
+int sqlite3_open(
+    const char *filename,   /* Database filename (UTF-8) */
+    sqlite3 **ppDb          /* OUT: SQLite db handle */
+);
 
-SQLITE_DENY     = 1
-SQLITE_IGNORE   = 2
+int sqlite3_close(sqlite3 *);
 
-SQLITE_CREATE_INDEX             = 1
-SQLITE_CREATE_TABLE             = 2
-SQLITE_CREATE_TEMP_INDEX        = 3
-SQLITE_CREATE_TEMP_TABLE        = 4
-SQLITE_CREATE_TEMP_TRIGGER      = 5
-SQLITE_CREATE_TEMP_VIEW         = 6
-SQLITE_CREATE_TRIGGER           = 7
-SQLITE_CREATE_VIEW              = 8
-SQLITE_DELETE                   = 9
-SQLITE_DROP_INDEX               = 10
-SQLITE_DROP_TABLE               = 11
-SQLITE_DROP_TEMP_INDEX          = 12
-SQLITE_DROP_TEMP_TABLE          = 13
-SQLITE_DROP_TEMP_TRIGGER        = 14
-SQLITE_DROP_TEMP_VIEW           = 15
-SQLITE_DROP_TRIGGER             = 16
-SQLITE_DROP_VIEW                = 17
-SQLITE_INSERT                   = 18
-SQLITE_PRAGMA                   = 19
-SQLITE_READ                     = 20
-SQLITE_SELECT                   = 21
-SQLITE_TRANSACTION              = 22
-SQLITE_UPDATE                   = 23
-SQLITE_ATTACH                   = 24
-SQLITE_DETACH                   = 25
-SQLITE_ALTER_TABLE              = 26
-SQLITE_REINDEX                  = 27
-SQLITE_ANALYZE                  = 28
+int sqlite3_busy_timeout(sqlite3*, int ms);
+int sqlite3_prepare_v2(
+    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 */
+);
+int sqlite3_finalize(sqlite3_stmt *pStmt);
+int sqlite3_column_count(sqlite3_stmt *pStmt);
+const char *sqlite3_column_name(sqlite3_stmt*, int N);
+int sqlite3_get_autocommit(sqlite3*);
+int sqlite3_reset(sqlite3_stmt *pStmt);
+int sqlite3_step(sqlite3_stmt*);
+int sqlite3_errcode(sqlite3 *db);
+const char *sqlite3_errmsg(sqlite3*);
+int sqlite3_changes(sqlite3*);
 
-# SQLite C API
+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);
 
-_lib.sqlite3_value_int.argtypes = [c_void_p]
-_lib.sqlite3_value_int.restype = c_int
+const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+double sqlite3_column_double(sqlite3_stmt*, int iCol);
+int sqlite3_column_int(sqlite3_stmt*, int iCol);
+sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+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);
 
-_lib.sqlite3_value_int64.argtypes = [c_void_p]
-_lib.sqlite3_value_int64.restype = c_int64
+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);
 
-_lib.sqlite3_value_blob.argtypes = [c_void_p]
-_lib.sqlite3_value_blob.restype = c_void_p
+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*);
 
-_lib.sqlite3_value_bytes.argtypes = [c_void_p]
-_lib.sqlite3_value_bytes.restype = c_int
+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 */
+);
 
-_lib.sqlite3_value_double.argtypes = [c_void_p]
-_lib.sqlite3_value_double.restype = c_double
+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);
 
-_lib.sqlite3_value_text.argtypes = [c_void_p]
-_lib.sqlite3_value_text.restype = c_char_p
+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.sqlite3_value_type.argtypes = [c_void_p]
-_lib.sqlite3_value_type.restype = c_int
+def _has_load_extension():
+    """Only available since 3.3.6"""
+    unverified_ffi = _FFI()
+    unverified_ffi.cdef("""
+    typedef ... sqlite3;
+    int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+    """)
+    unverified_lib = unverified_ffi.dlopen('sqlite3')
+    return hasattr(unverified_lib, 'sqlite3_enable_load_extension')
 
-_lib.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p]
-_lib.sqlite3_bind_blob.restype = c_int
-_lib.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double]
-_lib.sqlite3_bind_double.restype = c_int
-_lib.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int]
-_lib.sqlite3_bind_int.restype = c_int
-_lib.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64]
-_lib.sqlite3_bind_int64.restype = c_int
-_lib.sqlite3_bind_null.argtypes = [c_void_p, c_int]
-_lib.sqlite3_bind_null.restype = c_int
-_lib.sqlite3_bind_parameter_count.argtypes = [c_void_p]
-_lib.sqlite3_bind_parameter_count.restype = c_int
-_lib.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p]
-_lib.sqlite3_bind_parameter_index.restype = c_int
-_lib.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int]
-_lib.sqlite3_bind_parameter_name.restype = c_char_p
-_lib.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int, c_void_p]
-_lib.sqlite3_bind_text.restype = c_int
-_lib.sqlite3_busy_timeout.argtypes = [c_void_p, c_int]
-_lib.sqlite3_busy_timeout.restype = c_int
-_lib.sqlite3_changes.argtypes = [c_void_p]
-_lib.sqlite3_changes.restype = c_int
-_lib.sqlite3_close.argtypes = [c_void_p]
-_lib.sqlite3_close.restype = c_int
-_lib.sqlite3_column_blob.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_blob.restype = c_void_p
-_lib.sqlite3_column_bytes.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_bytes.restype = c_int
-_lib.sqlite3_column_count.argtypes = [c_void_p]
-_lib.sqlite3_column_count.restype = c_int
-_lib.sqlite3_column_decltype.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_decltype.restype = c_char_p
-_lib.sqlite3_column_double.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_double.restype = c_double
-_lib.sqlite3_column_int64.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_int64.restype = c_int64
-_lib.sqlite3_column_name.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_name.restype = c_char_p
-_lib.sqlite3_column_text.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_text.restype = POINTER(c_char)
-_lib.sqlite3_column_type.argtypes = [c_void_p, c_int]
-_lib.sqlite3_column_type.restype = c_int
-_lib.sqlite3_complete.argtypes = [c_char_p]
-_lib.sqlite3_complete.restype = c_int
-_lib.sqlite3_errcode.restype = c_int
-_lib.sqlite3_errmsg.argtypes = [c_void_p]
-_lib.sqlite3_errmsg.restype = c_char_p
-_lib.sqlite3_finalize.argtypes = [c_void_p]
-_lib.sqlite3_finalize.restype = c_int
-_lib.sqlite3_get_autocommit.argtypes = [c_void_p]
-_lib.sqlite3_get_autocommit.restype = c_int
-_lib.sqlite3_last_insert_rowid.argtypes = [c_void_p]
-_lib.sqlite3_last_insert_rowid.restype = c_int64
-_lib.sqlite3_libversion.argtypes = []
-_lib.sqlite3_libversion.restype = c_char_p
-_lib.sqlite3_open.argtypes = [c_char_p, c_void_p]
-_lib.sqlite3_open.restype = c_int
-_lib.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, 
POINTER(c_char_p)]
-_lib.sqlite3_prepare.restype = c_int
-_lib.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, 
POINTER(c_char_p)]
-_lib.sqlite3_prepare_v2.restype = c_int
-_lib.sqlite3_step.argtypes = [c_void_p]
-_lib.sqlite3_step.restype = c_int
-_lib.sqlite3_reset.argtypes = [c_void_p]
-_lib.sqlite3_reset.restype = c_int
-_lib.sqlite3_total_changes.argtypes = [c_void_p]
-_lib.sqlite3_total_changes.restype = c_int
+if _has_load_extension():
+    _ffi.cdef("int sqlite3_enable_load_extension(sqlite3 *db, int onoff);")
 
-_lib.sqlite3_result_blob.argtypes = [c_void_p, c_void_p, c_int, c_void_p]
-_lib.sqlite3_result_blob.restype = None
-_lib.sqlite3_result_int64.argtypes = [c_void_p, c_int64]
-_lib.sqlite3_result_int64.restype = None
-_lib.sqlite3_result_null.argtypes = [c_void_p]
-_lib.sqlite3_result_null.restype = None
-_lib.sqlite3_result_double.argtypes = [c_void_p, c_double]
-_lib.sqlite3_result_double.restype = None
-_lib.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int]
-_lib.sqlite3_result_error.restype = None
-_lib.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
-_lib.sqlite3_result_text.restype = None
+_lib = _ffi.verify("""
+#include <sqlite3.h>
+""", libraries=['sqlite3']
+)
 
-_HAS_LOAD_EXTENSION = hasattr(_lib, "sqlite3_enable_load_extension")
-if _HAS_LOAD_EXTENSION:
-    _lib.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int]
-    _lib.sqlite3_enable_load_extension.restype = c_int
+exported_sqlite_symbols = [
+    'SQLITE_ALTER_TABLE',
+    'SQLITE_ANALYZE',
+    'SQLITE_ATTACH',
+    'SQLITE_CREATE_INDEX',
+    'SQLITE_CREATE_TABLE',
+    'SQLITE_CREATE_TEMP_INDEX',
+    'SQLITE_CREATE_TEMP_TABLE',
+    'SQLITE_CREATE_TEMP_TRIGGER',
+    'SQLITE_CREATE_TEMP_VIEW',
+    'SQLITE_CREATE_TRIGGER',
+    'SQLITE_CREATE_VIEW',
+    'SQLITE_DELETE',
+    'SQLITE_DENY',
+    'SQLITE_DETACH',
+    'SQLITE_DROP_INDEX',
+    'SQLITE_DROP_TABLE',
+    'SQLITE_DROP_TEMP_INDEX',
+    'SQLITE_DROP_TEMP_TABLE',
+    'SQLITE_DROP_TEMP_TRIGGER',
+    'SQLITE_DROP_TEMP_VIEW',
+    'SQLITE_DROP_TRIGGER',
+    'SQLITE_DROP_VIEW',
+    'SQLITE_IGNORE',
+    'SQLITE_INSERT',
+    'SQLITE_OK',
+    'SQLITE_PRAGMA',
+    'SQLITE_READ',
+    'SQLITE_REINDEX',
+    'SQLITE_SELECT',
+    'SQLITE_TRANSACTION',
+    'SQLITE_UPDATE',
+]
 
-##########################################
-# END Wrapped SQLite C API and constants
-##########################################
+for symbol in exported_sqlite_symbols:
+    globals()[symbol] = getattr(_lib, symbol)
+
+_SQLITE_TRANSIENT = _ffi.cast('void *', _lib.SQLITE_TRANSIENT)
 
 # pysqlite version information
 version = "2.6.0"
@@ -257,7 +308,7 @@
 PARSE_DECLTYPES = 2
 
 # SQLite version information
-sqlite_version = str(_lib.sqlite3_libversion().decode('ascii'))
+sqlite_version = _ffi.string(_lib.sqlite3_libversion())
 
 
 class Error(StandardError):
@@ -347,12 +398,13 @@
     def __init__(self, database, timeout=5.0, detect_types=0, 
isolation_level="",
                  check_same_thread=True, factory=None, cached_statements=100):
         self.__initialized = True
-        self._db = c_void_p()
+        db_star = _ffi.new('sqlite3 **')
 
         if isinstance(database, unicode):
             database = database.encode('utf-8')
-        if _lib.sqlite3_open(database, byref(self._db)) != _lib.SQLITE_OK:
+        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
             _lib.sqlite3_busy_timeout(self._db, timeout)
@@ -438,7 +490,7 @@
     def _get_exception(self, error_code=None):
         if error_code is None:
             error_code = _lib.sqlite3_errcode(self._db)
-        error_message = _lib.sqlite3_errmsg(self._db).decode('utf-8')
+        error_message = 
_ffi.string(_lib.sqlite3_errmsg(self._db)).decode('utf-8')
 
         if error_code == _lib.SQLITE_OK:
             raise ValueError("error signalled but got SQLITE_OK")
@@ -527,18 +579,20 @@
         return _iterdump(self)
 
     def _begin(self):
-        statement = c_void_p()
+        self._check_closed()
+        statement_star = _ffi.new('sqlite3_stmt **')
+        next_char = _ffi.new('char **')
         ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1,
-                                      byref(statement), None)
+                                      statement_star, next_char)
         try:
             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)
             self._in_transaction = True
         finally:
-            _lib.sqlite3_finalize(statement)
+            _lib.sqlite3_finalize(statement_star[0])
 
     def commit(self):
         self._check_thread()
@@ -548,18 +602,19 @@
 
         self.__do_all_statements(Statement._reset, False)
 
-        statement = c_void_p()
+        statement_star = _ffi.new('sqlite3_stmt **')
+        next_char = _ffi.new('char **')
         ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1,
-                                      byref(statement), None)
+                                      statement_star, next_char)
         try:
             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)
             self._in_transaction = False
         finally:
-            _lib.sqlite3_finalize(statement)
+            _lib.sqlite3_finalize(statement_star[0])
 
     def rollback(self):
         self._check_thread()
@@ -569,18 +624,19 @@
 
         self.__do_all_statements(Statement._reset, True)
 
-        statement = c_void_p()
+        statement_star = _ffi.new('sqlite3_stmt **')
+        next_char = _ffi.new('char **')
         ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1,
-                                      byref(statement), None)
+                                      statement_star, next_char)
         try:
             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)
             self._in_transaction = False
         finally:
-            _lib.sqlite3_finalize(statement)
+            _lib.sqlite3_finalize(statement_star[0])
 
     def __enter__(self):
         return self
@@ -595,20 +651,18 @@
     @_check_closed_wrap
     def create_function(self, name, num_args, callback):
         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
+            self.__func_cache[callback] = closure
 
         if isinstance(name, unicode):
             name = name.encode('utf-8')
         ret = _lib.sqlite3_create_function(self._db, name, num_args,
-                                           _lib.SQLITE_UTF8, None,
-                                           c_closure,
-                                           cast(None, _STEP),
-                                           cast(None, _FINAL))
+                                           _lib.SQLITE_UTF8, _ffi.NULL,
+                                           closure, _ffi.NULL, _ffi.NULL)
         if ret != _lib.SQLITE_OK:
             raise self.OperationalError("Error creating function")
 
@@ -616,13 +670,13 @@
     @_check_closed_wrap
     def create_aggregate(self, name, num_args, cls):
         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(
-                    _lib.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[1]", res)
 
                 if not aggregate_ptr[0]:
                     try:
@@ -646,11 +700,11 @@
                            b"method raised error")
                     _lib.sqlite3_result_error(context, msg, len(msg))
 
+            @_ffi.callback("void(sqlite3_context*)")
             def final_callback(context):
-                aggregate_ptr = cast(
-                    _lib.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[1]", res)
 
                 if aggregate_ptr[0]:
                     aggregate = self.__aggregate_instances[aggregate_ptr[0]]
@@ -665,19 +719,15 @@
                     finally:
                         del self.__aggregate_instances[aggregate_ptr[0]]
 
-            c_step_callback = _STEP(step_callback)
-            c_final_callback = _FINAL(final_callback)
-
-            self.__aggregates[cls] = (c_step_callback, c_final_callback,
-                                     step_callback, final_callback)
+            self.__aggregates[cls] = (step_callback, final_callback)
 
         if isinstance(name, unicode):
             name = name.encode('utf-8')
         ret = _lib.sqlite3_create_function(self._db, name, num_args,
-                                           _lib.SQLITE_UTF8, None,
-                                           cast(None, _FUNC),
-                                           c_step_callback,
-                                           c_final_callback)
+                                           _lib.SQLITE_UTF8, _ffi.NULL,
+                                           _ffi.NULL,
+                                           step_callback,
+                                           final_callback)
         if ret != _lib.SQLITE_OK:
             raise self._get_exception(ret)
 
@@ -690,26 +740,26 @@
 
         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).decode('utf-8')
-                text2 = string_at(str2, len2).decode('utf-8')
+                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
 
         if isinstance(name, unicode):
             name = name.encode('utf-8')
         ret = _lib.sqlite3_create_collation(self._db, name,
                                               _lib.SQLITE_UTF8,
-                                              None,
-                                              c_collation_callback)
+                                              _ffi.NULL,
+                                              collation_callback)
         if ret != _lib.SQLITE_OK:
             raise self._get_exception(ret)
 
@@ -717,20 +767,20 @@
     @_check_closed_wrap
     def set_authorizer(self, callback):
         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 SQLITE_DENY
-            c_authorizer = _AUTHORIZER(authorizer)
-
-            self.__func_cache[callback] = c_authorizer, authorizer
+                    return _lib.SQLITE_DENY
+            self.__func_cache[callback] = authorizer
 
         ret = _lib.sqlite3_set_authorizer(self._db,
-                                            c_authorizer,
-                                            None)
+                                          authorizer,
+                                          _ffi.NULL)
         if ret != _lib.SQLITE_OK:
             raise self._get_exception(ret)
 
@@ -738,11 +788,12 @@
     @_check_closed_wrap
     def set_progress_handler(self, callable, nsteps):
         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()
@@ -750,14 +801,10 @@
                     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 = _lib.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)
 
     if sys.version_info[0] >= 3:
         def __get_in_transaction(self):
@@ -780,7 +827,7 @@
         self._isolation_level = val
     isolation_level = property(__get_isolation_level, __set_isolation_level)
 
-    if _HAS_LOAD_EXTENSION:
+    if hasattr(_lib, 'sqlite3_enable_load_extension'):
         @_check_thread_wrap
         @_check_closed_wrap
         def enable_load_extension(self, enabled):
@@ -903,35 +950,36 @@
             sql = sql.encode('utf-8')
         elif not isinstance(sql, str):
             raise ValueError("script argument must be unicode or string.")
-        sql = c_char_p(sql)
-        statement = c_void_p()
+        statement_star = _ffi.new('sqlite3_stmt **')
+        tail = _ffi.new('char **')
 
         self.__connection.commit()
         while True:
             rc = _lib.sqlite3_prepare(self.__connection._db, sql, -1,
-                                      byref(statement), byref(sql))
+                                      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:
                     break
                 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 sql.value:
+            if not sql:
                 break
         return self
 
@@ -1020,22 +1068,22 @@
 
         if isinstance(sql, unicode):
             sql = sql.encode('utf-8')
-        sql = c_char_p(sql)
-        self._statement = c_void_p()
+        statement_star = _ffi.new('sqlite3_stmt **')
+        next_char = _ffi.new('char **')
+        ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1,
+                                      statement_star, next_char)
+        self._statement = statement_star[0]
 
-        ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1,
-                                      byref(self._statement), byref(sql))
-        if ret == _lib.SQLITE_OK and self._statement.value is None:
+        if ret == _lib.SQLITE_OK and not self._statement:
             # an empty statement, work around that, as it's the least trouble
-            sql = c_char_p(b"select 42")
-            ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1,
-                                          byref(self._statement), byref(sql))
+            ret = _lib.sqlite3_prepare_v2(self.__con._db, "select 42", -1,
+                                          statement_star, next_char)
+            self._statement = statement_star[0]
             self._kind = Statement._DQL
         if ret != _lib.SQLITE_OK:
             raise self.__con._get_exception(ret)
 
-        sql = sql.value.decode('utf-8')
-        if _check_remaining_sql(sql):
+        if _check_remaining_sql(_ffi.string(next_char[0])):
             raise Warning("You can only execute one statement at a time.")
 
     def __del__(self):
@@ -1085,15 +1133,15 @@
         elif isinstance(param, unicode):
             param = param.encode("utf-8")
             rc = _lib.sqlite3_bind_text(self._statement, idx, param,
-                                        len(param), _lib.SQLITE_TRANSIENT)
+                                        len(param), _SQLITE_TRANSIENT)
         elif isinstance(param, str):
             self.__check_decodable(param)
             rc = _lib.sqlite3_bind_text(self._statement, idx, param,
-                                        len(param), _lib.SQLITE_TRANSIENT)
+                                        len(param), _SQLITE_TRANSIENT)
         elif isinstance(param, (buffer, bytes)):
             param = bytes(param)
             rc = _lib.sqlite3_bind_blob(self._statement, idx, param,
-                                        len(param), _lib.SQLITE_TRANSIENT)
+                                        len(param), _SQLITE_TRANSIENT)
         else:
             rc = -1
         return rc
@@ -1122,11 +1170,11 @@
         elif isinstance(params, dict):
             for i in range(1, num_params_needed + 1):
                 param_name = _lib.sqlite3_bind_parameter_name(self._statement, 
i)
-                if param_name is None:
+                if not param_name:
                     raise ProgrammingError("Binding %d has no name, but you "
                                            "supplied a dictionary (which has "
                                            "only names)." % i)
-                param_name = param_name.decode('utf-8')[1:]
+                param_name = _ffi.string(param_name)[1:]
                 try:
                     param = params[param_name]
                 except KeyError:
@@ -1150,7 +1198,7 @@
             if self.__con._detect_types & PARSE_COLNAMES:
                 colname = _lib.sqlite3_column_name(self._statement, i)
                 if colname is not None:
-                    colname = colname.decode('utf-8')
+                    colname = _ffi.string(colname)
                     type_start = -1
                     key = None
                     for pos in range(len(colname)):
@@ -1163,7 +1211,7 @@
             if converter is None and self.__con._detect_types & 
PARSE_DECLTYPES:
                 decltype = _lib.sqlite3_column_decltype(self._statement, i)
                 if decltype is not None:
-                    decltype = decltype.decode('utf-8')
+                    decltype = _ffi.string(decltype)
                     # if multiple words, use first, eg.
                     # "INTEGER NOT NULL" => "INTEGER"
                     decltype = decltype.split()[0]
@@ -1188,7 +1236,7 @@
                     val = None
                 else:
                     blob_len = _lib.sqlite3_column_bytes(self._statement, i)
-                    val = bytes(string_at(blob, blob_len))
+                    val = _ffi.buffer(blob, blob_len)[:]
                     val = converter(val)
             else:
                 typ = _lib.sqlite3_column_type(self._statement, i)
@@ -1202,12 +1250,12 @@
                 elif typ == _lib.SQLITE_TEXT:
                     text = _lib.sqlite3_column_text(self._statement, i)
                     text_len = _lib.sqlite3_column_bytes(self._statement, i)
-                    val = string_at(text, text_len)
+                    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(string_at(blob, blob_len))
+                    val = _BLOB_TYPE(_ffi.buffer(blob, blob_len))
             row.append(val)
 
         row = tuple(row)
@@ -1237,8 +1285,7 @@
         desc = []
         for i in xrange(_lib.sqlite3_column_count(self._statement)):
             name = _lib.sqlite3_column_name(self._statement, i)
-            if name is not None:
-                name = name.decode('utf-8').split("[")[0].strip()
+            name = _ffi.string(name).split("[")[0].strip()
             desc.append((name, None, None, None, None, None, None))
         return desc
 
@@ -1333,11 +1380,11 @@
             val = _lib.sqlite3_value_double(params[i])
         elif typ == _lib.SQLITE_TEXT:
             val = _lib.sqlite3_value_text(params[i])
-            val = val.decode('utf-8')
+            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(string_at(blob, blob_len))
+            val = _BLOB_TYPE(_ffi.buffer(blob, blob_len))
         else:
             raise NotImplementedError
         _params.append(val)
@@ -1353,11 +1400,11 @@
         _lib.sqlite3_result_double(con, val)
     elif isinstance(val, unicode):
         val = val.encode('utf-8')
-        _lib.sqlite3_result_text(con, val, len(val), _lib.SQLITE_TRANSIENT)
+        _lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
     elif isinstance(val, str):
-        _lib.sqlite3_result_text(con, val, len(val), _lib.SQLITE_TRANSIENT)
+        _lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT)
     elif isinstance(val, (buffer, bytes)):
-        _lib.sqlite3_result_blob(con, bytes(val), len(val), 
_lib.SQLITE_TRANSIENT)
+        _lib.sqlite3_result_blob(con, bytes(val), len(val), _SQLITE_TRANSIENT)
     else:
         raise NotImplementedError
 
@@ -1372,27 +1419,6 @@
     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)
-_lib.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, 
c_void_p, _FUNC, _STEP, _FINAL]
-_lib.sqlite3_create_function.restype = c_int
-
-_lib.sqlite3_aggregate_context.argtypes = [c_void_p, c_int]
-_lib.sqlite3_aggregate_context.restype = c_void_p
-
-_COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p)
-_lib.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, 
_COLLATION]
-_lib.sqlite3_create_collation.restype = c_int
-
-_PROGRESS = CFUNCTYPE(c_int, c_void_p)
-_lib.sqlite3_progress_handler.argtypes = [c_void_p, c_int, _PROGRESS, c_void_p]
-_lib.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)
-_lib.sqlite3_set_authorizer.argtypes = [c_void_p, _AUTHORIZER, c_void_p]
-_lib.sqlite3_set_authorizer.restype = c_int
-
 converters = {}
 adapters = {}
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to