├── BUILD ├── LICENSE.txt ├── README.md ├── sqlite3.c └── test.js /BUILD: -------------------------------------------------------------------------------- 1 | # BUILD 2 | # 3 | # Build with tcc or gcc. 4 | 5 | CC=gcc 6 | # 7 | $CC -g -DJS_SHARED_LIBRARY=1 -fPIC -O2 -c sqlite3.c 8 | $CC -g -shared -o sqlite3.so sqlite3.o -lsqlite3 9 | # 10 | # ce: .mshell; 11 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Fred Weigel 2 | Fred Weigel 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without 7 | restriction, including without limitation the rights to use, 8 | copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | qjs-sqlite3 2 | =========== 3 | 4 | ## What is it? ## 5 | **qjs-sqlite3** is a simple interface to sqlite3 from quickjs 6 | . 7 | 8 | This has only been run on Linux x86_64 (Fedora 31). 9 | 10 | See test.js for simple example and testing. 11 | 12 | ## How to use it? ## 13 | Use new sqlite3_db("db") to get a handle to the open db. 14 | 15 | ``` 16 | import { sqlite3_db } from "./sqlite3.so"; 17 | 18 | db = new sqlite3_db("db); 19 | db.close(); // close db 20 | db.errmsg(); // last error message from sqlite3 21 | st = db.prepare("sql"); // prepare statement 22 | db.exec("sql"); // non-parameter sql 23 | db.last_insert_rowid(); // return last insert rowid 24 | 25 | st.clear_bindings(); // clear bindings 26 | st.reset(); // reset statement 27 | st.finalize(); // finalize (free) statement 28 | st.step(); // step statement (returns "row", "done", "busy", null) 29 | st.bind_parameter_count(); // bind parameter count 30 | st.bind_parameter_name(n); // name for parameter n (1..) 31 | st.bind_parameter_index(name); // index for parameter name 32 | st.bind(n, value); // bind parameter n to value 33 | st.column_count(); // result column count 34 | st.column_name(n); // column name for n (0..) 35 | st.column_text(n); // column n as text 36 | st.column_value(n); // column n value 37 | 38 | ``` 39 | 40 | ## Installation ## 41 | Installing qjs-sqlite3 is easy. 42 | 43 | ``` 44 | $ ./BUILD 45 | ``` 46 | 47 | ## Available imports ## 48 | ``` 49 | import { sqlite3_db } from "./sqlite3.so"; 50 | ``` 51 | 52 | ## Changes ## 53 | 54 | * Wed Feb 12 15:51:56 EST 2020 55 | * initial release 56 | 57 | 58 | ## Limitations ## 59 | 60 | * Small subset of sqlite3 API supported. 61 | * Synchronous interface 62 | 63 | ## TODO ## 64 | 65 | * Needs testing 66 | -------------------------------------------------------------------------------- /sqlite3.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * * 3 | * sqlite3.c * 4 | * * 5 | * For sqlite3 function docs, see: * 6 | * https://www.sqlite.org/c3ref/funclist.html * 7 | * * 8 | **********************************************************************/ 9 | 10 | #define _GNU_SOURCE 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 21 | 22 | static void debug(const char *fmt, ...) { 23 | va_list ap; 24 | va_start(ap, fmt); 25 | vfprintf(stderr, fmt, ap); 26 | va_end(ap); 27 | } 28 | 29 | static void warn(const char *fmt, ...) { 30 | va_list ap; 31 | va_start(ap, fmt); 32 | vfprintf(stderr, fmt, ap); 33 | va_end(ap); 34 | } 35 | 36 | static void fatal(const char *fmt, ...) { 37 | va_list ap; 38 | va_start(ap, fmt); 39 | vfprintf(stderr, fmt, ap); 40 | va_end(ap); 41 | exit(2); 42 | } 43 | 44 | typedef struct { 45 | char *name; 46 | sqlite3 *db; 47 | } sqlite_db; 48 | 49 | static JSClassID db_class_id; 50 | 51 | typedef struct { 52 | sqlite3_stmt *st; 53 | } sqlite_st; 54 | 55 | static JSClassID st_class_id; 56 | 57 | static void st_finalizer(JSRuntime *rt, JSValue val) { 58 | sqlite_st *s = JS_GetOpaque(val, st_class_id); 59 | if (s) { 60 | if (s->st) 61 | sqlite3_finalize(s->st); 62 | js_free_rt(rt, s); 63 | } 64 | } 65 | 66 | static JSValue new_st(JSContext *ctx, sqlite3_stmt *st) { 67 | sqlite_st *s; 68 | JSValue obj; 69 | obj = JS_NewObjectClass(ctx, st_class_id); 70 | if (JS_IsException(obj)) 71 | return obj; 72 | s = js_mallocz(ctx, sizeof(*s)); 73 | if (!s) { 74 | JS_FreeValue(ctx, obj); 75 | return JS_EXCEPTION; 76 | } 77 | s->st = st; 78 | JS_SetOpaque(obj, s); 79 | return obj; 80 | } 81 | 82 | static void db_finalizer(JSRuntime *rt, JSValue val) { 83 | sqlite_db *s = JS_GetOpaque(val, db_class_id); 84 | if (s) { 85 | if (s->db) 86 | sqlite3_close(s->db); 87 | js_free_rt(rt, s); 88 | } 89 | } 90 | 91 | static JSValue db_ctor(JSContext *ctx, JSValueConst new_target, 92 | int argc, JSValueConst *argv) { 93 | sqlite_db *s; 94 | JSValue obj = JS_UNDEFINED; 95 | JSValue proto; 96 | int r; 97 | const char *name; 98 | 99 | s = js_mallocz(ctx, sizeof(*s)); 100 | if (!s) 101 | return JS_EXCEPTION; 102 | name = JS_ToCString(ctx, argv[0]); 103 | if (!name) 104 | goto fail; 105 | proto = JS_GetPropertyStr(ctx, new_target, "prototype"); 106 | if (JS_IsException(proto)) 107 | goto fail; 108 | obj = JS_NewObjectProtoClass(ctx, proto, db_class_id); 109 | JS_FreeValue(ctx, proto); 110 | if (JS_IsException(obj)) 111 | goto fail; 112 | JS_SetOpaque(obj, s); 113 | r = sqlite3_open(name, &(s->db)); 114 | if (r != SQLITE_OK) 115 | goto fail; 116 | JS_FreeCString(ctx, name); 117 | return obj; 118 | fail: 119 | if (name) 120 | JS_FreeCString(ctx, name); 121 | js_free(ctx, s); 122 | JS_FreeValue(ctx, obj); 123 | return JS_EXCEPTION; 124 | } 125 | 126 | static JSValue db_errmsg(JSContext *ctx, JSValueConst this_val, 127 | int argc, JSValueConst *argv) { 128 | sqlite_db *s = JS_GetOpaque2(ctx, this_val, db_class_id); 129 | if (!s) 130 | return JS_EXCEPTION; 131 | if (s->db) 132 | return JS_NewString(ctx, sqlite3_errmsg(s->db)); 133 | else 134 | return JS_EXCEPTION; 135 | } 136 | 137 | static JSValue db_last_insert_rowid(JSContext *ctx, 138 | JSValueConst this_val, 139 | int argc, JSValueConst *argv) { 140 | sqlite_db *s = JS_GetOpaque2(ctx, this_val, db_class_id); 141 | if (!s) 142 | return JS_EXCEPTION; 143 | if (s->db) 144 | return JS_NewInt32(ctx, sqlite3_last_insert_rowid(s->db)); 145 | return JS_EXCEPTION; 146 | } 147 | 148 | static JSValue db_prepare(JSContext *ctx, JSValueConst this_val, 149 | int argc, JSValueConst *argv) { 150 | sqlite_db *s = JS_GetOpaque2(ctx, this_val, db_class_id); 151 | const char *sql; 152 | sqlite3_stmt *t; 153 | int r; 154 | if (!s) 155 | return JS_EXCEPTION; 156 | if (!s->db) 157 | return JS_EXCEPTION; 158 | sql = JS_ToCString(ctx, argv[0]); 159 | if (!sql) 160 | return JS_EXCEPTION; 161 | r = sqlite3_prepare_v2(s->db, sql, strlen(sql) + 1, &t, NULL); 162 | JS_FreeCString(ctx, sql); 163 | if (r != SQLITE_OK) 164 | return JS_NULL; 165 | if (t == NULL) 166 | return JS_NULL; 167 | return new_st(ctx, t); 168 | } 169 | 170 | static JSValue db_exec(JSContext *ctx, JSValueConst this_val, 171 | int argc, JSValueConst *argv) { 172 | sqlite_db *s = JS_GetOpaque2(ctx, this_val, db_class_id); 173 | int r; 174 | const char *sql; 175 | if (!s) 176 | return JS_EXCEPTION; 177 | if (s->db == NULL) 178 | return JS_EXCEPTION; 179 | sql = JS_ToCString(ctx, argv[0]); 180 | if (!sql) 181 | return JS_EXCEPTION; 182 | r = sqlite3_exec(s->db, sql, NULL, NULL, NULL); 183 | JS_FreeCString(ctx, sql); 184 | if (r == SQLITE_OK) 185 | return JS_TRUE; 186 | return JS_FALSE; 187 | } 188 | 189 | static JSValue db_close(JSContext *ctx, JSValueConst this_val, 190 | int argc, JSValueConst *argv) { 191 | sqlite_db *s = JS_GetOpaque2(ctx, this_val, db_class_id); 192 | if (!s) 193 | return JS_EXCEPTION; 194 | if (s->db) { 195 | sqlite3_close(s->db); 196 | s->db = NULL; 197 | } 198 | return JS_UNDEFINED; 199 | } 200 | 201 | static JSValue st_finalize(JSContext *ctx, JSValueConst this_val, 202 | int argc, JSValueConst *argv) { 203 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 204 | sqlite3_stmt *st; 205 | if (!s) 206 | return JS_EXCEPTION; 207 | st = s->st; 208 | s->st = NULL; 209 | if (!st) 210 | return JS_TRUE; 211 | if (sqlite3_finalize(s->st) == SQLITE_OK) 212 | return JS_TRUE; 213 | return JS_FALSE; 214 | } 215 | 216 | static JSValue st_reset(JSContext *ctx, JSValueConst this_val, 217 | int argc, JSValueConst *argv) { 218 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 219 | if (!s) 220 | return JS_EXCEPTION; 221 | if (!s->st) 222 | return JS_EXCEPTION; 223 | if (sqlite3_reset(s->st) == SQLITE_OK) 224 | return JS_TRUE; 225 | return JS_FALSE; 226 | } 227 | 228 | static JSValue st_clear_bindings(JSContext *ctx, JSValueConst this_val, 229 | int argc, JSValueConst *argv) { 230 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 231 | if (!s) 232 | return JS_EXCEPTION; 233 | if (!s->st) 234 | return JS_EXCEPTION; 235 | if (sqlite3_clear_bindings(s->st) == SQLITE_OK) 236 | return JS_TRUE; 237 | return JS_FALSE; 238 | } 239 | 240 | static JSValue st_bind_parameter_count(JSContext *ctx, 241 | JSValueConst this_val, 242 | int argc, JSValueConst *argv) { 243 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 244 | if (!s) 245 | return JS_EXCEPTION; 246 | if (!s->st) 247 | return JS_EXCEPTION; 248 | return JS_NewInt32(ctx, sqlite3_bind_parameter_count(s->st)); 249 | } 250 | 251 | static JSValue st_column_text(JSContext *ctx, JSValueConst this_val, 252 | int argc, JSValueConst *argv) { 253 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 254 | int n; 255 | if (!s) 256 | return JS_EXCEPTION; 257 | if (!s->st) 258 | return JS_EXCEPTION; 259 | if (JS_ToInt32(ctx, &n, argv[0])) 260 | return JS_EXCEPTION; 261 | return JS_NewString(ctx, sqlite3_column_text(s->st, n)); 262 | } 263 | 264 | static JSValue st_column_name(JSContext *ctx, JSValueConst this_val, 265 | int argc, JSValueConst *argv) { 266 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 267 | int n; 268 | if (!s) 269 | return JS_EXCEPTION; 270 | if (!s->st) 271 | return JS_EXCEPTION; 272 | if (JS_ToInt32(ctx, &n, argv[0])) 273 | return JS_EXCEPTION; 274 | return JS_NewString(ctx, sqlite3_column_name(s->st, n)); 275 | } 276 | 277 | static JSValue st_column_count(JSContext *ctx, JSValueConst this_val, 278 | int argc, JSValueConst *argv) { 279 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 280 | if (!s) 281 | return JS_EXCEPTION; 282 | if (!s->st) 283 | return JS_EXCEPTION; 284 | return JS_NewInt32(ctx, sqlite3_column_count(s->st)); 285 | } 286 | 287 | static JSValue st_bind_parameter_name(JSContext *ctx, 288 | JSValueConst this_val, 289 | int argc, JSValueConst *argv) { 290 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 291 | int n; 292 | if (!s) 293 | return JS_EXCEPTION; 294 | if (!s->st) 295 | return JS_EXCEPTION; 296 | if (JS_ToInt32(ctx, &n, argv[0])) 297 | return JS_EXCEPTION; 298 | return JS_NewString(ctx, sqlite3_bind_parameter_name(s->st, n)); 299 | } 300 | 301 | static JSValue st_bind_parameter_index(JSContext *ctx, 302 | JSValueConst this_val, 303 | int argc, JSValueConst *argv) { 304 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 305 | const char *name; 306 | int n; 307 | if (!s) 308 | return JS_EXCEPTION; 309 | if (!s->st) 310 | return JS_EXCEPTION; 311 | name = JS_ToCString(ctx, argv[0]); 312 | if (!name) 313 | return JS_NULL; 314 | n = sqlite3_bind_parameter_index(s->st, name); 315 | JS_FreeCString(ctx, name); 316 | return JS_NewInt32(ctx, n); 317 | } 318 | 319 | static JSValue st_step(JSContext *ctx, JSValueConst this_val, 320 | int argc, JSValueConst *argv) { 321 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 322 | int r; 323 | if (!s) 324 | return JS_EXCEPTION; 325 | if (!s->st) 326 | return JS_EXCEPTION; 327 | r = sqlite3_step(s->st); 328 | switch (r) { 329 | case SQLITE_ROW: 330 | return JS_NewString(ctx, "row"); 331 | case SQLITE_DONE: 332 | return JS_NewString(ctx, "done"); 333 | case SQLITE_BUSY: 334 | return JS_NewString(ctx, "busy"); 335 | default: 336 | return JS_NULL; 337 | } 338 | } 339 | 340 | static JSValue st_column_value(JSContext *ctx, JSValueConst this_val, 341 | int argc, JSValueConst *argv) { 342 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 343 | int n; 344 | if (!s) 345 | return JS_EXCEPTION; 346 | if (!s->st) 347 | return JS_EXCEPTION; 348 | if (JS_ToInt32(ctx, &n, argv[0])) 349 | return JS_EXCEPTION; 350 | switch (sqlite3_column_type(s->st, n)) { 351 | case SQLITE_INTEGER: 352 | return JS_NewInt64(ctx, sqlite3_column_int64(s->st, n)); 353 | case SQLITE_FLOAT: 354 | return JS_NewFloat64(ctx, sqlite3_column_double(s->st, n)); 355 | case SQLITE_BLOB: 356 | return JS_NewArrayBufferCopy(ctx, 357 | (uint8_t *)sqlite3_column_blob(s->st, n), 358 | (size_t)sqlite3_column_bytes(s->st, n)); 359 | case SQLITE_NULL: 360 | return JS_NULL; 361 | case SQLITE3_TEXT: 362 | default: 363 | return JS_NewString(ctx, sqlite3_column_text(s->st, n)); 364 | } 365 | return JS_EXCEPTION; 366 | } 367 | 368 | static inline JS_BOOL JS_IsInteger(JSValueConst v) { 369 | int tag = JS_VALUE_GET_TAG(v); 370 | return tag == JS_TAG_INT || tag == JS_TAG_BIG_INT; 371 | } 372 | 373 | static JSValue st_bind(JSContext *ctx, JSValueConst this_val, 374 | int argc, JSValueConst *argv) { 375 | sqlite_st *s = JS_GetOpaque2(ctx, this_val, st_class_id); 376 | JSValueConst a; 377 | int n, r; 378 | if (!s) 379 | return JS_EXCEPTION; 380 | if (!s->st) 381 | return JS_EXCEPTION; 382 | if (JS_ToInt32(ctx, &n, argv[0])) 383 | return JS_EXCEPTION; 384 | a = argv[1]; 385 | if (JS_IsNull(a)) { 386 | r = sqlite3_bind_null(s->st, n); 387 | } else if (JS_IsBool(a)) { 388 | int b = JS_ToBool(ctx, a); 389 | r = sqlite3_bind_int(s->st, n, b); 390 | } else if (JS_IsInteger(a)) { 391 | int64_t i64; 392 | int i; 393 | double d; 394 | if (!JS_ToInt32(ctx, &i, a)) { 395 | r = sqlite3_bind_int(s->st, n, i); 396 | } if (!JS_ToInt64(ctx, &i64, a)) { 397 | r = sqlite3_bind_int64(s->st, n, i64); 398 | } else if (JS_ToFloat64(ctx, &d, a)) { 399 | return JS_EXCEPTION; 400 | } else { 401 | r = sqlite3_bind_double(s->st, n, d); 402 | } 403 | } else if (JS_IsNumber(a)) { 404 | double d; 405 | if (JS_ToFloat64(ctx, &d, a)) 406 | return JS_EXCEPTION; 407 | r = sqlite3_bind_double(s->st, n, d); 408 | } else if (JS_IsString(a)) { 409 | const char *t; 410 | t = JS_ToCString(ctx, a); 411 | r = sqlite3_bind_text(s->st, n, t, strlen(t), SQLITE_TRANSIENT); 412 | JS_FreeCString(ctx, t); 413 | } else { 414 | uint8_t *buf; 415 | size_t size; 416 | buf = JS_GetArrayBuffer(ctx, &size, a); 417 | if (!buf) 418 | return JS_EXCEPTION; 419 | r = sqlite3_bind_blob(s->st, n, buf, size, SQLITE_TRANSIENT); 420 | } 421 | return JS_NewInt32(ctx, r); 422 | } 423 | 424 | static JSClassDef db_class = { 425 | "sqlite3_db", 426 | .finalizer = db_finalizer, 427 | }; 428 | 429 | static const JSCFunctionListEntry db_proto_funcs[] = { 430 | JS_CFUNC_DEF("exec", 1, db_exec), 431 | JS_CFUNC_DEF("prepare", 0, db_prepare), 432 | JS_CFUNC_DEF("last_insert_rowid", 0, db_last_insert_rowid), 433 | JS_CFUNC_DEF("errmsg", 0, db_errmsg), 434 | JS_CFUNC_DEF("close", 0, db_close), 435 | }; 436 | 437 | static const JSCFunctionListEntry st_proto_funcs[] = { 438 | JS_CFUNC_DEF("column_value", 1, st_column_value), 439 | JS_CFUNC_DEF("column_text", 1, st_column_text), 440 | JS_CFUNC_DEF("column_name", 1, st_column_name), 441 | JS_CFUNC_DEF("column_count", 0, st_column_count), 442 | JS_CFUNC_DEF("bind", 2, st_bind), 443 | JS_CFUNC_DEF("bind_parameter_index", 1, st_bind_parameter_index), 444 | JS_CFUNC_DEF("bind_parameter_name", 1, st_bind_parameter_name), 445 | JS_CFUNC_DEF("bind_parameter_count", 0, st_bind_parameter_count), 446 | JS_CFUNC_DEF("step", 0, st_step), 447 | JS_CFUNC_DEF("finalize", 0, st_finalize), 448 | JS_CFUNC_DEF("reset", 0, st_reset), 449 | JS_CFUNC_DEF("clear_bindings", 0, st_clear_bindings), 450 | }; 451 | 452 | static JSClassDef st_class = { 453 | "sqlite3_st", 454 | .finalizer = st_finalizer, 455 | }; 456 | 457 | static int st_init(JSContext *ctx, JSModuleDef *m) { 458 | JSValue proto; 459 | JS_NewClassID(&st_class_id); 460 | JS_NewClass(JS_GetRuntime(ctx), st_class_id, &st_class); 461 | proto = JS_NewObject(ctx); 462 | JS_SetPropertyFunctionList(ctx, proto, st_proto_funcs, 463 | countof(st_proto_funcs)); 464 | JS_SetClassProto(ctx, st_class_id, proto); 465 | return 0; 466 | } 467 | 468 | static int db_init(JSContext *ctx, JSModuleDef *m) { 469 | JSValue proto, class; 470 | st_init(ctx, m); 471 | JS_NewClassID(&db_class_id); 472 | JS_NewClass(JS_GetRuntime(ctx), db_class_id, &db_class); 473 | proto = JS_NewObject(ctx); 474 | JS_SetPropertyFunctionList(ctx, proto, db_proto_funcs, 475 | countof(db_proto_funcs)); 476 | JS_SetClassProto(ctx, db_class_id, proto); 477 | class = JS_NewCFunction2(ctx, db_ctor, "sqlite3_db", 2, 478 | JS_CFUNC_constructor, 0); 479 | JS_SetConstructor(ctx, class, proto); 480 | JS_SetModuleExport(ctx, m, "sqlite3_db", class); 481 | return 0; 482 | } 483 | 484 | #ifdef JS_SHARED_LIBRARY 485 | #define JS_INIT_MODULE js_init_module 486 | #else 487 | #define JS_INIT_MODULE js_init_module_sqlite3 488 | #endif 489 | 490 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) { 491 | JSModuleDef *m; 492 | m = JS_NewCModule(ctx, module_name, db_init); 493 | if (!m) 494 | return NULL; 495 | JS_AddModuleExport(ctx, m, "sqlite3_db"); 496 | return m; 497 | } 498 | 499 | /* ce: .mc; */ 500 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /* test.js 2 | */ 3 | 4 | import * as std from "std"; 5 | import * as os from "os"; 6 | import { sqlite3_db } from "./sqlite3.so"; 7 | 8 | console.log("sqlite3 test"); 9 | 10 | var db = new sqlite3_db("testdb"); 11 | 12 | if (!db.exec("create table t (a, b, c);")) 13 | console.log(db.errmsg()); 14 | 15 | var st = db.prepare("insert into t (a, b, c) values (1, 2, 3);"); 16 | console.log("bind parameter count = " + st.bind_parameter_count()); 17 | var s; 18 | s = st.step(); 19 | console.log("step result = " + s); // "row" "done" "busy" null 20 | st.reset(); 21 | st.clear_bindings(); 22 | st.finalize(); 23 | console.log("last insert rowid = " + db.last_insert_rowid()); 24 | 25 | st = db.prepare("insert into t (a, b, c) values (?1, ?2, ?3);"); 26 | console.log("bind parameter count = " + st.bind_parameter_count()); 27 | /* distinctly 1 based */ 28 | console.log(st.bind_parameter_name(1)); 29 | console.log(st.bind_parameter_index("?2")); 30 | console.log(st.column_count()); 31 | st.bind(1, null); 32 | st.bind(2, null); 33 | st.bind(3, null); 34 | st.finalize(); 35 | 36 | console.log("select"); 37 | st = db.prepare("select * from t;"); 38 | st.step(); 39 | console.log(st.column_count()); 40 | var i; 41 | console.log("begin column names..."); 42 | /* zero based - and see above bind parameter indices */ 43 | for (i = 0; i < st.column_count(); ++i) { 44 | console.log(st.column_name(i)); 45 | } 46 | console.log("... end column names"); 47 | st.reset(); 48 | while ((s = st.step()) == "row") { 49 | console.log("row", st.column_value(0), st.column_value(1), 50 | st.column_value(2)); 51 | } 52 | console.log(s); 53 | st.finalize(); 54 | 55 | db.close(); 56 | --------------------------------------------------------------------------------