Skip to content

Commit 4a249da

Browse files
committed
Ad supprort for parameter binding to prepered statements.
Still need to add support for freeing memory before it's usefull in the real world.
1 parent f91ca55 commit 4a249da

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ EMSCRIPTEN?=/usr/bin
44
EMCC=$(EMSCRIPTEN)/emcc -s RESERVED_FUNCTION_POINTERS=2 --closure 1 -O3 -s INLINING_LIMIT=10
55
CC=clang -O2
66
CFLAGS=-DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DISABLE_LFS -DLONGDOUBLE_TYPE=double -DSQLITE_INT64_TYPE="long long int" -DSQLITE_THREADSAFE=0
7-
EXPORTED_FUNCTIONS="['_sqlite3_open', '_sqlite3_close', '_sqlite3_exec', '_sqlite3_free', '_sqlite3_data_count', '_sqlite3_column_type', '_sqlite3_column_text', '_sqlite3_column_double', '_sqlite3_prepare_v2', '_sqlite3_step']"
7+
EXPORTED_FUNCTIONS="['_sqlite3_open', '_sqlite3_close', '_sqlite3_exec', '_sqlite3_free', '_sqlite3_data_count', '_sqlite3_column_type', '_sqlite3_column_text', '_sqlite3_column_double', '_sqlite3_prepare_v2', '_sqlite3_step', '_sqlite3_bind_text', '_sqlite3_bind_double']"
88

99

1010
all: js/sql.js test/benchmark.js test/benchmark

README.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@ var sql = require('./js/sql-api.js');
1616
var db = new sql.Database();
1717

1818
// Execute some sql
19-
db.exec("CREATE TABLE hello (a int, b char); INSERT INTO hello VALUES (0, 'world');");
19+
sqlstr = "CREATE TABLE hello (a int, b char);";
20+
sqlstr += "INSERT INTO hello VALUES (0, 'hello');"
21+
sqlstr += "INSERT INTO hello VALUES (1, 'world');"
22+
db.exec(sqlstr);
2023

2124
// Prepare an sql statement
22-
var stmt = db.prepare("SELECT * FROM hello")
25+
var stmt = db.prepare("SELECT * FROM hello WHERE a=? AND b=?");
2326

24-
// Fetch the results of the query
25-
while (stmt.step()) console.log(stmt.get()); // Will print [0, 'world']
27+
// Bind values to the parameters
28+
stmt.bind([1, 'world']);
2629

27-
// stmt.bind support is coming...
30+
// Fetch the results of the query
31+
while (stmt.step()) console.log(stmt.get()); // Will print [1, 'world']
2832
```
2933

3034
## Differences from the original sql.js

js/api.coffee

+34-6
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,37 @@ callbackTemp = Runtime.addFunction (notUsed, argc, argv, colNames) ->
2929

3030
class Statement
3131
constructor: (@stmt) ->
32+
@pos = 1 # Index of the leftmost parameter is 1
3233
step: ->
34+
@pos = 1
3335
ret = sqlite3_step @stmt
3436
if ret is SQLite.ROW then return true
3537
else if ret is SQLite.DONE then return false
3638
else throw 'SQLite error: ' + handleErrors ret
37-
getNumber: (pos) ->
38-
return sqlite3_column_double @stmt, pos
39-
getString: (pos) ->
40-
return sqlite3_column_text @stmt, pos
39+
getNumber: (pos = @pos++) -> sqlite3_column_double @stmt, pos
40+
getString: (pos = @pos++) -> sqlite3_column_text @stmt, pos
4141
get: -> # Get all fields
4242
for field in [0 ... sqlite3_data_count(@stmt)]
4343
type = sqlite3_column_type @stmt, field
4444
if type in [SQLite.INTEGER, SQLite.FLOAT] then @getNumber field
4545
else if type in [SQLite.TEXT, SQLite.BLOB] then @getString field
4646
else null
47+
bindString: (string, pos = @pos++) ->
48+
ret = sqlite3_bind_text @stmt, pos, string, -1, NULL
49+
err = handleErrors ret
50+
if err isnt null then throw 'SQLite error : ' + err
51+
bindNumber: (num, pos = @pos++) ->
52+
ret = sqlite3_bind_double @stmt, pos, num
53+
err = handleErrors ret
54+
if err isnt null then throw 'SQLite error : ' + err
55+
bindValue: (val, pos = @pos++) ->
56+
switch typeof val
57+
when "string" then @bindString val, pos
58+
when "number" then @bindNumber val, pos
59+
# Not binding a parameter is the same as binding it to NULL
60+
bind : (values) ->
61+
@bindValue v,i+1 for v,i in values # Index of the leftmost parameter is 1
62+
null
4763

4864
class Database
4965
# Open a new database:
@@ -96,9 +112,21 @@ sqlite3_open = Module.cwrap 'sqlite3_open', 'number', ['string', 'number']
96112
sqlite3_close = Module.cwrap 'sqlite3_close', 'number', ['number'];
97113
sqlite3_exec = Module.cwrap 'sqlite3_exec', 'number', ['number', 'string', 'number', 'number', 'number']
98114
sqlite3_free = Module.cwrap 'sqlite3_free', '', ['number']
115+
116+
# Prepared statements
117+
## prepare
99118
sqlite3_prepare_v2 = Module.cwrap 'sqlite3_prepare_v2', 'number', ['number', 'string', 'number', 'number', 'number']
100-
sqlite3_step = Module.cwrap 'sqlite3_step', 'number', ['number'] # int sqlite3_step(sqlite3_stmt*)
101-
sqlite3_data_count = Module.cwrap 'sqlite3_data_count', 'number', ['number'] # int sqlite3_data_count(sqlite3_stmt *pStmt);
119+
## Bind parameters
120+
#int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
121+
sqlite3_bind_text = Module.cwrap 'sqlite3_bind_text', 'number', ['number', 'number', 'string', 'number', 'number']
122+
#int sqlite3_bind_double(sqlite3_stmt*, int, double);
123+
sqlite3_bind_double = Module.cwrap 'sqlite3_bind_double', 'number', ['number', 'number', 'number']
124+
125+
## Get values
126+
# int sqlite3_step(sqlite3_stmt*)
127+
sqlite3_step = Module.cwrap 'sqlite3_step', 'number', ['number']
128+
# int sqlite3_data_count(sqlite3_stmt *pStmt);
129+
sqlite3_data_count = Module.cwrap 'sqlite3_data_count', 'number', ['number']
102130
sqlite3_column_double = Module.cwrap 'sqlite3_column_double', 'number', ['number', 'number']
103131
sqlite3_column_text = Module.cwrap 'sqlite3_column_text', 'string', ['number', 'number']
104132
sqlite3_column_type = Module.cwrap 'sqlite3_column_type', 'number', ['number', 'number']

0 commit comments

Comments
 (0)