Commit 412492a7579de80ee5828ca8b145ac6c6c811247
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)
Showing
3 changed files
with
94 additions
and
41 deletions
Show diff stats
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, | ... | ... |