From 412492a7579de80ee5828ca8b145ac6c6c811247 Mon Sep 17 00:00:00 2001 From: Cédric Ricard Date: Fri, 2 Jan 2009 22:04:06 +0000 Subject: [PATCH] - 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 | 48 ++++++++++++++++++++++++++++++------------------ anubis_dev/library/data_base/sqlite.anubis | 65 +++++++++++++++++++++++++++++++++++++++++++++++++---------------- anubis_dev/library/predefined.anubis | 22 +++++++++++++++------- 3 files changed, 94 insertions(+), 41 deletions(-) diff --git a/anubis_dev/compiler/src/predef.anubis b/anubis_dev/compiler/src/predef.anubis index 003a734..e08047d 100644 --- a/anubis_dev/compiler/src/predef.anubis +++ b/anubis_dev/compiler/src/predef.anubis @@ -528,7 +528,7 @@ public define ByteArray extract(ByteArray s, public define ByteArray ByteArray s + ByteArray t = £avm{ concat_byte_array }. public define String to_ascii(ByteArray s) = £avm{ byte_array_to_ascii }. public define String to_string(ByteArray s) = £avm{ byte_array_to_string }. -public define String to_hexa(ByteArray s) = £avm{ byte_array_to_string }. +public define String to_hexa(ByteArray s) = £avm{ byte_array_to_ascii }. public define ByteArray to_byte_array(String s) = £avm{ string_to_byte_array }. public define ByteArray to_text_mode(ByteArray s) = £avm{ byte_array_to_text_mode }. @@ -3207,7 +3207,6 @@ public define Result(SQLite3Error, SQLite3HeadersOrRow -> SQLite3Row) define One -> SQLite3Row £make_new_cursor ( - £StructPtr(SQLite3) db, £StructPtr(SQLite3Stmt) stmt, Bool first_row_cached, ) = @@ -3380,7 +3379,27 @@ define Result(SQLite3Error,List(SQLite3Datum)) £null then ok([null . t]) } }. - + +define SQLite3QueryResult + £make_SQLite3QueryResult + ( + £StructPtr(SQLite3Stmt) stmt, + ) = + if £go_to_next_row(stmt) is + { + /* no row at all in the result */ + no_more_row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0), + (One u) |-> no_more_row, + (List(SQLite3Bind) bindings) |-> + forget(£do_reset(stmt)); £do_bind(stmt,bindings)), + /* the first row exists */ + row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0), + £make_new_cursor(stmt,true), + (List(SQLite3Bind) bindings) |-> + forget(£do_reset(stmt)); £do_bind(stmt,bindings)), + /* error */ + error(c,m) then error(sqlite3(c,m)) + }. public define SQLite3QueryResult sqlite3_query @@ -3406,21 +3425,7 @@ public define SQLite3QueryResult if £do_bind(stmt,initial_bindings) is { error(msg) then error(msg), - ok then if £go_to_next_row(stmt) is - { - /* no row at all in the result */ - no_more_row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0), - (One u) |-> no_more_row, - (List(SQLite3Bind) bindings) |-> - forget(£do_reset(stmt)); £do_bind(stmt,bindings)), - /* the first row exists */ - row then ok((One u) |-> £list_headers(stmt,£column_count(stmt),0), - £make_new_cursor(db1,stmt,true), - (List(SQLite3Bind) bindings) |-> - forget(£do_reset(stmt)); £do_bind(stmt,bindings)), - /* error */ - error(c,m) then error(sqlite3(c,m)) - } + ok then £make_SQLite3QueryResult(stmt) } }. @@ -3478,6 +3483,13 @@ public define SQLite3Result if stmt is £statement(stmt1) then £do_reset(stmt1). +public define SQLite3QueryResult + make_SQLite3QueryResult + ( + SQLite3Stmt stmt, + ) = + if stmt is £statement(stmt1) then + £make_SQLite3QueryResult(stmt1). diff --git a/anubis_dev/library/data_base/sqlite.anubis b/anubis_dev/library/data_base/sqlite.anubis index 0de127a..f36d878 100644 --- a/anubis_dev/library/data_base/sqlite.anubis +++ b/anubis_dev/library/data_base/sqlite.anubis @@ -300,25 +300,58 @@ public define SQLite3QueryResult ) = with deadline = now + timeout, do_query = (One _) |-do_query-> - if sqlite3_query(db, sql_command, initial_bindings) is + if sqlite3_prepare(db, sql_command) is { error(sql_error) then - if (sql_error.code /= 1 & sql_error.code /= 5 & sql_error.code /= 6) | now > deadline then - error(sql_error) - else // here error is SQLITE_ERROR, SQLITE_BUSY or SQLITE_LOCKED - // this is a very bad thing to have SQLITE_ERROR here, but 'nested transaction' returns this error... :-( - // error 1 = SQLITE_ERROR --> a SELECT statement isn't finished - // error 5 = SQLITE_BUSSY --> a SELECT statement isn't finished into another instance - ( - if sql_error.code = 5 then - unique - else - println(db_error(sql_error) + "executing [" + sql_command + "]") - ); - sleep(ms_retry_delay); - do_query(unique), - ok(headers, cursor, reset) then ok(headers, cursor, reset) + println(db_error(sql_error) + " preparing [" + sql_command + "]"); + error(sql_error), + ok(stmt) then + if sqlite3_bind(stmt, initial_bindings) is + { + error(sql_error) then + println(db_error(sql_error) + " binding parameters to [" + sql_command + "]"); + error(sql_error), + ok then + if make_SQLite3QueryResult(stmt) is + { + error(sql_error) then + if (sql_error.code /= 1 & sql_error.code /= 5 & sql_error.code /= 6) | now > deadline then + error(sql_error) + else // here error is SQLITE_ERROR, SQLITE_BUSY or SQLITE_LOCKED + // this is a very bad thing to have SQLITE_ERROR here, but 'nested transaction' returns this error... :-( + // error 1 = SQLITE_ERROR --> a SELECT statement isn't finished + // error 5 = SQLITE_BUSSY --> a SELECT statement isn't finished into another instance + ( + if sql_error.code = 5 then + unique + else + println(db_error(sql_error) + " executing [" + sql_command + "]") + ); + sleep(ms_retry_delay); + do_query(unique), + ok(headers, cursor, reset) then ok(headers, cursor, reset) + } + } }, +// if sqlite3_query(db, sql_command, initial_bindings) is +// { +// error(sql_error) then +// if (sql_error.code /= 1 & sql_error.code /= 5 & sql_error.code /= 6) | now > deadline then +// error(sql_error) +// else // here error is SQLITE_ERROR, SQLITE_BUSY or SQLITE_LOCKED +// // this is a very bad thing to have SQLITE_ERROR here, but 'nested transaction' returns this error... :-( +// // error 1 = SQLITE_ERROR --> a SELECT statement isn't finished +// // error 5 = SQLITE_BUSSY --> a SELECT statement isn't finished into another instance +// ( +// if sql_error.code = 5 then +// unique +// else +// println(db_error(sql_error) + " executing [" + sql_command + "]") +// ); +// sleep(ms_retry_delay); +// do_query(unique), +// ok(headers, cursor, reset) then ok(headers, cursor, reset) +// }, do_query(unique). // --------------------------------------------------------------------------- diff --git a/anubis_dev/library/predefined.anubis b/anubis_dev/library/predefined.anubis index 85e7fec..090ece6 100644 --- a/anubis_dev/library/predefined.anubis +++ b/anubis_dev/library/predefined.anubis @@ -917,14 +917,13 @@ public define ByteArray ByteArray s + ByteArray t. The following two primitives transform a byte array into a string. The first one - 'to_ascii' transforms each byte in the byte array into a sequence of two hexadecimal + 'to_hexa' transforms each byte in the byte array into a sequence of two hexadecimal digits. For example, if the byte array 's' has 3 bytes with respective values 4, 10 and 55, we have: -to do: to_ascii(ByteArray) should become to_hexa(ByteArray). - to_ascii(s) = "040a37" + to_hexa(s) = "040a37" - Note that 'to_ascii' transforms a byte array of length n into a string of length 2*n. + Note that 'to_hexa' transforms a byte array of length n into a string of length 2*n. On the contrary, 'to_string' copies into a new string the bytes of 's' until either the 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 SQLite3Stmt stmt, ). +/** + * Low level utility function allowing to construct a SQLite3QueryResult from a prepared and eventually binded statement. + * This function is used by higher level function 'sqlite3_query'. + */ +public define SQLite3QueryResult + make_SQLite3QueryResult + ( + SQLite3Stmt stmt, + ). @@ -4516,9 +4524,9 @@ public define MakeFastLexerResult The external library (actually the wrapper library) must be loaded before you can use it. This is acheived by: -public type WrapperLibrary:... an opaque type + public type WrapperLibrary:... an opaque type -public define Maybe(WrapperLibrary) + public define Maybe(WrapperLibrary) load_wrapper_library ( String wrapper_library_name @@ -4535,7 +4543,7 @@ public define Maybe(WrapperLibrary) In order to call an external library function, use the following: -public define Maybe($U) + public define Maybe($U) wrapper_library_call ( WrapperLibrary library, -- libgit2 0.21.4