def __build_row_cast_map(self): if not self.__connection._detect_types: return self.__row_cast_map = [] for i in xrange(_lib.sqlite3_column_count(self.__statement._statement)): converter = None if self.__connection._detect_types & PARSE_COLNAMES: colname = _lib.sqlite3_column_name(self.__statement._statement, i) if colname: colname = _ffi.string(colname).decode('utf-8') type_start = -1 key = None for pos in range(len(colname)): if colname[pos] == '[': type_start = pos + 1 elif colname[pos] == ']' and type_start != -1: key = colname[type_start:pos] converter = converters[key.upper()] if converter is None and self.__connection._detect_types & PARSE_DECLTYPES: decltype = _lib.sqlite3_column_decltype(self.__statement._statement, i) if decltype: decltype = _ffi.string(decltype).decode('utf-8') # if multiple words, use first, eg. # "INTEGER NOT NULL" => "INTEGER" decltype = decltype.split()[0] if '(' in decltype: decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) self.__row_cast_map.append(converter)
def __build_row_cast_map(self): if not self.__connection._detect_types: return self.__row_cast_map = [] for i in xrange(_lib.sqlite3_column_count( self.__statement._statement)): converter = None if self.__connection._detect_types & PARSE_COLNAMES: colname = _lib.sqlite3_column_name(self.__statement._statement, i) if colname: colname = _ffi.string(colname).decode('utf-8') type_start = -1 key = None for pos in range(len(colname)): if colname[pos] == '[': type_start = pos + 1 elif colname[pos] == ']' and type_start != -1: key = colname[type_start:pos] converter = converters[key.upper()] if converter is None and self.__connection._detect_types & PARSE_DECLTYPES: decltype = _lib.sqlite3_column_decltype( self.__statement._statement, i) if decltype: decltype = _ffi.string(decltype).decode('utf-8') # if multiple words, use first, eg. # "INTEGER NOT NULL" => "INTEGER" decltype = decltype.split()[0] if '(' in decltype: decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) self.__row_cast_map.append(converter)
def _get_exception(self, error_code=None): if error_code is None: error_code = _lib.sqlite3_errcode(self._db) 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") elif error_code in (_lib.SQLITE_INTERNAL, _lib.SQLITE_NOTFOUND): 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): exc = OperationalError elif error_code == _lib.SQLITE_CORRUPT: exc = DatabaseError elif error_code == _lib.SQLITE_TOOBIG: exc = DataError elif error_code in (_lib.SQLITE_CONSTRAINT, _lib.SQLITE_MISMATCH): exc = IntegrityError elif error_code == _lib.SQLITE_MISUSE: exc = ProgrammingError else: exc = DatabaseError exc = exc(error_message) exc.error_code = error_code return exc
def _get_exception(self, error_code=None): if error_code is None: error_code = _lib.sqlite3_errcode(self._db) 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") elif error_code in (_lib.SQLITE_INTERNAL, _lib.SQLITE_NOTFOUND): 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): exc = OperationalError elif error_code == _lib.SQLITE_CORRUPT: exc = DatabaseError elif error_code == _lib.SQLITE_TOOBIG: exc = DataError elif error_code in (_lib.SQLITE_CONSTRAINT, _lib.SQLITE_MISMATCH): exc = IntegrityError elif error_code == _lib.SQLITE_MISUSE: exc = ProgrammingError else: exc = DatabaseError exc = exc(error_message) exc.error_code = error_code return exc
def __init__(self, connection, sql): self.__con = connection self._in_use = False if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") if '\0' in sql: raise ValueError("the query contains a null character") if sql.strip(): first_word = sql.lstrip().split()[0].upper() if first_word == '': self._type = _STMT_TYPE_INVALID if first_word == "SELECT": self._type = _STMT_TYPE_SELECT elif first_word == "INSERT": self._type = _STMT_TYPE_INSERT elif first_word == "UPDATE": self._type = _STMT_TYPE_UPDATE elif first_word == "DELETE": self._type = _STMT_TYPE_DELETE elif first_word == "REPLACE": self._type = _STMT_TYPE_REPLACE else: self._type = _STMT_TYPE_OTHER else: self._type = _STMT_TYPE_INVALID if isinstance(sql, unicode): sql = sql.encode('utf-8') self._valid = True statement_star = _ffi.new('sqlite3_stmt **') next_char = _ffi.new('char **') c_sql = _ffi.new("char[]", sql) ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] if ret == _lib.SQLITE_OK and not self._statement: # an empty statement, work around that, as it's the least trouble self._type = _STMT_TYPE_SELECT c_sql = _ffi.new("char[]", b"select 42 where 42 = 23") ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] self._valid = False if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) tail = _ffi.string(next_char[0]).decode('utf-8') if _check_remaining_sql(tail): raise Warning("You can only execute one statement at a time.")
def __fetch_one_row(self): num_cols = _lib.sqlite3_data_count(self.__statement._statement) row = newlist_hint(num_cols) for i in xrange(num_cols): if self.__connection._detect_types: converter = self.__row_cast_map[i] else: converter = None if converter is not None: blob = _lib.sqlite3_column_blob(self.__statement._statement, i) if not blob: val = None else: blob_len = _lib.sqlite3_column_bytes( self.__statement._statement, i) val = _ffi.buffer(blob, blob_len)[:] val = converter(val) else: typ = _lib.sqlite3_column_type(self.__statement._statement, i) if typ == _lib.SQLITE_NULL: val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_column_int64( self.__statement._statement, i) val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_column_double( self.__statement._statement, i) elif typ == _lib.SQLITE_TEXT: text = _lib.sqlite3_column_text( self.__statement._statement, i) text_len = _lib.sqlite3_column_bytes( self.__statement._statement, i) val = _ffi.buffer(text, text_len)[:] try: val = self.__connection.text_factory(val) except Exception: column_name = _lib.sqlite3_column_name( self.__statement._statement, i) if column_name: column_name = _ffi.string(column_name).decode( 'utf-8') else: column_name = "<unknown column name>" val = val.decode('ascii', 'replace') raise OperationalError( "Could not decode to UTF-8 column '%s' with text '%s'" % (column_name, val)) elif typ == _lib.SQLITE_BLOB: blob = _lib.sqlite3_column_blob( self.__statement._statement, i) blob_len = _lib.sqlite3_column_bytes( self.__statement._statement, i) val = _BLOB_TYPE(_ffi.buffer(blob, blob_len)[:]) row.append(val) return tuple(row)
def _get_description(self): if self._is_dml: return None desc = [] for i in xrange(_lib.sqlite3_column_count(self._statement)): name = _lib.sqlite3_column_name(self._statement, i) if name: name = _ffi.string(name).decode('utf-8').split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc
def _get_description(self): if self._type in (_STMT_TYPE_INSERT, _STMT_TYPE_UPDATE, _STMT_TYPE_DELETE, _STMT_TYPE_REPLACE): return None desc = [] for i in xrange(_lib.sqlite3_column_count(self._statement)): name = _lib.sqlite3_column_name(self._statement, i) if name: name = _ffi.string(name).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc
def __init__(self, connection, sql): self.__con = connection self._in_use = False if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") if '\0' in sql: raise ValueError("the query contains a null character") first_word = sql.lstrip().split(" ")[0].upper() if first_word == "": self._type = _STMT_TYPE_INVALID elif first_word == "SELECT": self._type = _STMT_TYPE_SELECT elif first_word == "INSERT": self._type = _STMT_TYPE_INSERT elif first_word == "UPDATE": self._type = _STMT_TYPE_UPDATE elif first_word == "DELETE": self._type = _STMT_TYPE_DELETE elif first_word == "REPLACE": self._type = _STMT_TYPE_REPLACE else: self._type = _STMT_TYPE_OTHER if isinstance(sql, unicode): sql = sql.encode('utf-8') statement_star = _ffi.new('sqlite3_stmt **') next_char = _ffi.new('char **') c_sql = _ffi.new("char[]", sql) ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] if ret == _lib.SQLITE_OK and not self._statement: # an empty statement, work around that, as it's the least trouble self._type = _STMT_TYPE_SELECT c_sql = _ffi.new("char[]", b"select 42") ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) tail = _ffi.string(next_char[0]).decode('utf-8') if _check_remaining_sql(tail): raise Warning("You can only execute one statement at a time.")
def __fetch_one_row(self): num_cols = _lib.sqlite3_data_count(self.__statement._statement) row = newlist_hint(num_cols) for i in xrange(num_cols): if self.__connection._detect_types: converter = self.__row_cast_map[i] else: converter = None if converter is not None: blob = _lib.sqlite3_column_blob(self.__statement._statement, i) if not blob: val = None else: blob_len = _lib.sqlite3_column_bytes(self.__statement._statement, i) val = _ffi.buffer(blob, blob_len)[:] val = converter(val) else: typ = _lib.sqlite3_column_type(self.__statement._statement, i) if typ == _lib.SQLITE_NULL: val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_column_int64(self.__statement._statement, i) val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_column_double(self.__statement._statement, i) elif typ == _lib.SQLITE_TEXT: text = _lib.sqlite3_column_text(self.__statement._statement, i) text_len = _lib.sqlite3_column_bytes(self.__statement._statement, i) val = _ffi.buffer(text, text_len)[:] try: val = self.__connection.text_factory(val) except Exception: column_name = _lib.sqlite3_column_name( self.__statement._statement, i) if column_name: column_name = _ffi.string(column_name).decode('utf-8') else: column_name = "<unknown column name>" val = val.decode('ascii', 'replace') raise OperationalError( "Could not decode to UTF-8 column '%s' with text '%s'" % ( column_name, val)) elif typ == _lib.SQLITE_BLOB: blob = _lib.sqlite3_column_blob(self.__statement._statement, i) blob_len = _lib.sqlite3_column_bytes(self.__statement._statement, i) val = _BLOB_TYPE(_ffi.buffer(blob, blob_len)[:]) row.append(val) return tuple(row)
def _set_params(self, params): self._in_use = True num_params_needed = _lib.sqlite3_bind_parameter_count(self._statement) if isinstance(params, (tuple, list)) or \ not isinstance(params, dict) and \ hasattr(params, '__getitem__'): try: num_params = len(params) except TypeError: num_params = -1 if num_params != num_params_needed: raise ProgrammingError( "Incorrect number of bindings supplied. " "The current statement uses %d, and " "there are %d supplied." % (num_params_needed, num_params)) for i in range(num_params): rc = self.__set_param(i + 1, params[i]) if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter %d - " "probably unsupported type." % i) elif isinstance(params, dict): for i in range(1, num_params_needed + 1): param_name = _lib.sqlite3_bind_parameter_name( self._statement, i) if not param_name: raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " "only names)." % i) param_name = _ffi.string(param_name).decode('utf-8')[1:] try: param = params[param_name] except KeyError: raise ProgrammingError("You did not supply a value for " "binding %d." % i) rc = self.__set_param(i, param) if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter :%s - " "probably unsupported type." % param_name) else: raise ValueError("parameters are of unsupported type")
def _set_params(self, params): self._in_use = True num_params_needed = _lib.sqlite3_bind_parameter_count(self._statement) if isinstance(params, (tuple, list)) or \ not isinstance(params, dict) and \ hasattr(params, '__getitem__'): try: num_params = len(params) except TypeError: num_params = -1 if num_params != num_params_needed: raise ProgrammingError("Incorrect number of bindings supplied. " "The current statement uses %d, and " "there are %d supplied." % (num_params_needed, num_params)) for i in range(num_params): rc = self.__set_param(i + 1, params[i]) if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter %d - " "probably unsupported type." % i) elif isinstance(params, dict): for i in range(1, num_params_needed + 1): param_name = _lib.sqlite3_bind_parameter_name(self._statement, i) if not param_name: raise ProgrammingError("Binding %d has no name, but you " "supplied a dictionary (which has " "only names)." % i) param_name = _ffi.string(param_name).decode('utf-8')[1:] try: param = params[param_name] except KeyError: raise ProgrammingError("You did not supply a value for " "binding %d." % i) rc = self.__set_param(i, param) if rc != _lib.SQLITE_OK: raise InterfaceError("Error binding parameter :%s - " "probably unsupported type." % param_name) else: raise ValueError("parameters are of unsupported type")
def executescript(self, sql): self.__check_cursor() self._reset = False if isinstance(sql, unicode): sql = sql.encode('utf-8') elif not isinstance(sql, str): raise ValueError("script argument must be unicode or string.") statement_star = _ffi.new('sqlite3_stmt **') next_char = _ffi.new('char **') self.__connection.commit() while True: c_sql = _ffi.new("char[]", sql) rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1, statement_star, next_char) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) rc = _lib.SQLITE_ROW while rc == _lib.SQLITE_ROW: if not statement_star[0]: rc = _lib.SQLITE_OK else: rc = _lib.sqlite3_step(statement_star[0]) if rc != _lib.SQLITE_DONE: _lib.sqlite3_finalize(statement_star[0]) if rc == _lib.SQLITE_OK: break else: raise self.__connection._get_exception(rc) rc = _lib.sqlite3_finalize(statement_star[0]) if rc != _lib.SQLITE_OK: raise self.__connection._get_exception(rc) sql = _ffi.string(next_char[0]) if not sql: break return self
def _convert_params(con, nargs, params): _params = [] for i in range(nargs): typ = _lib.sqlite3_value_type(params[i]) if typ == _lib.SQLITE_NULL: val = None elif typ == _lib.SQLITE_INTEGER: val = _lib.sqlite3_value_int64(params[i]) val = int(val) elif typ == _lib.SQLITE_FLOAT: val = _lib.sqlite3_value_double(params[i]) elif typ == _lib.SQLITE_TEXT: val = _lib.sqlite3_value_text(params[i]) val = _ffi.string(val).decode('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) return _params
def __init__(self, connection, sql): self.__con = connection self._in_use = False if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") if '\0' in sql: raise ValueError("the query contains a null character") to_check = sql.lstrip().upper() self._valid = bool(to_check) self._is_dml = to_check.startswith(('INSERT', 'UPDATE', 'DELETE', 'REPLACE')) statement_star = _ffi.new('sqlite3_stmt **') next_char = _ffi.new('char **') c_sql = _ffi.new("char[]", sql.encode('utf-8')) ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] if ret == _lib.SQLITE_OK and not self._statement: # an empty statement, work around that, as it's the least trouble c_sql = _ffi.new("char[]", b"select 42") ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) self.__con._remember_statement(self) tail = _ffi.string(next_char[0]).decode('utf-8') if _check_remaining_sql(tail): raise Warning("You can only execute one statement at a time.")
def trace_callback(userdata, statement): stmt = _ffi.string(statement).decode('utf-8') callable(stmt)
] for symbol in exported_sqlite_symbols: globals()[symbol] = getattr(_lib, symbol) _SQLITE_TRANSIENT = _lib.SQLITE_TRANSIENT # pysqlite version information version = "2.6.0" # pysqlite constants PARSE_COLNAMES = 1 PARSE_DECLTYPES = 2 # SQLite version information sqlite_version = str(_ffi.string(_lib.sqlite3_libversion()).decode('ascii')) _STMT_TYPE_UPDATE = 0 _STMT_TYPE_DELETE = 1 _STMT_TYPE_INSERT = 2 _STMT_TYPE_REPLACE = 3 _STMT_TYPE_OTHER = 4 _STMT_TYPE_SELECT = 5 _STMT_TYPE_INVALID = 6 class Error(StandardError): pass class Warning(StandardError):