From d35c52a37076e405ca299b1ccc2f0c89151d9525 Mon Sep 17 00:00:00 2001 From: Alexey Romanov Date: Tue, 10 May 2011 12:03:47 +0400 Subject: [PATCH] Fixed tests and documentation. --- c_src/sqlite3_drv.c | 17 +++++++++++------ src/sqlite3.erl | 33 ++++++++++++++++++++++++--------- test/sqlite3_test.erl | 2 -- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/c_src/sqlite3_drv.c b/c_src/sqlite3_drv.c index 4d6ab38..3a5fc41 100644 --- a/c_src/sqlite3_drv.c +++ b/c_src/sqlite3_drv.c @@ -594,7 +594,7 @@ static void sql_free_async(void *_async_command) { driver_free(async_command); } -static void sql_exec_one_statement( +static int sql_exec_one_statement( sqlite3_stmt *statement, async_sqlite3_command *async_command, int *term_count_p, int *term_allocated_p, ErlDrvTermData **dataset_p) { int column_count = sqlite3_column_count(statement); @@ -740,14 +740,14 @@ static void sql_exec_one_statement( dataset_p, term_count_p, term_allocated_p, &async_command->error_code); async_command->finalize_statement_on_free = 1; - return; + return next_row; } if (next_row != SQLITE_DONE) { return_error(drv, next_row, sqlite3_errmsg(drv->db), dataset_p, term_count_p, term_allocated_p, &async_command->error_code); async_command->finalize_statement_on_free = 1; - return; + return next_row; } if (column_count > 0) { @@ -796,6 +796,8 @@ static void sql_exec_one_statement( fflush(drv->log); #endif async_command->finalize_statement_on_free = 1; + + return 0; } static void sql_exec_async(void *_async_command) { @@ -836,16 +838,19 @@ static void sql_exec_async(void *_async_command) { } result = sqlite3_prepare_v2(drv->db, rest, end - rest, &statement, &rest); if (result != SQLITE_OK) { + num_statements++; return_error(drv, result, sqlite3_errmsg(drv->db), &dataset, &term_count, &term_allocated, &async_command->error_code); - num_statements++; break; } else if (statement == NULL) { break; } else { num_statements++; - sql_exec_one_statement(statement, async_command, &term_count, - &term_allocated, &dataset); + result = sql_exec_one_statement(statement, async_command, &term_count, + &term_allocated, &dataset); + if (result) { + break; + } } } diff --git a/src/sqlite3.erl b/src/sqlite3.erl index 1fe9ba6..dfee112 100644 --- a/src/sqlite3.erl +++ b/src/sqlite3.erl @@ -218,10 +218,11 @@ sql_exec_timeout(Db, SQL, Params, Timeout) -> %% @spec sql_exec_script(Db :: atom(), Sql :: iodata()) -> [sql_result()] %% @doc %% Executes the Sql script (consisting of semicolon-separated statements) -%% directly on the Db database. Returns the list of their results (same as -%% if sql_exec/2 was called for all of them in order, but more efficient). -%% Note that any whitespace or comments after the last semicolon will be -%% considered an empty statement and produce the corresponding error. +%% directly on the Db database. +%% +%% If an error happens while executing a statement, no further statements are executed. +%% +%% The return value is the list of results of all executed statements. %% @end %%-------------------------------------------------------------------- -spec sql_exec_script(atom(), iodata()) -> [sql_result()]. @@ -232,10 +233,11 @@ sql_exec_script(Db, SQL) -> %% @spec sql_exec_script_timeout(Db :: atom(), Sql :: iodata(), Timeout :: timeout()) -> [sql_result()] %% @doc %% Executes the Sql script (consisting of semicolon-separated statements) -%% directly on the Db database. Returns the list of their results (same as -%% if sql_exec/3 was called for all of them in order, but more efficient). -%% Note that any whitespace or comments after the last semicolon will be -%% considered an empty statement and produce the corresponding error. +%% directly on the Db database. +%% +%% If an error happens while executing a statement, no further statements are executed. +%% +%% The return value is the list of results of all executed statements. %% @end %%-------------------------------------------------------------------- -spec sql_exec_script_timeout(atom(), iodata(), timeout()) -> [sql_result()]. @@ -1077,7 +1079,20 @@ do_sql_bind_and_exec(SQL, Params, #state{port = Port}) -> do_sql_exec_script(SQL, #state{port = Port}) -> ?dbgF("SQL: ~s~n", [SQL]), - exec(Port, {sql_exec_script, SQL}). + Results = exec(Port, {sql_exec_script, SQL}), + %% last element of Results may be an error + case Results of + [_|_] -> + case lists:last(Results) of + {error, _Code, Reason} -> + error_logger:error_msg("sqlite3 driver error: ~s~n", + [Reason]); + _ -> ok + end; + _ -> + ok + end, + Results. exec(_Port, {create_function, _FunctionName, _Function}) -> error_logger:error_report([{application, sqlite3}, "NOT IMPL YET"]); diff --git a/test/sqlite3_test.erl b/test/sqlite3_test.erl index 1bfe276..b44f3c2 100644 --- a/test/sqlite3_test.erl +++ b/test/sqlite3_test.erl @@ -210,7 +210,6 @@ large_number() -> Query1 = io_lib:format("select ~p, ~p", [N1, N2]), ?assertEqual([{N1, N2}], rows(sqlite3:sql_exec(ct, Query1))), Query2 = "select ?, ?", - ?debugMsg("Error message \"sqlite3 driver error: bind or column index out of range\" should be shown..."), ?assertEqual([{N1, N2}], rows(sqlite3:sql_exec(ct, Query2, [N1, N2]))), ?assertNot([{N1 + 1, N2 - 1}] == rows(sqlite3:sql_exec(ct, Query2, [N1 + 1, N2 - 1]))). @@ -262,7 +261,6 @@ script_test() -> "INSERT INTO person (id) VALUES (2);", " " ], "\n"), - ?WARN_ERROR_MESSAGE, ?assertEqual( [ok, ok, ok], sqlite3:sql_exec_script(script, Script)),