kopia lustrzana https://github.com/micropython/micropython-lib
sqlite3: Add .close() methods, better error checking and reporting.
rodzic
d4a7fda960
commit
51e06be476
|
@ -4,6 +4,8 @@ import ffi
|
||||||
sq3 = ffi.open("libsqlite3.so.0")
|
sq3 = ffi.open("libsqlite3.so.0")
|
||||||
|
|
||||||
sqlite3_open = sq3.func("i", "sqlite3_open", "sp")
|
sqlite3_open = sq3.func("i", "sqlite3_open", "sp")
|
||||||
|
#int sqlite3_close(sqlite3*);
|
||||||
|
sqlite3_close = sq3.func("i", "sqlite3_close", "p")
|
||||||
#int sqlite3_prepare(
|
#int sqlite3_prepare(
|
||||||
# sqlite3 *db, /* Database handle */
|
# sqlite3 *db, /* Database handle */
|
||||||
# const char *zSql, /* SQL statement, UTF-8 encoded */
|
# const char *zSql, /* SQL statement, UTF-8 encoded */
|
||||||
|
@ -12,6 +14,8 @@ sqlite3_open = sq3.func("i", "sqlite3_open", "sp")
|
||||||
# const char **pzTail /* OUT: Pointer to unused portion of zSql */
|
# const char **pzTail /* OUT: Pointer to unused portion of zSql */
|
||||||
#);
|
#);
|
||||||
sqlite3_prepare = sq3.func("i", "sqlite3_prepare", "psipp")
|
sqlite3_prepare = sq3.func("i", "sqlite3_prepare", "psipp")
|
||||||
|
#int sqlite3_finalize(sqlite3_stmt *pStmt);
|
||||||
|
sqlite3_finalize = sq3.func("i", "sqlite3_finalize", "p")
|
||||||
#int sqlite3_step(sqlite3_stmt*);
|
#int sqlite3_step(sqlite3_stmt*);
|
||||||
sqlite3_step = sq3.func("i", "sqlite3_step", "p")
|
sqlite3_step = sq3.func("i", "sqlite3_step", "p")
|
||||||
#int sqlite3_column_count(sqlite3_stmt *pStmt);
|
#int sqlite3_column_count(sqlite3_stmt *pStmt);
|
||||||
|
@ -22,8 +26,15 @@ sqlite3_column_int = sq3.func("i", "sqlite3_column_int", "pi")
|
||||||
# using "d" return type gives wrong results
|
# using "d" return type gives wrong results
|
||||||
sqlite3_column_double = sq3.func("f", "sqlite3_column_double", "pi")
|
sqlite3_column_double = sq3.func("f", "sqlite3_column_double", "pi")
|
||||||
sqlite3_column_text = sq3.func("s", "sqlite3_column_text", "pi")
|
sqlite3_column_text = sq3.func("s", "sqlite3_column_text", "pi")
|
||||||
|
#const char *sqlite3_errmsg(sqlite3*);
|
||||||
|
sqlite3_errmsg = sq3.func("s", "sqlite3_errmsg", "p")
|
||||||
|
|
||||||
|
# Too recent
|
||||||
|
##const char *sqlite3_errstr(int);
|
||||||
|
#sqlite3_errstr = sq3.func("s", "sqlite3_errstr", "i")
|
||||||
|
|
||||||
|
|
||||||
|
SQLITE_OK = 0
|
||||||
SQLITE_ERROR = 1
|
SQLITE_ERROR = 1
|
||||||
SQLITE_BUSY = 5
|
SQLITE_BUSY = 5
|
||||||
SQLITE_MISUSE = 21
|
SQLITE_MISUSE = 21
|
||||||
|
@ -37,6 +48,15 @@ SQLITE_BLOB = 4
|
||||||
SQLITE_NULL = 5
|
SQLITE_NULL = 5
|
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def check_error(db, s):
|
||||||
|
if s != SQLITE_OK:
|
||||||
|
raise Error(s, sqlite3_errmsg(db))
|
||||||
|
|
||||||
|
|
||||||
class Connections:
|
class Connections:
|
||||||
|
|
||||||
def __init__(self, h):
|
def __init__(self, h):
|
||||||
|
@ -45,43 +65,53 @@ class Connections:
|
||||||
def cursor(self):
|
def cursor(self):
|
||||||
return Cursor(self.h)
|
return Cursor(self.h)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
s = sqlite3_close(self.h)
|
||||||
|
check_error(self.h, s)
|
||||||
|
|
||||||
|
|
||||||
class Cursor:
|
class Cursor:
|
||||||
|
|
||||||
def __init__(self, h):
|
def __init__(self, h):
|
||||||
self.h = h
|
self.h = h
|
||||||
self.s = None
|
self.stmnt = None
|
||||||
|
|
||||||
def execute(self, sql):
|
def execute(self, sql):
|
||||||
b = bytearray(4)
|
b = bytearray(4)
|
||||||
sqlite3_prepare(self.h, sql, -1, b, None)
|
s = sqlite3_prepare(self.h, sql, -1, b, None)
|
||||||
self.s = int.from_bytes(b)
|
check_error(self.h, s)
|
||||||
self.num_cols = sqlite3_column_count(self.s)
|
self.stmnt = int.from_bytes(b)
|
||||||
#print("num_cols", self.num_cols)
|
print("stmnt", self.stmnt)
|
||||||
|
self.num_cols = sqlite3_column_count(self.stmnt)
|
||||||
|
print("num_cols", self.num_cols)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
s = sqlite3_finalize(self.stmnt)
|
||||||
|
check_error(self.h, s)
|
||||||
|
|
||||||
def make_row(self):
|
def make_row(self):
|
||||||
res = []
|
res = []
|
||||||
for i in range(self.num_cols):
|
for i in range(self.num_cols):
|
||||||
t = sqlite3_column_type(self.s, i)
|
t = sqlite3_column_type(self.stmnt, i)
|
||||||
#print("type", t)
|
#print("type", t)
|
||||||
if t == SQLITE_INTEGER:
|
if t == SQLITE_INTEGER:
|
||||||
res.append(sqlite3_column_int(self.s, i))
|
res.append(sqlite3_column_int(self.stmnt, i))
|
||||||
elif t == SQLITE_FLOAT:
|
elif t == SQLITE_FLOAT:
|
||||||
res.append(sqlite3_column_double(self.s, i))
|
res.append(sqlite3_column_double(self.stmnt, i))
|
||||||
elif t == SQLITE_TEXT:
|
elif t == SQLITE_TEXT:
|
||||||
res.append(sqlite3_column_text(self.s, i))
|
res.append(sqlite3_column_text(self.stmnt, i))
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
return tuple(res)
|
return tuple(res)
|
||||||
|
|
||||||
def fetchone(self):
|
def fetchone(self):
|
||||||
res = sqlite3_step(self.s)
|
res = sqlite3_step(self.stmnt)
|
||||||
#print("step:", res)
|
#print("step:", res)
|
||||||
if res == SQLITE_DONE:
|
if res == SQLITE_DONE:
|
||||||
return None
|
return None
|
||||||
if res == SQLITE_ROW:
|
if res == SQLITE_ROW:
|
||||||
return self.make_row()
|
return self.make_row()
|
||||||
assert False, res
|
check_error(self.h, res)
|
||||||
|
|
||||||
|
|
||||||
def connect(fname):
|
def connect(fname):
|
||||||
|
|
Ładowanie…
Reference in New Issue