diff options
Diffstat (limited to 'lib/odbc/test')
-rw-r--r-- | lib/odbc/test/odbc_connect_SUITE.erl | 82 | ||||
-rw-r--r-- | lib/odbc/test/odbc_data_type_SUITE.erl | 7 | ||||
-rw-r--r-- | lib/odbc/test/odbc_query_SUITE.erl | 91 | ||||
-rw-r--r-- | lib/odbc/test/oracle.erl | 29 | ||||
-rw-r--r-- | lib/odbc/test/postgres.erl | 41 |
5 files changed, 226 insertions, 24 deletions
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl index a076c4dfff..74ae2c96e6 100644 --- a/lib/odbc/test/odbc_connect_SUITE.erl +++ b/lib/odbc/test/odbc_connect_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -51,7 +51,7 @@ all() -> {group, client_dies}, connect_timeout, timeout, many_timeouts, timeout_reset, disconnect_on_timeout, connection_closed, disable_scrollable_cursors, - return_rows_as_lists, api_missuse]; + return_rows_as_lists, api_missuse, extended_errors]; Other -> {skip, Other} end. @@ -277,13 +277,19 @@ port_dies(_Config) -> {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()), {status, _} = process_info(Ref, status), process_flag(trap_exit, true), - Port = lists:last(erlang:ports()), - exit(Port, kill), - %% Wait for exit_status from port 5000 ms (will not get a exit - %% status in this case), then wait a little longer to make sure - %% the port and the controlprocess has had time to terminate. - test_server:sleep(10000), - undefined = process_info(Ref, status). + NamedPorts = [{P, erlang:port_info(P, name)} || P <- erlang:ports()], + case [P || {P, {name, Name}} <- NamedPorts, is_odbcserver(Name)] of + [Port] -> + exit(Port, kill), + %% Wait for exit_status from port 5000 ms (will not get a exit + %% status in this case), then wait a little longer to make sure + %% the port and the controlprocess has had time to terminate. + test_server:sleep(10000), + undefined = process_info(Ref, status); + [] -> + ct:fail([erlang:port_info(P, name) || P <- erlang:ports()]) + end. + %%------------------------------------------------------------------------- control_process_dies(doc) -> @@ -292,13 +298,17 @@ control_process_dies(suite) -> []; control_process_dies(_Config) -> {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()), process_flag(trap_exit, true), - Port = lists:last(erlang:ports()), - {connected, Ref} = erlang:port_info(Port, connected), - exit(Ref, kill), - test_server:sleep(500), - undefined = erlang:port_info(Port, connected). - %% Check for c-program still running, how? - + NamedPorts = [{P, erlang:port_info(P, name)} || P <- erlang:ports()], + case [P || {P, {name, Name}} <- NamedPorts, is_odbcserver(Name)] of + [Port] -> + {connected, Ref} = erlang:port_info(Port, connected), + exit(Ref, kill), + test_server:sleep(500), + undefined = erlang:port_info(Port, connected); + %% Check for c-program still running, how? + [] -> + ct:fail([erlang:port_info(P, name) || P <- erlang:ports()]) + end. %%------------------------------------------------------------------------- client_dies_normal(doc) -> @@ -838,3 +848,43 @@ transaction_support_str(mysql) -> "ENGINE = InnoDB"; transaction_support_str(_) -> "". + + +%%------------------------------------------------------------------------- +extended_errors(doc)-> + ["Test the extended errors connection option: When off; the old behaviour of just an error " + "string is returned on error. When on, the error string is replaced by a 3 element tuple " + "that also exposes underlying ODBC provider error codes."]; +extended_errors(suite) -> []; +extended_errors(Config) when is_list(Config)-> + Table = ?config(tableName, Config), + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()), + {updated, _} = odbc:sql_query(Ref, "create table " ++ Table ++" ( id integer, data varchar(10))"), + + % Error case WITHOUT extended errors on... + case odbc:sql_query(Ref, "create table " ++ Table ++" ( id integer, data varchar(10))") of + {error, ErrorString} when is_list(ErrorString) -> ok + end, + + % Now the test case with extended errors on - This should return a tuple, not a list/string now. + % The first element is a string that is the ODBC error string; the 2nd element is a native integer error + % code passed from the underlying provider driver. The last is the familiar old error string. + % We can't check the actual error code; as each different underlying provider will return + % a different value - So we just check the return types at least. + {ok, RefExtended} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options() ++ [{extended_errors, on}]), + case odbc:sql_query(RefExtended, "create table " ++ Table ++" ( id integer, data varchar(10))") of + {error, {ODBCCodeString, NativeCodeNum, ShortErrorString}} when is_list(ODBCCodeString), is_number(NativeCodeNum), is_list(ShortErrorString) -> ok + end, + + ok = odbc:disconnect(Ref), + ok = odbc:disconnect(RefExtended). + + +is_odbcserver(Name) -> + case re:run(Name, "odbcserver") of + {match, _} -> + true; + _ -> + false + end. + diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl index d61a91f973..2d33546622 100644 --- a/lib/odbc/test/odbc_data_type_SUITE.erl +++ b/lib/odbc/test/odbc_data_type_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1469,7 +1470,7 @@ utf8(Config) when is_list(Config) -> odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ "(FIELD text)"), - Latin1Data = ["���������", + Latin1Data = ["ÖÄÅÄÖÅäöå", "testasdf", "Row 3", "Row 4", @@ -1564,7 +1565,7 @@ timestamp(Config) when is_list(Config) -> %%------------------------------------------------------------------------ w_char_support(Ref, Table, CharType, Size) -> - Latin1Data = ["���������", + Latin1Data = ["ÖÄÅÄÖÅäöå", "testasdf", "Row 3", "Row 4", diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl index 1852678b4b..56550bfaa6 100644 --- a/lib/odbc/test/odbc_query_SUITE.erl +++ b/lib/odbc/test/odbc_query_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> case odbc_test_lib:odbc_check() of ok -> - [sql_query, next, {group, scrollable_cursors}, select_count, + [stored_proc, sql_query, next, {group, scrollable_cursors}, select_count, select_next, select_relative, select_absolute, create_table_twice, delete_table_twice, duplicate_key, not_connection_owner, no_result_set, query_error, @@ -63,7 +63,8 @@ groups() -> param_insert_numeric, {group, param_insert_string}, param_insert_float, param_insert_real, param_insert_double, param_insert_mix, param_update, - param_delete, param_select]}, + param_delete, param_select, + param_select_empty_params, param_delete_empty_params]}, {param_integers, [], [param_insert_tiny_int, param_insert_small_int, param_insert_int, param_insert_integer]}, @@ -171,6 +172,26 @@ end_per_testcase(_Case, Config) -> %%------------------------------------------------------------------------- %% Test cases starts here. %%------------------------------------------------------------------------- +stored_proc(doc)-> + ["Test stored proc with OUT param"]; +stored_proc(suite) -> []; +stored_proc(Config) when is_list(Config) -> + case ?RDBMS of + X when X == oracle; X == postgres-> + Ref = ?config(connection_ref, Config), + {updated, _} = + odbc:sql_query(Ref, + ?RDBMS:stored_proc_integer_out()), + Result = ?RDBMS:query_result(), + Result = + ?RDBMS:param_query(Ref), + {updated, _} = + odbc:sql_query(Ref, ?RDBMS:drop_proc()), + ok; + _ -> + {skip, "stored proc not yet supported"} + end. + sql_query(doc)-> ["Test the common cases"]; sql_query(suite) -> []; @@ -1345,6 +1366,70 @@ param_select(Config) when is_list(Config) -> ok. %%------------------------------------------------------------------------- +param_select_empty_params(doc) -> + ["Test parameterized select query with no parameters."]; +param_select_empty_params(suite) -> + []; +param_select_empty_params(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID INTEGER, DATA CHARACTER VARYING(10)," + " PRIMARY KEY(ID))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2, 3]}, + {{sql_varchar, 10}, + ["foo", "bar", "foo"]}]), + + true = odbc_test_lib:check_row_count(3, Count), + + SelectResult = ?RDBMS:param_select(), + + SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++ + " WHERE DATA = \'foo\'", + []), + ok. + +%%------------------------------------------------------------------------- +param_delete_empty_params(doc) -> + ["Test parameterized delete query with no parameters."]; +param_delete_empty_params(suite) -> + []; +param_delete_empty_params(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID INTEGER, DATA CHARACTER VARYING(10)," + " PRIMARY KEY(ID))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2, 3]}, + {{sql_varchar, 10}, + ["foo", "bar", "baz"]}]), + true = odbc_test_lib:check_row_count(3, Count), + + {updated, NewCount} = odbc:param_query(Ref, "DELETE FROM " ++ Table ++ + " WHERE ID = 1 OR ID = 2", + []), + + true = odbc_test_lib:check_row_count(2, NewCount), + + UpdateResult = ?RDBMS:param_delete(), + + UpdateResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + ok. + +%%------------------------------------------------------------------------- describe_integer(doc) -> ["Test describe_table/[2,3] for integer columns."]; describe_integer(suite) -> diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl index d74863d8c1..3e49a1b64d 100644 --- a/lib/odbc/test/oracle.erl +++ b/lib/odbc/test/oracle.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -240,3 +240,30 @@ describe_floating() -> {ok,[{"F",sql_double},{"R",sql_double},{"D",sql_double}]}. describe_dec_num() -> {ok,[{"MYDEC",{sql_decimal,9,3}},{"MYNUM",{sql_decimal,9,2}}]}. + +%------------------------------------------------------------------------- +drop_proc() -> + "drop procedure test_proc1;". + +stored_proc_integer_out() -> + "create or replace PROCEDURE test_proc1(" ++ + "int_a OUT NUMBER, " ++ + "int_b OUT NUMBER) " ++ + "is " ++ + "begin " ++ + " int_a := 123; " ++ + " int_b := 456; " ++ + "exception " ++ + "WHEN NO_DATA_FOUND THEN " ++ + " int_a := 0; " ++ + " int_b := 0; " ++ + "end;". + +param_query(Ref) -> + odbc:param_query(Ref, "call test_proc1(?,?)", + [{sql_integer, out, [0]}, + {sql_integer, out, [0]}]). + + +query_result() -> + {executed, 2, [{123, 456}]}. diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl index d564dbd5ff..99a191c46a 100644 --- a/lib/odbc/test/postgres.erl +++ b/lib/odbc/test/postgres.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -293,3 +293,42 @@ describe_dec_num() -> describe_timestamp() -> {ok, [{"field", sql_timestamp}]}. + +%------------------------------------------------------------------------- +drop_proc() -> + "drop function test_proc1(OUT integer, OUT integer);". + +stored_proc_integer_out() -> + "create or replace FUNCTION test_proc1(" ++ + "OUT int_a INTEGER, " ++ + "OUT int_b INTEGER) " ++ + "AS $$ " ++ + "BEGIN " ++ + " int_a := 123; " ++ + " int_b := 456; " ++ + "END " ++ + "$$ LANGUAGE plpgsql ". + +%% This does not test what you might think it is supposed to test. +%% Since the stored procedure has got 2 out parameters and no +%% in parameters it is of arity 0 as called below. +%% +%% The port program odbcserver.c will marshal these out parameters +%% and hand them to ODBC. The ODBC driver for postgres will +%% apparently not give a hoot about these out parameters and instead +%% return the result in a regular result select set. The port program +%% will assume it has the result in the out parameters and marshal +%% these as they are i.e as it itself had packed them, so they +%% come back unchanged. +%% +%% The real function result goes into the void but the code in odbcserver.c +%% that marshals out parameters returned from ODBC will be run +%% so that is what this test tests... +%% +param_query(Ref) -> + odbc:param_query(Ref, "select * from test_proc1()", + [{sql_integer, out, [111]}, + {sql_integer, out, [444]}]). + +query_result() -> + {executed, 2, [{111, 444}]}. |