Commit 412492a7579de80ee5828ca8b145ac6c6c811247

Authored by Cédric RICARD
1 parent 698e8898

- Added make_SQLite3QueryResult() function into predefined

- improved sql_query_timeout() function (better granularity handling errors)
- fix to_hexa(ByteArray) function (was previously make a wrong syscall)
anubis_dev/compiler/src/predef.anubis
... ... @@ -528,7 +528,7 @@ public define ByteArray extract(ByteArray s,
528 528 public define ByteArray ByteArray s + ByteArray t = £avm{ concat_byte_array }.
529 529 public define String to_ascii(ByteArray s) = £avm{ byte_array_to_ascii }.
530 530 public define String to_string(ByteArray s) = £avm{ byte_array_to_string }.
531   -public define String to_hexa(ByteArray s) = £avm{ byte_array_to_string }.
  531 +public define String to_hexa(ByteArray s) = £avm{ byte_array_to_ascii }.
532 532 public define ByteArray to_byte_array(String s) = £avm{ string_to_byte_array }.
533 533 public define ByteArray to_text_mode(ByteArray s) = £avm{ byte_array_to_text_mode }.
534 534  
... ... @@ -3207,7 +3207,6 @@ public define Result(SQLite3Error, SQLite3HeadersOrRow -> SQLite3Row)
3207 3207 define One -> SQLite3Row
3208 3208 £make_new_cursor
3209 3209 (
3210   - £StructPtr(SQLite3) db,
3211 3210 £StructPtr(SQLite3Stmt) stmt,
3212 3211 Bool first_row_cached,
3213 3212 ) =
... ... @@ -3380,7 +3379,27 @@ define Result(SQLite3Error,List(SQLite3Datum))
3380 3379 £null then ok([null . t])
3381 3380 }
3382 3381 }.
3383   -
  3382 +
  3383 +define SQLite3QueryResult
  3384 + £make_SQLite3QueryResult
  3385 + (
  3386 + £StructPtr(SQLite3Stmt) stmt,
  3387 + ) =
  3388 + if £go_to_next_row(stmt) is
  3389 + {
  3390 + /* no row at all in the result */
  3391 + no_more_row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0),
  3392 + (One u) |-> no_more_row,
  3393 + (List(SQLite3Bind) bindings) |->
  3394 + forget(£do_reset(stmt)); £do_bind(stmt,bindings)),
  3395 + /* the first row exists */
  3396 + row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0),
  3397 + £make_new_cursor(stmt,true),
  3398 + (List(SQLite3Bind) bindings) |->
  3399 + forget(£do_reset(stmt)); £do_bind(stmt,bindings)),
  3400 + /* error */
  3401 + error(c,m) then error(sqlite3(c,m))
  3402 + }.
3384 3403  
3385 3404 public define SQLite3QueryResult
3386 3405 sqlite3_query
... ... @@ -3406,21 +3425,7 @@ public define SQLite3QueryResult
3406 3425 if £do_bind(stmt,initial_bindings) is
3407 3426 {
3408 3427 error(msg) then error(msg),
3409   - ok then if £go_to_next_row(stmt) is
3410   - {
3411   - /* no row at all in the result */
3412   - no_more_row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0),
3413   - (One u) |-> no_more_row,
3414   - (List(SQLite3Bind) bindings) |->
3415   - forget(£do_reset(stmt)); £do_bind(stmt,bindings)),
3416   - /* the first row exists */
3417   - row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0),
3418   - £make_new_cursor(db1,stmt,true),
3419   - (List(SQLite3Bind) bindings) |->
3420   - forget(£do_reset(stmt)); £do_bind(stmt,bindings)),
3421   - /* error */
3422   - error(c,m) then error(sqlite3(c,m))
3423   - }
  3428 + ok then £make_SQLite3QueryResult(stmt)
3424 3429 }
3425 3430 }.
3426 3431  
... ... @@ -3478,6 +3483,13 @@ public define SQLite3Result
3478 3483 if stmt is £statement(stmt1) then
3479 3484 £do_reset(stmt1).
3480 3485  
  3486 +public define SQLite3QueryResult
  3487 + make_SQLite3QueryResult
  3488 + (
  3489 + SQLite3Stmt stmt,
  3490 + ) =
  3491 + if stmt is £statement(stmt1) then
  3492 + £make_SQLite3QueryResult(stmt1).
3481 3493  
3482 3494  
3483 3495  
... ...
anubis_dev/library/data_base/sqlite.anubis
... ... @@ -300,25 +300,58 @@ public define SQLite3QueryResult
300 300 ) =
301 301 with deadline = now + timeout,
302 302 do_query = (One _) |-do_query->
303   - if sqlite3_query(db, sql_command, initial_bindings) is
  303 + if sqlite3_prepare(db, sql_command) is
304 304 {
305 305 error(sql_error) then
306   - if (sql_error.code /= 1 & sql_error.code /= 5 & sql_error.code /= 6) | now > deadline then
307   - error(sql_error)
308   - else // here error is SQLITE_ERROR, SQLITE_BUSY or SQLITE_LOCKED
309   - // this is a very bad thing to have SQLITE_ERROR here, but 'nested transaction' returns this error... :-(
310   - // error 1 = SQLITE_ERROR --> a SELECT statement isn't finished
311   - // error 5 = SQLITE_BUSSY --> a SELECT statement isn't finished into another instance
312   - (
313   - if sql_error.code = 5 then
314   - unique
315   - else
316   - println(db_error(sql_error) + "executing [" + sql_command + "]")
317   - );
318   - sleep(ms_retry_delay);
319   - do_query(unique),
320   - ok(headers, cursor, reset) then ok(headers, cursor, reset)
  306 + println(db_error(sql_error) + " preparing [" + sql_command + "]");
  307 + error(sql_error),
  308 + ok(stmt) then
  309 + if sqlite3_bind(stmt, initial_bindings) is
  310 + {
  311 + error(sql_error) then
  312 + println(db_error(sql_error) + " binding parameters to [" + sql_command + "]");
  313 + error(sql_error),
  314 + ok then
  315 + if make_SQLite3QueryResult(stmt) is
  316 + {
  317 + error(sql_error) then
  318 + if (sql_error.code /= 1 & sql_error.code /= 5 & sql_error.code /= 6) | now > deadline then
  319 + error(sql_error)
  320 + else // here error is SQLITE_ERROR, SQLITE_BUSY or SQLITE_LOCKED
  321 + // this is a very bad thing to have SQLITE_ERROR here, but 'nested transaction' returns this error... :-(
  322 + // error 1 = SQLITE_ERROR --> a SELECT statement isn't finished
  323 + // error 5 = SQLITE_BUSSY --> a SELECT statement isn't finished into another instance
  324 + (
  325 + if sql_error.code = 5 then
  326 + unique
  327 + else
  328 + println(db_error(sql_error) + " executing [" + sql_command + "]")
  329 + );
  330 + sleep(ms_retry_delay);
  331 + do_query(unique),
  332 + ok(headers, cursor, reset) then ok(headers, cursor, reset)
  333 + }
  334 + }
321 335 },
  336 +// if sqlite3_query(db, sql_command, initial_bindings) is
  337 +// {
  338 +// error(sql_error) then
  339 +// if (sql_error.code /= 1 & sql_error.code /= 5 & sql_error.code /= 6) | now > deadline then
  340 +// error(sql_error)
  341 +// else // here error is SQLITE_ERROR, SQLITE_BUSY or SQLITE_LOCKED
  342 +// // this is a very bad thing to have SQLITE_ERROR here, but 'nested transaction' returns this error... :-(
  343 +// // error 1 = SQLITE_ERROR --> a SELECT statement isn't finished
  344 +// // error 5 = SQLITE_BUSSY --> a SELECT statement isn't finished into another instance
  345 +// (
  346 +// if sql_error.code = 5 then
  347 +// unique
  348 +// else
  349 +// println(db_error(sql_error) + " executing [" + sql_command + "]")
  350 +// );
  351 +// sleep(ms_retry_delay);
  352 +// do_query(unique),
  353 +// ok(headers, cursor, reset) then ok(headers, cursor, reset)
  354 +// },
322 355 do_query(unique).
323 356  
324 357 // ---------------------------------------------------------------------------
... ...
anubis_dev/library/predefined.anubis
... ... @@ -917,14 +917,13 @@ public define ByteArray ByteArray s + ByteArray t.
917 917  
918 918  
919 919 The following two primitives transform a byte array into a string. The first one
920   - 'to_ascii' transforms each byte in the byte array into a sequence of two hexadecimal
  920 + 'to_hexa' transforms each byte in the byte array into a sequence of two hexadecimal
921 921 digits. For example, if the byte array 's' has 3 bytes with respective values 4, 10 and
922 922 55, we have:
923 923  
924   -to do: to_ascii(ByteArray) should become to_hexa(ByteArray).
925   - to_ascii(s) = "040a37"
  924 + to_hexa(s) = "040a37"
926 925  
927   - Note that 'to_ascii' transforms a byte array of length n into a string of length 2*n.
  926 + Note that 'to_hexa' transforms a byte array of length n into a string of length 2*n.
928 927  
929 928 On the contrary, 'to_string' copies into a new string the bytes of 's' until either the
930 929 end of 's' or the first zero byte is reached. Hence 'to_string(s)' is at most as long
... ... @@ -4240,6 +4239,15 @@ public define SQLite3Result
4240 4239 SQLite3Stmt stmt,
4241 4240 ).
4242 4241  
  4242 +/**
  4243 + * Low level utility function allowing to construct a SQLite3QueryResult from a prepared and eventually binded statement.
  4244 + * This function is used by higher level function 'sqlite3_query'.
  4245 + */
  4246 +public define SQLite3QueryResult
  4247 + make_SQLite3QueryResult
  4248 + (
  4249 + SQLite3Stmt stmt,
  4250 + ).
4243 4251  
4244 4252  
4245 4253  
... ... @@ -4516,9 +4524,9 @@ public define MakeFastLexerResult
4516 4524 The external library (actually the wrapper library) must be loaded before you can use
4517 4525 it. This is acheived by:
4518 4526  
4519   -public type WrapperLibrary:... an opaque type
  4527 + public type WrapperLibrary:... an opaque type
4520 4528  
4521   -public define Maybe(WrapperLibrary)
  4529 + public define Maybe(WrapperLibrary)
4522 4530 load_wrapper_library
4523 4531 (
4524 4532 String wrapper_library_name
... ... @@ -4535,7 +4543,7 @@ public define Maybe(WrapperLibrary)
4535 4543  
4536 4544 In order to call an external library function, use the following:
4537 4545  
4538   -public define Maybe($U)
  4546 + public define Maybe($U)
4539 4547 wrapper_library_call
4540 4548 (
4541 4549 WrapperLibrary library,
... ...