2
2
3
3
apiTemp = Runtime .stackAlloc (4 );
4
4
5
- SQLite = {
6
- # Constants are defined below
7
- errorMessages : [] # Will contain all SQLite error descriptions sorted by error codes
8
- };
5
+ # Constants are defined in api-data.coffee
6
+ SQLite = {};
9
7
10
8
### Represents an prepared statement.
11
9
@@ -25,7 +23,7 @@ class Statement
25
23
# Statements can't be created by the API user, only by Database::prepare
26
24
# @private
27
25
# @nodoc
28
- constructor : (@stmt ) ->
26
+ constructor : (@stmt , @db ) ->
29
27
@pos = 1 # Index of the leftmost parameter is 1
30
28
@allocatedmem = [] # Pointers to allocated memory, that need to be freed when the statemend is destroyed
31
29
@@ -79,10 +77,10 @@ class Statement
79
77
' step ' : ->
80
78
if not @stmt then throw " Statement closed"
81
79
@pos = 1
82
- ret = sqlite3_step @stmt
83
- if ret is SQLite .ROW then return true
84
- else if ret is SQLite .DONE then return false
85
- else throw ' SQLite error: ' + handleErrors ret
80
+ switch ret = sqlite3_step @stmt
81
+ when SQLite .ROW then return true
82
+ when SQLite .DONE then return false
83
+ else @db . handleError ret
86
84
87
85
# Internal methods to retrieve data from the results of a statement that has been executed
88
86
# @nodoc
@@ -161,25 +159,22 @@ class Statement
161
159
bindString : (string , pos = @pos ++ ) ->
162
160
bytes = intArrayFromString (string)
163
161
@allocatedmem .push strptr = allocate bytes, ' i8' , ALLOC_NORMAL
164
- ret = sqlite3_bind_text @stmt , pos, strptr, bytes .length , 0
165
- if ret is SQLite .OK then return true
166
- err = handleErrors ret
167
- if err isnt null then throw ' SQLite error : ' + err
162
+ @db .handleError sqlite3_bind_text @stmt , pos, strptr, bytes .length , 0
163
+ return true
164
+
168
165
# @nodoc
169
166
bindBlob : (array , pos = @pos ++ ) ->
170
167
@allocatedmem .push blobptr = allocate array, ' i8' , ALLOC_NORMAL
171
- ret = sqlite3_bind_blob @stmt , pos, blobptr, array .length , 0
172
- if ret is SQLite .OK then return true
173
- err = handleErrors ret
174
- if err isnt null then throw ' SQLite error : ' + err
168
+ @db .handleError sqlite3_bind_blob @stmt , pos, blobptr, array .length , 0
169
+ return true
170
+
175
171
# @private
176
172
# @nodoc
177
173
bindNumber : (num , pos = @pos ++ ) ->
178
174
bindfunc = if num is (num| 0 ) then sqlite3_bind_int else sqlite3_bind_double
179
- ret = bindfunc @stmt , pos, num
180
- if ret is SQLite .OK then return true
181
- err = handleErrors ret
182
- if err isnt null then throw ' SQLite error : ' + err
175
+ @db .handleError bindfunc @stmt , pos, num
176
+ return true
177
+
183
178
# @nodoc
184
179
bindNull : (pos = @pos ++ ) -> sqlite3_bind_blob (@stmt , pos, 0 ,0 ,0 ) is SQLite .OK
185
180
# Call bindNumber or bindString appropriatly
@@ -217,8 +212,8 @@ class Statement
217
212
###
218
213
' reset ' : ->
219
214
@ freemem ()
220
- sqlite3_reset (@stmt ) is SQLite .OK and
221
- sqlite3_clear_bindings (@stmt ) is SQLite .OK
215
+ sqlite3_clear_bindings (@stmt ) is SQLite .OK and
216
+ sqlite3_reset (@stmt ) is SQLite .OK
222
217
223
218
### Free the memory allocated during parameter binding
224
219
###
@@ -243,8 +238,7 @@ class Database
243
238
constructor : (data ) ->
244
239
@filename = ' dbfile_' + (0xffffffff * Math .random ()>>> 0 )
245
240
if data? then FS .createDataFile ' /' , @filename , data, true , true
246
- ret = sqlite3_open @filename , apiTemp
247
- if ret isnt SQLite .OK then throw ' SQLite error: ' + SQLite .errorMessages [ret]
241
+ @ handleError sqlite3_open @filename , apiTemp
248
242
@db = getValue (apiTemp, ' i32' )
249
243
@statements = [] # A list of all prepared statements of the database
250
244
@@ -268,9 +262,7 @@ class Database
268
262
stmt[' step' ]()
269
263
stmt[' free' ]()
270
264
else
271
- ret = sqlite3_exec @db , sql, 0 , 0 , apiTemp
272
- err = handleErrors ret, apiTemp
273
- if err isnt null then throw ' SQLite error : ' + err
265
+ @ handleError sqlite3_exec @db , sql, 0 , 0 , apiTemp
274
266
return @
275
267
276
268
### Execute an SQL query, and returns the result.
@@ -369,14 +361,12 @@ class Database
369
361
###
370
362
' prepare ' : (sql , params ) ->
371
363
setValue apiTemp, 0 , ' i32'
372
- ret = sqlite3_prepare_v2 @db , sql, - 1 , apiTemp, NULL
373
- err = handleErrors ret, NULL
374
- if err isnt null then throw ' SQLite error: ' + err
364
+ @ handleError sqlite3_prepare_v2 @db , sql, - 1 , apiTemp, NULL
375
365
pStmt = getValue apiTemp, ' i32' # pointer to a statement, or null
376
366
if pStmt is NULL then throw ' Nothing to prepare'
377
- stmt = new Statement ( pStmt)
367
+ stmt = new Statement pStmt, this
378
368
if params? then stmt .bind params
379
- @statements .push ( stmt)
369
+ @statements .push stmt
380
370
return stmt
381
371
382
372
### Exports the contents of the database to a binary array
@@ -397,18 +387,17 @@ class Database
397
387
###
398
388
' close ' : ->
399
389
stmt[' free' ]() for stmt in @statements
400
- ret = sqlite3_close_v2 @db
401
- if ret isnt 0 then throw ' SQLite error: ' + SQLite_codes[ret].msg
390
+ @ handleError sqlite3_close_v2 @db
402
391
FS .unlink ' /' + @filename
403
392
@db = null
404
393
405
- handleErrors = ( ret , errPtrPtr ) ->
406
- if not errPtrPtr
407
- return if ret is SQLite . OK then null else SQLite . errorMessages [ret]
408
- else
409
- errPtr = getValue errPtrPtr, ' i32 '
410
- if errPtr isnt NULL and errPtr isnt undefined
411
- msg = Pointer_stringify errPtr
412
- sqlite3_free errPtr
413
- return msg
414
- else return null
394
+ ### Analyze a result code, return null if no error occured, and throw
395
+ an error with a descriptive message otherwise
396
+ @nodoc
397
+ ###
398
+ handleError : ( returnCode ) ->
399
+ if returnCode is SQLite . OK
400
+ null
401
+ else
402
+ errmsg = sqlite3_errmsg @db
403
+ throw new Error (errmsg)
0 commit comments