├── 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 |
--------------------------------------------------------------------------------