static int clear_timer(duk_context *duk) { es_timer_t *et = es_resource_get(duk, 0, &es_resource_timer); es_resource_destroy(&et->super); return 0; }
static int es_db_last_insert_row_id(duk_context *ctx) { es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); duk_push_uint(ctx, sqlite3_last_insert_rowid(es->es_db)); return 1; }
static int es_db_last_error_str(duk_context *ctx) { es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); duk_push_string(ctx, sqlite3_errmsg(es->es_db)); return 1; }
static int es_db_changes(duk_context *ctx) { es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); duk_push_int(ctx, sqlite3_changes(es->es_db)); return 1; }
static es_fd_t * es_fd_get(duk_context *ctx, int idx) { es_fd_t *efd = es_resource_get(ctx, idx, &es_resource_fd); if(efd->efd_fh == NULL) duk_error(ctx, DUK_ERR_ERROR, "Filehandle for %s is closed", efd->efd_path); return efd; }
static int es_db_upgrade_schema(duk_context *ctx) { es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); int r = db_upgrade_schema(es->es_db, duk_safe_to_string(ctx, 1), es->es_name, NULL, NULL); if(r) duk_error(ctx, DUK_ERR_ERROR, "Unable to upgrade schema"); return 0; }
static int es_sqlite_query(duk_context *ctx) { int argc = duk_get_top(ctx); if(argc < 2) return DUK_RET_TYPE_ERROR; es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); const char *query = duk_safe_to_string(ctx, 1); if(es->es_stmt) { sqlite3_finalize(es->es_stmt); es->es_stmt = NULL; } int rc = db_prepare(es->es_db, &es->es_stmt, query); if(rc != SQLITE_OK) { if(es->es_transaction && rc == SQLITE_LOCKED) duk_error(ctx, ST_ERROR_SQLITE_BASE | rc , "Deadlock"); duk_error(ctx, ST_ERROR_SQLITE_BASE | rc, "Sqlite error 0x%x -- %s", rc, sqlite3_errmsg(es->es_db)); } sqlite3_stmt *stmt = es->es_stmt; for(int i = 2; i < argc; i++) { int sqlite_arg = i - 1; if(duk_is_null_or_undefined(ctx, i)) { sqlite3_bind_null(stmt, sqlite_arg); } else if(duk_is_number(ctx, i)) { sqlite3_bind_double(stmt, sqlite_arg, duk_get_number(ctx, i)); } else if(duk_is_boolean(ctx, i)) { sqlite3_bind_int(stmt, sqlite_arg, duk_get_boolean(ctx, i)); } else { sqlite3_bind_text(stmt, sqlite_arg, duk_safe_to_string(ctx, i), -1, SQLITE_STATIC); } } es_sqlite_stmt_step(ctx, es); return 0; }
static int es_sqlite_step(duk_context *ctx) { es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); if(es->es_stmt == NULL) { duk_push_null(ctx); return 1; } const int cols = sqlite3_data_count(es->es_stmt); duk_push_object(ctx); for(int i = 0; i < cols; i++) { int64_t i64; switch(sqlite3_column_type(es->es_stmt, i)) { case SQLITE_INTEGER: i64 = sqlite3_column_int64(es->es_stmt, i); if(i64 >= INT32_MIN && i64 <= INT32_MAX) duk_push_int(ctx, i64); else if(i64 >= 0 && i64 <= UINT32_MAX) duk_push_uint(ctx, i64); else duk_push_number(ctx, i64); break; case SQLITE_TEXT: duk_push_string(ctx, (const char *)sqlite3_column_text(es->es_stmt, i)); break; case SQLITE_FLOAT: duk_push_number(ctx, sqlite3_column_double(es->es_stmt, i)); break; default: continue; } duk_put_prop_string(ctx, -2, sqlite3_column_name(es->es_stmt, i)); } es_sqlite_stmt_step(ctx, es); return 1; }