Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 243 additions & 28 deletions README.md

Large diffs are not rendered by default.

11 changes: 0 additions & 11 deletions micropython.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Create an INTERFACE library for our C module.
add_library(usermod_usqlite INTERFACE)

# Add our source files to the lib
target_sources(usermod_usqlite INTERFACE
${CMAKE_CURRENT_LIST_DIR}/usqlite_module.c
${CMAKE_CURRENT_LIST_DIR}/usqlite_connection.c
Expand All @@ -14,17 +12,8 @@ target_sources(usermod_usqlite INTERFACE
${CMAKE_CURRENT_LIST_DIR}/usqlite.c
)

if(IDF_TARGET MATCHES "^esp32")
target_compile_options(usermod_usqlite INTERFACE
-mtext-section-literals
)
endif()


# Add the current directory as an include directory.
target_include_directories(usermod_usqlite INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)

# Link our INTERFACE library to the usermod target.
target_link_libraries(usermod INTERFACE usermod_usqlite)
18 changes: 10 additions & 8 deletions usqlite.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,32 @@ SOFTWARE.
#endif

#ifdef SQLITE_OMIT_ANALYZE
SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2) {
SQLITE_PRIVATE void sqlite3Analyze(Parse* pParse, Token* pName1, Token* pName2) {
}

#if __GNUC__
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDB) {
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3* db, int iDB) {
return SQLITE_OK;
}
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx) {
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3* db, Index* pIdx) {
}
#endif
#endif

#ifdef SQLITE_OMIT_ATTACH
SQLITE_PRIVATE void sqlite3Vacuum(Parse *p, Token *t, Expr *e) {
SQLITE_PRIVATE void sqlite3Vacuum(Parse* p, Token* t, Expr* e) {
}
SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName) {
SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3* db, int iDb, const char* zName) {
return 0;
}
SQLITE_PRIVATE void sqlite3Attach(Parse *p, Expr *e1, Expr *e2, Expr *e3) {
SQLITE_PRIVATE void sqlite3Attach(Parse* p, Expr* e1, Expr* e2, Expr* e3) {
}
SQLITE_PRIVATE void sqlite3Detach(Parse *p, Expr *e) {
SQLITE_PRIVATE void sqlite3Detach(Parse* p, Expr* e) {
}

#ifdef __GNUC__
SQLITE_PRIVATE int sqlite3RunVacuum(char **c, sqlite3 *db, int i, sqlite3_value *v) {
SQLITE_PRIVATE int sqlite3RunVacuum(char** c, sqlite3* db, int i, sqlite3_value* v) {
return SQLITE_OK;
}
#endif
#endif
Expand Down
113 changes: 60 additions & 53 deletions usqlite_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ static mp_obj_t usqlite_connection_close(mp_obj_t self_in);

// ------------------------------------------------------------------------------

static mp_obj_t usqlite_connection_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
usqlite_connection_t *self = m_new_obj(usqlite_connection_t);
static mp_obj_t usqlite_connection_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
usqlite_connection_t* self = m_new_obj(usqlite_connection_t);

self->base.type = &usqlite_connection_type;
self->db = (sqlite3 *)MP_OBJ_TO_PTR(args[0]);
self->db = (sqlite3*)MP_OBJ_TO_PTR(args[0]);
self->row_type = MP_QSTR_tuple;
mp_obj_list_init(&self->cursors, 0);

Expand All @@ -45,8 +45,8 @@ static mp_obj_t usqlite_connection_make_new(const mp_obj_type_t *type, size_t n_

// ------------------------------------------------------------------------------

static void usqlite_connection_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
usqlite_connection_t *self = MP_OBJ_TO_PTR(self_in);
static void usqlite_connection_print(const mp_print_t* print, mp_obj_t self_in, mp_print_kind_t kind) {
usqlite_connection_t* self = MP_OBJ_TO_PTR(self_in);

mp_printf(print, "<%s '%s'>", mp_obj_get_type_str(self_in), self->db ? sqlite3_db_filename(self->db, NULL) : "");
}
Expand All @@ -61,17 +61,20 @@ static mp_obj_t usqlite_connection_close(mp_obj_t self_in) {
return mp_const_none;
}

for (size_t i = 0; i < self->cursors.len; i++)
// Safely close all cursors.
// Since calling usqlite_cursor_close() now REMOVES the item from the list,
// we just keep closing the first item until the list is empty.
while (self->cursors.len > 0)
{
mp_obj_t cursor = self->cursors.items[i];
self->cursors.items[0] = mp_const_none;
// Get the first cursor
mp_obj_t cursor = self->cursors.items[0];

// This call will close it AND remove it from self->cursors, reducing len by 1
usqlite_cursor_close(cursor);
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
m_free(MP_OBJ_TO_PTR(cursor), sizeof(usqlite_cursor_t));
#else
m_free(MP_OBJ_TO_PTR(cursor));
#endif
}

// List is now empty
self->cursors.len = 0;

usqlite_logprintf(___FUNC___ " closing '%s'\n", sqlite3_db_filename(self->db, NULL));
sqlite3_close(self->db);
Expand All @@ -97,27 +100,27 @@ MP_DEFINE_CONST_FUN_OBJ_1(usqlite_connection_del_obj, usqlite_connection_del);
// ------------------------------------------------------------------------------

static mp_obj_t usqlite_connection_cursor(mp_obj_t self_in) {
usqlite_connection_t *self = MP_OBJ_TO_PTR(self_in);
usqlite_connection_t* self = MP_OBJ_TO_PTR(self_in);

mp_obj_t args[2] =
{
MP_OBJ_FROM_PTR(self),
mp_const_none
};

#if defined(MP_OBJ_TYPE_GET_SLOT)
#if defined(MP_OBJ_TYPE_GET_SLOT)
return MP_OBJ_TYPE_GET_SLOT(&usqlite_cursor_type, make_new)(NULL, MP_ARRAY_SIZE(args), 0, args);
#else
#else
return usqlite_cursor_type.make_new(NULL, MP_ARRAY_SIZE(args), 0, args);
#endif
#endif
}

static MP_DEFINE_CONST_FUN_OBJ_1(usqlite_connection_cursor_obj, usqlite_connection_cursor);

// ------------------------------------------------------------------------------

static mp_obj_t usqlite_connection_execute(size_t n_args, const mp_obj_t *args) {
usqlite_connection_t *self = MP_OBJ_TO_PTR(args[0]);
static mp_obj_t usqlite_connection_execute(size_t n_args, const mp_obj_t* args) {
usqlite_connection_t* self = MP_OBJ_TO_PTR(args[0]);

mp_obj_t xargs[4] =
{
Expand All @@ -133,19 +136,19 @@ static mp_obj_t usqlite_connection_execute(size_t n_args, const mp_obj_t *args)
nxargs++;
}

#if defined(MP_OBJ_TYPE_GET_SLOT)
#if defined(MP_OBJ_TYPE_GET_SLOT)
return MP_OBJ_TYPE_GET_SLOT(&usqlite_cursor_type, make_new)(NULL, nxargs, 0, xargs);
#else
#else
return usqlite_cursor_type.make_new(NULL, nxargs, 0, xargs);
#endif
#endif
}

static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(usqlite_connection_execute_obj, 2, 3, usqlite_connection_execute);

// ------------------------------------------------------------------------------

static mp_obj_t usqlite_connection_executemany(mp_obj_t self_in, mp_obj_t sql) {
usqlite_connection_t *self = MP_OBJ_TO_PTR(self_in);
usqlite_connection_t* self = MP_OBJ_TO_PTR(self_in);

mp_obj_t args[3] =
{
Expand All @@ -154,42 +157,45 @@ static mp_obj_t usqlite_connection_executemany(mp_obj_t self_in, mp_obj_t sql) {
sql
};

#if defined(MP_OBJ_TYPE_GET_SLOT)
#if defined(MP_OBJ_TYPE_GET_SLOT)
return MP_OBJ_TYPE_GET_SLOT(&usqlite_cursor_type, make_new)(NULL, MP_ARRAY_SIZE(args), 0, args);
#else
#else
return usqlite_cursor_type.make_new(NULL, MP_ARRAY_SIZE(args), 0, args);
#endif
#endif
}

static MP_DEFINE_CONST_FUN_OBJ_2(usqlite_connection_executemany_obj, usqlite_connection_executemany);

// ------------------------------------------------------------------------------

static int traceCallback(unsigned uMask, void *context, void *p, void *x) {
usqlite_connection_t *self = (usqlite_connection_t *)context;
sqlite3_stmt *stmt = (sqlite3_stmt *)p;
char *xsql = sqlite3_expanded_sql(stmt);
static int traceCallback(unsigned uMask, void* context, void* p, void* x) {
usqlite_connection_t* self = (usqlite_connection_t*)context;
sqlite3_stmt* stmt = (sqlite3_stmt*)p;
char* xsql = sqlite3_expanded_sql(stmt);
if (xsql) {
mp_call_function_1(self->trace_callback, mp_obj_new_str(xsql, strlen(xsql)));
sqlite3_free(xsql);
} else {
const char *sql = sqlite3_sql(stmt);
}
else {
const char* sql = sqlite3_sql(stmt);
mp_call_function_1(self->trace_callback, mp_obj_new_str(sql, strlen(sql)));
}

return 0;
}

static mp_obj_t usqlite_connection_set_trace_callback(mp_obj_t self_in, mp_obj_t callback) {
usqlite_connection_t *self = MP_OBJ_TO_PTR(self_in);
usqlite_connection_t* self = MP_OBJ_TO_PTR(self_in);

if (callback == mp_const_none) {
self->trace_callback = mp_const_none;
sqlite3_trace_v2(self->db, 0, NULL, NULL);
} else if (mp_obj_is_callable(callback)) {
}
else if (mp_obj_is_callable(callback)) {
self->trace_callback = callback;
sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, traceCallback, self);
} else {
}
else {
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid callback"));
}

Expand All @@ -200,22 +206,22 @@ static MP_DEFINE_CONST_FUN_OBJ_2(usqlite_connection_set_trace_callback_obj, usql

// ------------------------------------------------------------------------------

void usqlite_connection_register(usqlite_connection_t *connection, mp_obj_t cursor) {
void usqlite_connection_register(usqlite_connection_t* connection, mp_obj_t cursor) {
mp_obj_t cursors = MP_OBJ_FROM_PTR(&connection->cursors);
mp_obj_list_append(cursors, cursor);
}

// ------------------------------------------------------------------------------

void usqlite_connection_deregister(usqlite_connection_t *connection, mp_obj_t cursor) {
void usqlite_connection_deregister(usqlite_connection_t* connection, mp_obj_t cursor) {
mp_obj_t cursors = MP_OBJ_FROM_PTR(&connection->cursors);
mp_obj_list_remove(cursors, cursor);
}

// ------------------------------------------------------------------------------

static void usqlite_connection_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
usqlite_connection_t *self = (usqlite_connection_t *)self_in;
static void usqlite_connection_attr(mp_obj_t self_in, qstr attr, mp_obj_t* dest) {
usqlite_connection_t* self = (usqlite_connection_t*)self_in;

if (dest[0] == MP_OBJ_NULL) {
if ((usqlite_lookup(self_in, attr, dest))) {
Expand All @@ -224,21 +230,22 @@ static void usqlite_connection_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest)

switch (attr)
{
case MP_QSTR_row_type:
dest[0] = MP_OBJ_NEW_QSTR(self->row_type);
break;
case MP_QSTR_row_type:
dest[0] = MP_OBJ_NEW_QSTR(self->row_type);
break;

case MP_QSTR_total_changes:
dest[0] = mp_obj_new_int(sqlite3_total_changes(self->db));
break;
case MP_QSTR_total_changes:
dest[0] = mp_obj_new_int(sqlite3_total_changes(self->db));
break;
}
} else if (dest[1] != MP_OBJ_NULL) {
}
else if (dest[1] != MP_OBJ_NULL) {
switch (attr)
{
case MP_QSTR_row_type:
self->row_type = mp_obj_str_get_qstr(dest[1]);
dest[0] = MP_OBJ_NULL;
break;
case MP_QSTR_row_type:
self->row_type = mp_obj_str_get_qstr(dest[1]);
dest[0] = MP_OBJ_NULL;
break;
}

// delete/store attribute
Expand All @@ -247,7 +254,7 @@ static void usqlite_connection_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest)

// ------------------------------------------------------------------------------

static mp_obj_t usqlite_connection_exit(size_t n_args, const mp_obj_t *args) {
static mp_obj_t usqlite_connection_exit(size_t n_args, const mp_obj_t* args) {
usqlite_logprintf(___FUNC___ "\n");

usqlite_connection_close(args[0]);
Expand Down Expand Up @@ -285,15 +292,15 @@ MP_DEFINE_CONST_OBJ_TYPE(
print, usqlite_connection_print,
attr, usqlite_connection_attr,
locals_dict, &usqlite_connection_locals_dict
);
);
#else
const mp_obj_type_t usqlite_connection_type =
{
{ &mp_type_type },
.name = MP_QSTR_Connection,
.print = usqlite_connection_print,
.make_new = usqlite_connection_make_new,
.locals_dict = (mp_obj_dict_t *)&usqlite_connection_locals_dict,
.locals_dict = (mp_obj_dict_t*)&usqlite_connection_locals_dict,
.attr = usqlite_connection_attr,
};
#endif
Expand Down
Loading