1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2002-2013. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: %% 21: 22: -module(odbc_query_SUITE). 23: 24: %% Note: This directive should only be used in test suites. 25: -compile(export_all). 26: 27: -include_lib("common_test/include/ct.hrl"). 28: -include("test_server_line.hrl"). 29: -include("odbc_test.hrl"). 30: 31: %%-------------------------------------------------------------------- 32: %% all(Arg) -> [Doc] | [Case] | {skip, Comment} 33: %% Arg - doc | suite 34: %% Doc - string() 35: %% Case - atom() 36: %% Name of a test case function. 37: %% Comment - string() 38: %% Description: Returns documentation/test cases in this test suite 39: %% or a skip tuple if the platform is not supported. 40: %%-------------------------------------------------------------------- 41: suite() -> [{ct_hooks,[ts_install_cth]}]. 42: 43: all() -> 44: case odbc_test_lib:odbc_check() of 45: ok -> 46: [stored_proc, sql_query, next, {group, scrollable_cursors}, select_count, 47: select_next, select_relative, select_absolute, 48: create_table_twice, delete_table_twice, duplicate_key, 49: not_connection_owner, no_result_set, query_error, 50: {group, multiple_result_sets}, 51: {group, parameterized_queries}, {group, describe_table}, 52: delete_nonexisting_row]; 53: Other -> {skip, Other} 54: end. 55: 56: groups() -> 57: [{multiple_result_sets, [], [multiple_select_result_sets, 58: multiple_mix_result_sets, 59: multiple_result_sets_error]}, 60: {scrollable_cursors, [], [first, last, prev]}, 61: {parameterized_queries, [], 62: [{group, param_integers}, param_insert_decimal, 63: param_insert_numeric, {group, param_insert_string}, 64: param_insert_float, param_insert_real, 65: param_insert_double, param_insert_mix, param_update, 66: param_delete, param_select, 67: param_select_empty_params, param_delete_empty_params]}, 68: {param_integers, [], 69: [param_insert_tiny_int, param_insert_small_int, 70: param_insert_int, param_insert_integer]}, 71: {param_insert_string, [], 72: [param_insert_char, param_insert_character, 73: param_insert_char_varying, 74: param_insert_character_varying]}, 75: {describe_table, [], 76: [describe_integer, describe_string, describe_floating, 77: describe_dec_num, describe_no_such_table]}]. 78: 79: init_per_group(multiple_result_sets, Config) -> 80: case is_supported_multiple_resultsets(?RDBMS) of 81: true -> 82: Config; 83: false -> 84: {skip, "Not supported by " ++ atom_to_list(?RDBMS) ++ "driver"} 85: end; 86: init_per_group(scrollable_cursors, Config) -> 87: case proplists:get_value(scrollable_cursors, odbc_test_lib:platform_options()) of 88: off -> 89: {skip, "Not supported by driver"}; 90: _ -> 91: Config 92: end; 93: 94: init_per_group(_,Config) -> 95: Config. 96: 97: end_per_group(_GroupName, Config) -> 98: Config. 99: 100: %%-------------------------------------------------------------------- 101: %% Function: init_per_suite(Config) -> Config 102: %% Config - [tuple()] 103: %% A list of key/value pairs, holding the test case configuration. 104: %% Description: Initiation before the whole suite 105: %% 106: %% Note: This function is free to add any key/value pairs to the Config 107: %% variable, but should NOT alter/remove any existing entries. 108: %%-------------------------------------------------------------------- 109: init_per_suite(Config) when is_list(Config) -> 110: case odbc_test_lib:skip() of 111: true -> 112: {skip, "ODBC not supported"}; 113: false -> 114: case (catch odbc:start()) of 115: ok -> 116: [{tableName, odbc_test_lib:unique_table_name()}| Config]; 117: _ -> 118: {skip, "ODBC not startable"} 119: end 120: end. 121: 122: %%-------------------------------------------------------------------- 123: %% Function: end_per_suite(Config) -> _ 124: %% Config - [tuple()] 125: %% A list of key/value pairs, holding the test case configuration. 126: %% Description: Cleanup after the whole suite 127: %%-------------------------------------------------------------------- 128: end_per_suite(_Config) -> 129: application:stop(odbc), 130: ok. 131: 132: %%-------------------------------------------------------------------- 133: %% Function: init_per_testcase(Case, Config) -> Config 134: %% Case - atom() 135: %% Name of the test case that is about to be run. 136: %% Config - [tuple()] 137: %% A list of key/value pairs, holding the test case configuration. 138: %% 139: %% Description: Initiation before each test case 140: %% 141: %% Note: This function is free to add any key/value pairs to the Config 142: %% variable, but should NOT alter/remove any existing entries. 143: %%-------------------------------------------------------------------- 144: init_per_testcase(_Case, Config) -> 145: {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()), 146: odbc_test_lib:strict(Ref, ?RDBMS), 147: Dog = test_server:timetrap(?default_timeout), 148: Temp = lists:keydelete(connection_ref, 1, Config), 149: NewConfig = lists:keydelete(watchdog, 1, Temp), 150: [{watchdog, Dog}, {connection_ref, Ref} | NewConfig]. 151: 152: %%-------------------------------------------------------------------- 153: %% Function: end_per_testcase(Case, Config) -> _ 154: %% Case - atom() 155: %% Name of the test case that is about to be run. 156: %% Config - [tuple()] 157: %% A list of key/value pairs, holding the test case configuration. 158: %% Description: Cleanup after each test case 159: %%-------------------------------------------------------------------- 160: end_per_testcase(_Case, Config) -> 161: Ref = ?config(connection_ref, Config), 162: ok = odbc:disconnect(Ref), 163: %% Clean up if needed 164: Table = ?config(tableName, Config), 165: {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()), 166: odbc:sql_query(NewRef, "DROP TABLE " ++ Table), 167: odbc:disconnect(NewRef), 168: Dog = ?config(watchdog, Config), 169: test_server:timetrap_cancel(Dog), 170: ok. 171: 172: %%------------------------------------------------------------------------- 173: %% Test cases starts here. 174: %%------------------------------------------------------------------------- 175: stored_proc(doc)-> 176: ["Test stored proc with OUT param"]; 177: stored_proc(suite) -> []; 178: stored_proc(Config) when is_list(Config) -> 179: case ?RDBMS of 180: X when X == oracle; X == postgres-> 181: Ref = ?config(connection_ref, Config), 182: {updated, _} = 183: odbc:sql_query(Ref, 184: ?RDBMS:stored_proc_integer_out()), 185: Result = ?RDBMS:query_result(), 186: Result = 187: ?RDBMS:param_query(Ref), 188: {updated, _} = 189: odbc:sql_query(Ref, ?RDBMS:drop_proc()), 190: ok; 191: _ -> 192: {skip, "stored proc not yet supported"} 193: end. 194: 195: sql_query(doc)-> 196: ["Test the common cases"]; 197: sql_query(suite) -> []; 198: sql_query(Config) when is_list(Config) -> 199: Ref = ?config(connection_ref, Config), 200: Table = ?config(tableName, Config), 201: 202: {updated, _} = 203: odbc:sql_query(Ref, 204: "CREATE TABLE " ++ Table ++ 205: " (ID integer, DATA varchar(10))"), 206: 207: {updated, Count} = 208: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), 209: 210: true = odbc_test_lib:check_row_count(1, Count), 211: 212: InsertResult = ?RDBMS:insert_result(), 213: InsertResult = 214: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 215: 216: {updated, NewCount} = 217: odbc:sql_query(Ref, "UPDATE " ++ Table ++ 218: " SET DATA = 'foo' WHERE ID = 1"), 219: 220: true = odbc_test_lib:check_row_count(1, NewCount), 221: 222: UpdateResult = ?RDBMS:update_result(), 223: UpdateResult = 224: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 225: 226: {updated, NewCount1} = odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ 227: " WHERE ID = 1"), 228: 229: true = odbc_test_lib:check_row_count(1, NewCount1), 230: 231: {selected, Fields, []} = 232: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 233: 234: ["ID","DATA"] = odbc_test_lib:to_upper(Fields), 235: ok. 236: 237: %%------------------------------------------------------------------------- 238: select_count(doc) -> 239: ["Tests select_count/[2,3]'s timeout, " 240: " select_count's functionality will be better tested by other tests " 241: " such as first."]; 242: select_count(sute) -> []; 243: select_count(Config) when is_list(Config) -> 244: Ref = ?config(connection_ref, Config), 245: Table = ?config(tableName, Config), 246: 247: {updated, _} = odbc:sql_query(Ref, 248: "CREATE TABLE " ++ Table ++ 249: " (ID integer)"), 250: 251: {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 252: " VALUES(1)"), 253: true = odbc_test_lib:check_row_count(1, Count), 254: {ok, _} = 255: odbc:select_count(Ref, "SELECT * FROM " ++ Table, ?TIMEOUT), 256: {'EXIT', {function_clause, _}} = 257: (catch odbc:select_count(Ref, "SELECT * FROM ", -1)), 258: ok. 259: %%------------------------------------------------------------------------- 260: first(doc) -> 261: ["Tests first/[1,2]"]; 262: first(suite) -> []; 263: first(Config) when is_list(Config) -> 264: Ref = ?config(connection_ref, Config), 265: Table = ?config(tableName, Config), 266: 267: {updated, _} = odbc:sql_query(Ref, 268: "CREATE TABLE " ++ Table ++ 269: " (ID integer)"), 270: 271: {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 272: " VALUES(1)"), 273: true = odbc_test_lib:check_row_count(1, Count), 274: {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 275: " VALUES(2)"), 276: true = odbc_test_lib:check_row_count(1, NewCount), 277: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 278: 279: 280: FirstResult = ?RDBMS:selected_ID(1, first), 281: FirstResult = odbc:first(Ref), 282: FirstResult = odbc:first(Ref, ?TIMEOUT), 283: {'EXIT', {function_clause, _}} = (catch odbc:first(Ref, -1)), 284: ok. 285: 286: %%------------------------------------------------------------------------- 287: last(doc) -> 288: ["Tests last/[1,2]"]; 289: last(suite) -> []; 290: last(Config) when is_list(Config) -> 291: Ref = ?config(connection_ref, Config), 292: Table = ?config(tableName, Config), 293: 294: {updated, _} = odbc:sql_query(Ref, 295: "CREATE TABLE " ++ Table ++ 296: " (ID integer)"), 297: 298: {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 299: " VALUES(1)"), 300: true = odbc_test_lib:check_row_count(1, Count), 301: {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 302: " VALUES(2)"), 303: true = odbc_test_lib:check_row_count(1, NewCount), 304: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 305: 306: LastResult = ?RDBMS:selected_ID(2, last), 307: LastResult = odbc:last(Ref), 308: 309: LastResult = odbc:last(Ref, ?TIMEOUT), 310: {'EXIT', {function_clause, _}} = (catch odbc:last(Ref, -1)), 311: ok. 312: 313: %%------------------------------------------------------------------------- 314: next(doc) -> 315: ["Tests next/[1,2]"]; 316: next(suite) -> []; 317: next(Config) when is_list(Config) -> 318: Ref = ?config(connection_ref, Config), 319: Table = ?config(tableName, Config), 320: 321: {updated, _} = odbc:sql_query(Ref, 322: "CREATE TABLE " ++ Table ++ 323: " (ID integer)"), 324: 325: {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 326: " VALUES(1)"), 327: true = odbc_test_lib:check_row_count(1, Count), 328: {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 329: " VALUES(2)"), 330: true = odbc_test_lib:check_row_count(1, NewCount), 331: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 332: 333: NextResult = ?RDBMS:selected_ID(1, next), 334: NextResult = odbc:next(Ref), 335: NextResult2 = ?RDBMS:selected_ID(2, next), 336: NextResult2 = odbc:next(Ref, ?TIMEOUT), 337: {'EXIT', {function_clause, _}} = (catch odbc:next(Ref, -1)), 338: ok. 339: %%------------------------------------------------------------------------- 340: prev(doc) -> 341: ["Tests prev/[1,2]"]; 342: prev(suite) -> []; 343: prev(Config) when is_list(Config) -> 344: Ref = ?config(connection_ref, Config), 345: Table = ?config(tableName, Config), 346: 347: {updated, _} = odbc:sql_query(Ref, 348: "CREATE TABLE " ++ Table ++ 349: " (ID integer)"), 350: 351: {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 352: " VALUES(1)"), 353: true = odbc_test_lib:check_row_count(1, Count), 354: {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 355: " VALUES(2)"), 356: true = odbc_test_lib:check_row_count(1, NewCount), 357: 358: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 359: 360: odbc:last(Ref), % Position cursor last so there will be a prev 361: PrevResult = ?RDBMS:selected_ID(1, prev), 362: PrevResult = odbc:prev(Ref), 363: 364: odbc:last(Ref), % Position cursor last so there will be a prev 365: PrevResult = odbc:prev(Ref, ?TIMEOUT), 366: {'EXIT', {function_clause, _}} = (catch odbc:prev(Ref, -1)), 367: ok. 368: %%------------------------------------------------------------------------- 369: select_next(doc) -> 370: ["Tests select/[4,5] with CursorRelation = next "]; 371: select_next(suit) -> []; 372: select_next(Config) when is_list(Config) -> 373: Ref = ?config(connection_ref, Config), 374: Table = ?config(tableName, Config), 375: 376: {updated, _} = odbc:sql_query(Ref, 377: "CREATE TABLE " ++ Table ++ 378: " (ID integer)"), 379: 380: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 381: " VALUES(1)"), 382: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 383: " VALUES(2)"), 384: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 385: " VALUES(3)"), 386: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 387: " VALUES(4)"), 388: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 389: " VALUES(5)"), 390: 391: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 392: 393: SelectResult1 = ?RDBMS:selected_next_N(1), 394: SelectResult1 = odbc:select(Ref, next, 3), 395: 396: %% Test that selecting stops at the end of the result set 397: SelectResult2 = ?RDBMS:selected_next_N(2), 398: SelectResult2 = odbc:select(Ref, next, 3, ?TIMEOUT), 399: {'EXIT',{function_clause, _}} = 400: (catch odbc:select(Ref, next, 2, -1)), 401: 402: %% If you try fetching data beyond the the end of result set, 403: %% you get an empty list. 404: {selected, Fields, []} = odbc:select(Ref, next, 1), 405: 406: ["ID"] = odbc_test_lib:to_upper(Fields), 407: ok. 408: 409: %%------------------------------------------------------------------------- 410: select_relative(doc) -> 411: ["Tests select/[4,5] with CursorRelation = relative "]; 412: select_relative(suit) -> []; 413: select_relative(Config) when is_list(Config) -> 414: Ref = ?config(connection_ref, Config), 415: Table = ?config(tableName, Config), 416: 417: {updated, _} = odbc:sql_query(Ref, 418: "CREATE TABLE " ++ Table ++ 419: " (ID integer)"), 420: 421: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 422: " VALUES(1)"), 423: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 424: " VALUES(2)"), 425: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 426: " VALUES(3)"), 427: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 428: " VALUES(4)"), 429: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 430: " VALUES(5)"), 431: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 432: " VALUES(6)"), 433: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 434: " VALUES(7)"), 435: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 436: " VALUES(8)"), 437: 438: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 439: 440: SelectResult1 = ?RDBMS:selected_relative_N(1), 441: SelectResult1 = odbc:select(Ref, {relative, 2}, 3), 442: 443: %% Test that selecting stops at the end of the result set 444: SelectResult2 = ?RDBMS:selected_relative_N(2), 445: SelectResult2 = odbc:select(Ref, {relative, 3}, 3, ?TIMEOUT), 446: {'EXIT',{function_clause, _}} = 447: (catch odbc:select(Ref, {relative, 3} , 2, -1)), 448: ok. 449: 450: %%------------------------------------------------------------------------- 451: select_absolute(doc) -> 452: ["Tests select/[4,5] with CursorRelation = absolute "]; 453: select_absolute(suit) -> []; 454: select_absolute(Config) when is_list(Config) -> 455: Ref = ?config(connection_ref, Config), 456: Table = ?config(tableName, Config), 457: 458: {updated, _} = odbc:sql_query(Ref, 459: "CREATE TABLE " ++ Table ++ 460: " (ID integer)"), 461: 462: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 463: " VALUES(1)"), 464: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 465: " VALUES(2)"), 466: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 467: " VALUES(3)"), 468: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 469: " VALUES(4)"), 470: {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 471: " VALUES(5)"), 472: {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 473: 474: SelectResult1 = ?RDBMS:selected_absolute_N(1), 475: SelectResult1 = odbc:select(Ref, {absolute, 1}, 3), 476: 477: %% Test that selecting stops at the end of the result set 478: SelectResult2 = ?RDBMS:selected_absolute_N(2), 479: SelectResult2 = odbc:select(Ref, {absolute, 1}, 6, ?TIMEOUT), 480: {'EXIT',{function_clause, _}} = 481: (catch odbc:select(Ref, {absolute, 1}, 2, -1)), 482: ok. 483: 484: %%------------------------------------------------------------------------- 485: create_table_twice(doc) -> 486: ["Test what happens if you try to create the same table twice."]; 487: create_table_twice(suite) -> []; 488: create_table_twice(Config) when is_list(Config) -> 489: Ref = ?config(connection_ref, Config), 490: Table = ?config(tableName, Config), 491: 492: {updated, _} = 493: odbc:sql_query(Ref, 494: "CREATE TABLE " ++ Table ++ 495: " (ID integer, DATA varchar(10))"), 496: {error, Error} = 497: odbc:sql_query(Ref, 498: "CREATE TABLE " ++ Table ++ 499: " (ID integer, DATA varchar(10))"), 500: is_driver_error(Error), 501: ok. 502: 503: %%------------------------------------------------------------------------- 504: delete_table_twice(doc) -> 505: ["Test what happens if you try to delete the same table twice."]; 506: delete_table_twice(suite) -> []; 507: delete_table_twice(Config) when is_list(Config) -> 508: Ref = ?config(connection_ref, Config), 509: Table = ?config(tableName, Config), 510: 511: {updated, _} = 512: odbc:sql_query(Ref, 513: "CREATE TABLE " ++ Table ++ 514: " (ID integer, DATA varchar(10))"), 515: {updated, _} = odbc:sql_query(Ref, "DROP TABLE " ++ Table), 516: {error, Error} = odbc:sql_query(Ref, "DROP TABLE " ++ Table), 517: is_driver_error(Error), 518: ok. 519: 520: %------------------------------------------------------------------------- 521: duplicate_key(doc) -> 522: ["Test what happens if you try to use the same key twice"]; 523: duplicate_key(suit) -> []; 524: duplicate_key(Config) when is_list(Config) -> 525: Ref = ?config(connection_ref, Config), 526: Table = ?config(tableName, Config), 527: 528: {updated, _} = 529: odbc:sql_query(Ref, 530: "CREATE TABLE " ++ Table ++ 531: " (ID integer, DATA char(10), PRIMARY KEY(ID))"), 532: 533: {updated, 1} = 534: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), 535: 536: {error, Error} = 537: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'foo')"), 538: is_driver_error(Error), 539: ok. 540: 541: %%------------------------------------------------------------------------- 542: not_connection_owner(doc) -> 543: ["Test what happens if a process that did not start the connection" 544: " tries to acess it."]; 545: not_connection_owner(suite) -> []; 546: not_connection_owner(Config) when is_list(Config) -> 547: Ref = ?config(connection_ref, Config), 548: Table = ?config(tableName, Config), 549: 550: spawn_link(?MODULE, not_owner, [self(), Ref, Table]), 551: 552: receive 553: continue -> 554: ok 555: end. 556: 557: not_owner(Pid, Ref, Table) -> 558: {error, process_not_owner_of_odbc_connection} = 559: odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ " (ID integer)"), 560: 561: {error, process_not_owner_of_odbc_connection} = 562: odbc:disconnect(Ref), 563: 564: Pid ! continue. 565: 566: %%------------------------------------------------------------------------- 567: no_result_set(doc) -> 568: ["Tests what happens if you try to use a function that needs an " 569: "associated result set when there is none."]; 570: no_result_set(suite) -> []; 571: no_result_set(Config) when is_list(Config) -> 572: Ref = ?config(connection_ref, Config), 573: 574: {error, result_set_does_not_exist} = odbc:first(Ref), 575: {error, result_set_does_not_exist} = odbc:last(Ref), 576: {error, result_set_does_not_exist} = odbc:next(Ref), 577: {error, result_set_does_not_exist} = odbc:prev(Ref), 578: {error, result_set_does_not_exist} = odbc:select(Ref, next, 1), 579: {error, result_set_does_not_exist} = 580: odbc:select(Ref, {absolute, 2}, 1), 581: {error, result_set_does_not_exist} = 582: odbc:select(Ref, {relative, 2}, 1), 583: ok. 584: %%------------------------------------------------------------------------- 585: query_error(doc) -> 586: ["Test what happens if there is an error in the query."]; 587: query_error(suite) -> 588: []; 589: query_error(Config) when is_list(Config) -> 590: Ref = ?config(connection_ref, Config), 591: Table = ?config(tableName, Config), 592: 593: {updated, _} = 594: odbc:sql_query(Ref, 595: "CREATE TABLE " ++ Table ++ 596: " (ID integer, DATA char(10), PRIMARY KEY(ID))"), 597: {updated, 1} = 598: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), 599: 600: {error, _} = 601: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), 602: 603: {error, _} = 604: odbc:sql_query(Ref, "INSERT ONTO " ++ Table ++ " VALUES(1,'bar')"), 605: ok. 606: 607: %%------------------------------------------------------------------------- 608: multiple_select_result_sets(doc) -> 609: ["Test what happens if you have a batch of select queries."]; 610: multiple_select_result_sets(suite) -> 611: []; 612: multiple_select_result_sets(Config) when is_list(Config) -> 613: case ?RDBMS of 614: sqlserver -> 615: Ref = ?config(connection_ref, Config), 616: Table = ?config(tableName, Config), 617: 618: {updated, _} = 619: odbc:sql_query(Ref, 620: "CREATE TABLE " ++ Table ++ 621: " (ID integer, DATA varchar(10), " 622: "PRIMARY KEY(ID))"), 623: {updated, 1} = 624: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 625: " VALUES(1,'bar')"), 626: 627: {updated, 1} = 628: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 629: " VALUES(2, 'foo')"), 630: 631: MultipleResult = ?RDBMS:multiple_select(), 632: 633: MultipleResult = 634: odbc:sql_query(Ref, "SELECT * FROM " ++ Table ++ 635: "; SELECT DATA FROM "++ Table ++ 636: " WHERE ID=2"), 637: ok; 638: _ -> 639: {skip, "multiple result_set not supported"} 640: end. 641: 642: %%------------------------------------------------------------------------- 643: multiple_mix_result_sets(doc) -> 644: ["Test what happens if you have a batch of select and other type of" 645: " queries."]; 646: multiple_mix_result_sets(suite) -> 647: []; 648: multiple_mix_result_sets(Config) when is_list(Config) -> 649: case ?RDBMS of 650: sqlserver -> 651: Ref = ?config(connection_ref, Config), 652: Table = ?config(tableName, Config), 653: 654: {updated, _} = 655: odbc:sql_query(Ref, 656: "CREATE TABLE " ++ Table ++ 657: " (ID integer, DATA varchar(10), " 658: "PRIMARY KEY(ID))"), 659: {updated, 1} = 660: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 661: " VALUES(1,'bar')"), 662: 663: MultipleResult = ?RDBMS:multiple_mix(), 664: 665: MultipleResult = 666: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 667: " VALUES(2,'foo'); UPDATE " ++ Table ++ 668: " SET DATA = 'foobar' WHERE ID =1;SELECT " 669: "* FROM " 670: ++ Table ++ ";DELETE FROM " ++ Table ++ 671: " WHERE ID =1; SELECT DATA FROM " ++ Table), 672: ok; 673: _ -> 674: {skip, "multiple result_set not supported"} 675: end. 676: %%------------------------------------------------------------------------- 677: multiple_result_sets_error(doc) -> 678: ["Test what happens if one of the batched queries fails."]; 679: multiple_result_sets_error(suite) -> 680: []; 681: multiple_result_sets_error(Config) when is_list(Config) -> 682: case ?RDBMS of 683: sqlserver -> 684: Ref = ?config(connection_ref, Config), 685: Table = ?config(tableName, Config), 686: 687: {updated, _} = 688: odbc:sql_query(Ref, 689: "CREATE TABLE " ++ Table ++ 690: " (ID integer, DATA varchar(10), " 691: "PRIMARY KEY(ID))"), 692: {updated, 1} = 693: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 694: " VALUES(1,'bar')"), 695: 696: {error, Error} = 697: odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 698: " VALUES(1,'foo'); SELECT * FROM " ++ Table), 699: is_driver_error(Error), 700: 701: {error, NewError} = 702: odbc:sql_query(Ref, "SELECT * FROM " 703: ++ Table ++ ";INSERT INTO " ++ Table ++ 704: " VALUES(1,'foo')"), 705: is_driver_error(NewError), 706: ok; 707: _ -> 708: {skip, "multiple result_set not supported"} 709: end. 710: 711: %%------------------------------------------------------------------------- 712: param_insert_tiny_int(doc)-> 713: ["Test insertion of tiny ints by parameterized queries."]; 714: param_insert_tiny_int(suite) -> 715: []; 716: param_insert_tiny_int(Config) when is_list(Config) -> 717: case ?RDBMS of 718: sqlserver -> 719: Ref = ?config(connection_ref, Config), 720: Table = ?config(tableName, Config), 721: 722: {updated, _} = 723: odbc:sql_query(Ref, 724: "CREATE TABLE " ++ Table ++ 725: " (FIELD TINYINT)"), 726: 727: {updated, Count} = 728: odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 729: "(FIELD) VALUES(?)", 730: [{sql_tinyint, [1, 2]}], 731: ?TIMEOUT),%Make sure to test timeout clause 732: 733: true = odbc_test_lib:check_row_count(2, Count), 734: 735: InsertResult = ?RDBMS:param_select_tiny_int(), 736: 737: InsertResult = 738: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 739: 740: {'EXIT',{badarg,odbc,param_query,'Params'}} = 741: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 742: "(FIELD) VALUES(?)", 743: [{sql_tinyint, [1, "2"]}])), 744: ok; 745: _ -> 746: {skip, "Type tiniyint not supported"} 747: end. 748: %%------------------------------------------------------------------------- 749: param_insert_small_int(doc)-> 750: ["Test insertion of small ints by parameterized queries."]; 751: param_insert_small_int(suite) -> 752: []; 753: param_insert_small_int(Config) when is_list(Config) -> 754: Ref = ?config(connection_ref, Config), 755: Table = ?config(tableName, Config), 756: 757: {updated, _} = 758: odbc:sql_query(Ref, 759: "CREATE TABLE " ++ Table ++ 760: " (FIELD SMALLINT)"), 761: 762: {updated, Count} = 763: odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 764: "(FIELD) VALUES(?)", [{sql_smallint, [1, 2]}], 765: ?TIMEOUT), %% Make sure to test timeout clause 766: 767: true = odbc_test_lib:check_row_count(2, Count), 768: 769: InsertResult = ?RDBMS:param_select_small_int(), 770: 771: InsertResult = 772: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 773: 774: {'EXIT',{badarg,odbc,param_query,'Params'}} = 775: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 776: "(FIELD) VALUES(?)", 777: [{sql_smallint, [1, "2"]}])), 778: ok. 779: 780: %%------------------------------------------------------------------------- 781: param_insert_int(doc)-> 782: ["Test insertion of ints by parameterized queries."]; 783: param_insert_int(suite) -> 784: []; 785: param_insert_int(Config) when is_list(Config) -> 786: Ref = ?config(connection_ref, Config), 787: Table = ?config(tableName, Config), 788: 789: {updated, _} = 790: odbc:sql_query(Ref, 791: "CREATE TABLE " ++ Table ++ 792: " (FIELD INT)"), 793: 794: Int = ?RDBMS:small_int_max() + 1, 795: 796: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 797: "(FIELD) VALUES(?)", 798: [{sql_integer, [1, Int]}]), 799: true = odbc_test_lib:check_row_count(2, Count), 800: 801: InsertResult = ?RDBMS:param_select_int(), 802: 803: InsertResult = 804: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 805: 806: {'EXIT',{badarg,odbc,param_query,'Params'}} = 807: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 808: "(FIELD) VALUES(?)", 809: [{sql_integer, [1, "2"]}])), 810: ok. 811: 812: %%------------------------------------------------------------------------- 813: param_insert_integer(doc)-> 814: ["Test insertion of integers by parameterized queries."]; 815: param_insert_integer(suite) -> 816: []; 817: param_insert_integer(Config) when is_list(Config) -> 818: Ref = ?config(connection_ref, Config), 819: Table = ?config(tableName, Config), 820: 821: {updated, _} = 822: odbc:sql_query(Ref, 823: "CREATE TABLE " ++ Table ++ 824: " (FIELD INTEGER)"), 825: 826: Int = ?RDBMS:small_int_max() + 1, 827: 828: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 829: "(FIELD) VALUES(?)", 830: [{sql_integer, [1, Int]}]), 831: true = odbc_test_lib:check_row_count(2, Count), 832: 833: InsertResult = ?RDBMS:param_select_int(), 834: 835: InsertResult = 836: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 837: 838: {'EXIT',{badarg,odbc,param_query,'Params'}} = 839: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 840: "(FIELD) VALUES(?)", 841: [{sql_integer, [1, 2.3]}])), 842: ok. 843: 844: %%------------------------------------------------------------------------- 845: param_insert_decimal(doc)-> 846: ["Test insertion of decimal numbers by parameterized queries."]; 847: param_insert_decimal(suite) -> 848: []; 849: param_insert_decimal(Config) when is_list(Config) -> 850: Ref = ?config(connection_ref, Config), 851: Table = ?config(tableName, Config), 852: 853: {updated, _} = 854: odbc:sql_query(Ref, 855: "CREATE TABLE " ++ Table ++ 856: " (FIELD DECIMAL (3,0))"), 857: 858: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 859: "(FIELD) VALUES(?)", 860: [{{sql_decimal, 3, 0}, [1, 2]}]), 861: true = odbc_test_lib:check_row_count(2, Count), 862: 863: InsertResult = ?RDBMS:param_select_decimal(), 864: 865: InsertResult = 866: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 867: 868: {'EXIT',{badarg,odbc,param_query,'Params'}} = 869: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 870: "(FIELD) VALUES(?)", 871: [{{sql_decimal, 3, 0}, [1, "2"]}])), 872: 873: 874: odbc:sql_query(Ref, "DROP TABLE " ++ Table), 875: 876: {updated, _} = 877: odbc:sql_query(Ref, 878: "CREATE TABLE " ++ Table ++ 879: " (FIELD DECIMAL (3,1))"), 880: 881: {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 882: "(FIELD) VALUES(?)", 883: [{{sql_decimal, 3, 1}, [0.25]}]), 884: true = odbc_test_lib:check_row_count(1, NewCount), 885: 886: {selected, Fields, [{Value}]} = 887: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 888: 889: ["FIELD"] = odbc_test_lib:to_upper(Fields), 890: 891: odbc_test_lib:match_float(Value, 0.3, 0.01), 892: 893: ok. 894: 895: %%------------------------------------------------------------------------- 896: param_insert_numeric(doc)-> 897: ["Test insertion of numeric numbers by parameterized queries."]; 898: param_insert_numeric(suite) -> 899: []; 900: param_insert_numeric(Config) when is_list(Config) -> 901: Ref = ?config(connection_ref, Config), 902: Table = ?config(tableName, Config), 903: 904: {updated, _} = 905: odbc:sql_query(Ref, 906: "CREATE TABLE " ++ Table ++ 907: " (FIELD NUMERIC (3,0))"), 908: 909: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 910: "(FIELD) VALUES(?)", 911: [{{sql_numeric,3,0}, [1, 2]}]), 912: 913: true = odbc_test_lib:check_row_count(2, Count), 914: 915: InsertResult = ?RDBMS:param_select_numeric(), 916: 917: InsertResult = 918: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 919: 920: {'EXIT',{badarg,odbc,param_query,'Params'}} = 921: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 922: "(FIELD) VALUES(?)", 923: [{{sql_decimal, 3, 0}, [1, "2"]}])), 924: 925: odbc:sql_query(Ref, "DROP TABLE " ++ Table), 926: 927: {updated, _} = 928: odbc:sql_query(Ref, 929: "CREATE TABLE " ++ Table ++ 930: " (FIELD NUMERIC (3,1))"), 931: 932: {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 933: "(FIELD) VALUES(?)", 934: [{{sql_numeric, 3, 1}, [0.25]}]), 935: 936: true = odbc_test_lib:check_row_count(1, NewCount), 937: 938: {selected, Fileds, [{Value}]} = 939: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 940: 941: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 942: 943: odbc_test_lib:match_float(Value, 0.3, 0.01), 944: ok. 945: 946: %%------------------------------------------------------------------------- 947: param_insert_char(doc)-> 948: ["Test insertion of fixed length string by parameterized queries."]; 949: param_insert_char(suite) -> 950: []; 951: param_insert_char(Config) when is_list(Config) -> 952: Ref = ?config(connection_ref, Config), 953: Table = ?config(tableName, Config), 954: 955: {updated, _} = 956: odbc:sql_query(Ref, 957: "CREATE TABLE " ++ Table ++ 958: " (FIELD CHAR (10))"), 959: 960: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 961: "(FIELD) VALUES(?)", 962: [{{sql_char, 10}, 963: ["foofoofoof", "0123456789"]}]), 964: true = odbc_test_lib:check_row_count(2, Count), 965: 966: {selected,Fileds,[{"foofoofoof"}, {"0123456789"}]} = 967: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 968: 969: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 970: 971: {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 972: "(FIELD) VALUES(?)", 973: [{{sql_char, 10}, 974: ["foo", "01234567890"]}]), 975: 976: {'EXIT',{badarg,odbc,param_query,'Params'}} = 977: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 978: "(FIELD) VALUES(?)", 979: [{{sql_char, 10}, ["1", 2.3]}])), 980: ok. 981: 982: %%------------------------------------------------------------------------- 983: param_insert_character(doc)-> 984: ["Test insertion of fixed length string by parameterized queries."]; 985: param_insert_character(suite) -> 986: []; 987: param_insert_character(Config) when is_list(Config) -> 988: Ref = ?config(connection_ref, Config), 989: Table = ?config(tableName, Config), 990: 991: {updated, _} = 992: odbc:sql_query(Ref, 993: "CREATE TABLE " ++ Table ++ 994: " (FIELD CHARACTER (10))"), 995: 996: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 997: "(FIELD) VALUES(?)", 998: [{{sql_char, 10}, 999: ["foofoofoof", "0123456789"]}]), 1000: 1001: true = odbc_test_lib:check_row_count(2, Count), 1002: 1003: {selected, Fileds, [{"foofoofoof"}, {"0123456789"}]} = 1004: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1005: 1006: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 1007: 1008: {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1009: "(FIELD) VALUES(?)", 1010: [{{sql_char, 10}, 1011: ["foo", "01234567890"]}]), 1012: 1013: {'EXIT',{badarg,odbc,param_query,'Params'}} = 1014: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1015: "(FIELD) VALUES(?)", 1016: [{{sql_char, 10}, ["1", 2]}])), 1017: ok. 1018: 1019: %%------------------------------------------------------------------------ 1020: param_insert_char_varying(doc)-> 1021: ["Test insertion of variable length strings by parameterized queries."]; 1022: param_insert_char_varying(suite) -> 1023: []; 1024: param_insert_char_varying(Config) when is_list(Config) -> 1025: Ref = ?config(connection_ref, Config), 1026: Table = ?config(tableName, Config), 1027: 1028: {updated, _} = 1029: odbc:sql_query(Ref, 1030: "CREATE TABLE " ++ Table ++ 1031: " (FIELD CHAR VARYING(10))"), 1032: 1033: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1034: "(FIELD) VALUES(?)", 1035: [{{sql_varchar, 10}, 1036: ["foo", "0123456789"]}]), 1037: 1038: true = odbc_test_lib:check_row_count(2, Count), 1039: 1040: {selected, Fileds, [{"foo"}, {"0123456789"}]} = 1041: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1042: 1043: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 1044: 1045: {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1046: "(FIELD) VALUES(?)", 1047: [{{sql_varchar, 10}, 1048: ["foo", "01234567890"]}]), 1049: 1050: {'EXIT',{badarg,odbc,param_query,'Params'}} = 1051: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1052: "(FIELD) VALUES(?)", 1053: [{{sql_varchar, 10}, ["1", 2.3]}])), 1054: ok. 1055: 1056: %%------------------------------------------------------------------------- 1057: param_insert_character_varying(doc)-> 1058: ["Test insertion of variable length strings by parameterized queries."]; 1059: param_insert_character_varying(suite) -> 1060: []; 1061: param_insert_character_varying(Config) when is_list(Config) -> 1062: Ref = ?config(connection_ref, Config), 1063: Table = ?config(tableName, Config), 1064: 1065: {updated, _} = 1066: odbc:sql_query(Ref, 1067: "CREATE TABLE " ++ Table ++ 1068: " (FIELD CHARACTER VARYING(10))"), 1069: 1070: 1071: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1072: "(FIELD) VALUES(?)", 1073: [{{sql_varchar, 10}, 1074: ["foo", "0123456789"]}]), 1075: 1076: true = odbc_test_lib:check_row_count(2, Count), 1077: 1078: {selected, Fileds, [{"foo"}, {"0123456789"}]} = 1079: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1080: 1081: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 1082: 1083: {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1084: "(FIELD) VALUES(?)", 1085: [{{sql_varchar, 10}, 1086: ["foo", "01234567890"]}]), 1087: 1088: {'EXIT',{badarg,odbc,param_query,'Params'}} = 1089: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1090: "(FIELD) VALUES(?)", 1091: [{{sql_varchar, 10}, ["1", 2]}])), 1092: ok. 1093: %%------------------------------------------------------------------------- 1094: param_insert_float(doc)-> 1095: ["Test insertion of floats by parameterized queries."]; 1096: param_insert_float(suite) -> 1097: []; 1098: param_insert_float(Config) when is_list(Config) -> 1099: Ref = ?config(connection_ref, Config), 1100: Table = ?config(tableName, Config), 1101: 1102: {updated, _} = 1103: odbc:sql_query(Ref, 1104: "CREATE TABLE " ++ Table ++ 1105: " (FIELD FLOAT(5))"), 1106: 1107: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1108: "(FIELD) VALUES(?)", 1109: [{{sql_float,5}, [1.3, 1.2]}]), 1110: 1111: true = odbc_test_lib:check_row_count(2, Count), 1112: 1113: {selected, Fileds, [{Float1},{Float2}]} = 1114: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1115: 1116: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 1117: 1118: case (odbc_test_lib:match_float(Float1, 1.3, 0.000001) and 1119: odbc_test_lib:match_float(Float2, 1.2, 0.000001)) of 1120: true -> 1121: ok; 1122: false -> 1123: test_server:fail(float_numbers_do_not_match) 1124: end, 1125: 1126: {'EXIT',{badarg,odbc,param_query,'Params'}} = 1127: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1128: "(FIELD) VALUES(?)", 1129: [{{sql_float, 5}, [1.0, "2"]}])), 1130: ok. 1131: 1132: %%------------------------------------------------------------------------- 1133: param_insert_real(doc)-> 1134: ["Test insertion of real numbers by parameterized queries."]; 1135: param_insert_real(suite) -> 1136: []; 1137: param_insert_real(Config) when is_list(Config) -> 1138: Ref = ?config(connection_ref, Config), 1139: Table = ?config(tableName, Config), 1140: 1141: {updated, _} = 1142: odbc:sql_query(Ref, 1143: "CREATE TABLE " ++ Table ++ 1144: " (FIELD REAL)"), 1145: 1146: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1147: "(FIELD) VALUES(?)", 1148: [{sql_real, [1.3, 1.2]}]), 1149: 1150: true = odbc_test_lib:check_row_count(2, Count), 1151: 1152: %_InsertResult = ?RDBMS:param_select_real(), 1153: 1154: {selected, Fileds, [{Real1},{Real2}]} = 1155: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1156: 1157: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 1158: 1159: case (odbc_test_lib:match_float(Real1, 1.3, 0.000001) and 1160: odbc_test_lib:match_float(Real2, 1.2, 0.000001)) of 1161: true -> 1162: ok; 1163: false -> 1164: test_server:fail(real_numbers_do_not_match) 1165: end, 1166: 1167: {'EXIT',{badarg,odbc,param_query,'Params'}} = 1168: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1169: "(FIELD) VALUES(?)", 1170: [{sql_real,[1.0, "2"]}])), 1171: ok. 1172: 1173: %%------------------------------------------------------------------------- 1174: param_insert_double(doc)-> 1175: ["Test insertion of doubles by parameterized queries."]; 1176: param_insert_double(suite) -> 1177: []; 1178: param_insert_double(Config) when is_list(Config) -> 1179: Ref = ?config(connection_ref, Config), 1180: Table = ?config(tableName, Config), 1181: 1182: {updated, _} = 1183: odbc:sql_query(Ref, 1184: "CREATE TABLE " ++ Table ++ 1185: " (FIELD DOUBLE PRECISION)"), 1186: 1187: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1188: "(FIELD) VALUES(?)", 1189: [{sql_double, [1.3, 1.2]}]), 1190: 1191: true = odbc_test_lib:check_row_count(2, Count), 1192: 1193: {selected, Fileds, [{Double1},{Double2}]} = 1194: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1195: 1196: ["FIELD"] = odbc_test_lib:to_upper(Fileds), 1197: 1198: case (odbc_test_lib:match_float(Double1, 1.3, 0.000001) and 1199: odbc_test_lib:match_float(Double2, 1.2, 0.000001)) of 1200: true -> 1201: ok; 1202: false -> 1203: test_server:fail(double_numbers_do_not_match) 1204: end, 1205: 1206: {'EXIT',{badarg,odbc,param_query,'Params'}} = 1207: (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1208: "(FIELD) VALUES(?)", 1209: [{sql_double, [1.0, "2"]}])), 1210: ok. 1211: 1212: %%------------------------------------------------------------------------- 1213: param_insert_mix(doc)-> 1214: ["Test insertion of a mixture of datatypes by parameterized queries."]; 1215: param_insert_mix(suite) -> 1216: []; 1217: param_insert_mix(Config) when is_list(Config) -> 1218: Ref = ?config(connection_ref, Config), 1219: Table = ?config(tableName, Config), 1220: 1221: {updated, _} = 1222: odbc:sql_query(Ref, 1223: "CREATE TABLE " ++ Table ++ 1224: " (ID INTEGER, DATA CHARACTER VARYING(10)," 1225: " PRIMARY KEY(ID))"), 1226: 1227: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1228: "(ID, DATA) VALUES(?, ?)", 1229: [{sql_integer, [1, 2]}, 1230: {{sql_varchar, 10}, ["foo", "bar"]}]), 1231: 1232: true = odbc_test_lib:check_row_count(2, Count), 1233: 1234: InsertResult = ?RDBMS:param_select_mix(), 1235: 1236: InsertResult = 1237: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1238: ok. 1239: %%------------------------------------------------------------------------- 1240: param_update(doc)-> 1241: ["Test parameterized update query."]; 1242: param_update(suite) -> 1243: []; 1244: param_update(Config) when is_list(Config) -> 1245: Ref = ?config(connection_ref, Config), 1246: Table = ?config(tableName, Config), 1247: 1248: {updated, _} = 1249: odbc:sql_query(Ref, 1250: "CREATE TABLE " ++ Table ++ 1251: " (ID INTEGER, DATA CHARACTER VARYING(10)," 1252: " PRIMARY KEY(ID))"), 1253: 1254: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1255: "(ID, DATA) VALUES(?, ?)", 1256: [{sql_integer, [1, 2, 3]}, 1257: {{sql_varchar, 10}, 1258: ["foo", "bar", "baz"]}]), 1259: 1260: true = odbc_test_lib:check_row_count(3, Count), 1261: 1262: {updated, NewCount} = odbc:param_query(Ref, "UPDATE " ++ Table ++ 1263: " SET DATA = 'foobar' WHERE ID = ?", 1264: [{sql_integer, [1, 2]}]), 1265: 1266: true = odbc_test_lib:check_row_count(2, NewCount), 1267: 1268: UpdateResult = ?RDBMS:param_update(), 1269: 1270: UpdateResult = 1271: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1272: ok. 1273: 1274: %%------------------------------------------------------------------------- 1275: delete_nonexisting_row(doc) -> % OTP-5759 1276: ["Make a delete...where with false conditions (0 rows deleted). ", 1277: "This used to give an error message (see ticket OTP-5759)."]; 1278: delete_nonexisting_row(Config) when is_list(Config) -> 1279: Ref = ?config(connection_ref, Config), 1280: Table = ?config(tableName, Config), 1281: 1282: {updated, _} = 1283: odbc:sql_query(Ref, "CREATE TABLE " ++ Table 1284: ++ " (ID INTEGER, DATA CHARACTER VARYING(10))"), 1285: {updated, Count} = 1286: odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1287: "(ID, DATA) VALUES(?, ?)", 1288: [{sql_integer, [1, 2, 3]}, 1289: {{sql_varchar, 10}, ["foo", "bar", "baz"]}]), 1290: 1291: true = odbc_test_lib:check_row_count(3, Count), 1292: 1293: {updated, NewCount} = 1294: odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ " WHERE ID = 8"), 1295: 1296: true = odbc_test_lib:check_row_count(0, NewCount), 1297: 1298: {updated, _} = 1299: odbc:sql_query(Ref, "DROP TABLE "++ Table), 1300: 1301: ok. 1302: 1303: %%------------------------------------------------------------------------- 1304: param_delete(doc) -> 1305: ["Test parameterized delete query."]; 1306: param_delete(suite) -> 1307: []; 1308: param_delete(Config) when is_list(Config) -> 1309: Ref = ?config(connection_ref, Config), 1310: Table = ?config(tableName, Config), 1311: 1312: {updated, _} = 1313: odbc:sql_query(Ref, 1314: "CREATE TABLE " ++ Table ++ 1315: " (ID INTEGER, DATA CHARACTER VARYING(10)," 1316: " PRIMARY KEY(ID))"), 1317: 1318: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1319: "(ID, DATA) VALUES(?, ?)", 1320: [{sql_integer, [1, 2, 3]}, 1321: {{sql_varchar, 10}, 1322: ["foo", "bar", "baz"]}]), 1323: true = odbc_test_lib:check_row_count(3, Count), 1324: 1325: {updated, NewCount} = odbc:param_query(Ref, "DELETE FROM " ++ Table ++ 1326: " WHERE ID = ?", 1327: [{sql_integer, [1, 2]}]), 1328: 1329: true = odbc_test_lib:check_row_count(2, NewCount), 1330: 1331: UpdateResult = ?RDBMS:param_delete(), 1332: 1333: UpdateResult = 1334: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1335: ok. 1336: 1337: 1338: %%------------------------------------------------------------------------- 1339: param_select(doc) -> 1340: ["Test parameterized select query."]; 1341: param_select(suite) -> 1342: []; 1343: param_select(Config) when is_list(Config) -> 1344: Ref = ?config(connection_ref, Config), 1345: Table = ?config(tableName, Config), 1346: 1347: {updated, _} = 1348: odbc:sql_query(Ref, 1349: "CREATE TABLE " ++ Table ++ 1350: " (ID INTEGER, DATA CHARACTER VARYING(10)," 1351: " PRIMARY KEY(ID))"), 1352: 1353: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1354: "(ID, DATA) VALUES(?, ?)", 1355: [{sql_integer, [1, 2, 3]}, 1356: {{sql_varchar, 10}, 1357: ["foo", "bar", "foo"]}]), 1358: 1359: true = odbc_test_lib:check_row_count(3, Count), 1360: 1361: SelectResult = ?RDBMS:param_select(), 1362: 1363: SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++ 1364: " WHERE DATA = ?", 1365: [{{sql_varchar, 10}, ["foo"]}]), 1366: ok. 1367: 1368: %%------------------------------------------------------------------------- 1369: param_select_empty_params(doc) -> 1370: ["Test parameterized select query with no parameters."]; 1371: param_select_empty_params(suite) -> 1372: []; 1373: param_select_empty_params(Config) when is_list(Config) -> 1374: Ref = ?config(connection_ref, Config), 1375: Table = ?config(tableName, Config), 1376: 1377: {updated, _} = 1378: odbc:sql_query(Ref, 1379: "CREATE TABLE " ++ Table ++ 1380: " (ID INTEGER, DATA CHARACTER VARYING(10)," 1381: " PRIMARY KEY(ID))"), 1382: 1383: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1384: "(ID, DATA) VALUES(?, ?)", 1385: [{sql_integer, [1, 2, 3]}, 1386: {{sql_varchar, 10}, 1387: ["foo", "bar", "foo"]}]), 1388: 1389: true = odbc_test_lib:check_row_count(3, Count), 1390: 1391: SelectResult = ?RDBMS:param_select(), 1392: 1393: SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++ 1394: " WHERE DATA = \'foo\'", 1395: []), 1396: ok. 1397: 1398: %%------------------------------------------------------------------------- 1399: param_delete_empty_params(doc) -> 1400: ["Test parameterized delete query with no parameters."]; 1401: param_delete_empty_params(suite) -> 1402: []; 1403: param_delete_empty_params(Config) when is_list(Config) -> 1404: Ref = ?config(connection_ref, Config), 1405: Table = ?config(tableName, Config), 1406: 1407: {updated, _} = 1408: odbc:sql_query(Ref, 1409: "CREATE TABLE " ++ Table ++ 1410: " (ID INTEGER, DATA CHARACTER VARYING(10)," 1411: " PRIMARY KEY(ID))"), 1412: 1413: {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 1414: "(ID, DATA) VALUES(?, ?)", 1415: [{sql_integer, [1, 2, 3]}, 1416: {{sql_varchar, 10}, 1417: ["foo", "bar", "baz"]}]), 1418: true = odbc_test_lib:check_row_count(3, Count), 1419: 1420: {updated, NewCount} = odbc:param_query(Ref, "DELETE FROM " ++ Table ++ 1421: " WHERE ID = 1 OR ID = 2", 1422: []), 1423: 1424: true = odbc_test_lib:check_row_count(2, NewCount), 1425: 1426: UpdateResult = ?RDBMS:param_delete(), 1427: 1428: UpdateResult = 1429: odbc:sql_query(Ref, "SELECT * FROM " ++ Table), 1430: ok. 1431: 1432: %%------------------------------------------------------------------------- 1433: describe_integer(doc) -> 1434: ["Test describe_table/[2,3] for integer columns."]; 1435: describe_integer(suite) -> 1436: []; 1437: describe_integer(Config) when is_list(Config) -> 1438: Ref = ?config(connection_ref, Config), 1439: Table = ?config(tableName, Config), 1440: 1441: {updated, _} = 1442: odbc:sql_query(Ref, 1443: "CREATE TABLE " ++ Table ++ 1444: " (myint1 SMALLINT, myint2 INT, myint3 INTEGER)"), 1445: 1446: Decs = ?RDBMS:describe_integer(), 1447: %% Make sure to test timeout clause 1448: Decs = odbc:describe_table(Ref, Table, ?TIMEOUT), 1449: ok. 1450: 1451: %%------------------------------------------------------------------------- 1452: describe_string(doc) -> 1453: ["Test describe_table/[2,3] for string columns."]; 1454: describe_string(suite) -> 1455: []; 1456: describe_string(Config) when is_list(Config) -> 1457: Ref = ?config(connection_ref, Config), 1458: Table = ?config(tableName, Config), 1459: 1460: {updated, _} = 1461: odbc:sql_query(Ref, 1462: "CREATE TABLE " ++ Table ++ 1463: " (str1 char(10), str2 character(10), " 1464: "str3 CHAR VARYING(10), str4 " 1465: "CHARACTER VARYING(10))"), 1466: 1467: Decs = ?RDBMS:describe_string(), 1468: 1469: Decs = odbc:describe_table(Ref, Table), 1470: ok. 1471: 1472: %%------------------------------------------------------------------------- 1473: describe_floating(doc) -> 1474: ["Test describe_table/[2,3] for floting columns."]; 1475: describe_floating(suite) -> 1476: []; 1477: describe_floating(Config) when is_list(Config) -> 1478: Ref = ?config(connection_ref, Config), 1479: Table = ?config(tableName, Config), 1480: 1481: {updated, _} = 1482: odbc:sql_query(Ref, 1483: "CREATE TABLE " ++ Table ++ 1484: " (f FLOAT(5), r REAL, " 1485: "d DOUBLE PRECISION)"), 1486: 1487: Decs = ?RDBMS:describe_floating(), 1488: 1489: Decs = odbc:describe_table(Ref, Table), 1490: ok. 1491: 1492: %%------------------------------------------------------------------------- 1493: describe_dec_num(doc) -> 1494: ["Test describe_table/[2,3] for decimal and numerical columns"]; 1495: describe_dec_num(suite) -> 1496: []; 1497: describe_dec_num(Config) when is_list(Config) -> 1498: 1499: Ref = ?config(connection_ref, Config), 1500: Table = ?config(tableName, Config), 1501: 1502: {updated, _} = 1503: odbc:sql_query(Ref, 1504: "CREATE TABLE " ++ Table ++ 1505: " (mydec DECIMAL(9,3), mynum NUMERIC(9,2))"), 1506: 1507: Decs = ?RDBMS:describe_dec_num(), 1508: 1509: Decs = odbc:describe_table(Ref, Table), 1510: ok. 1511: 1512: 1513: %%------------------------------------------------------------------------- 1514: describe_timestamp(doc) -> 1515: ["Test describe_table/[2,3] for tinmestap columns"]; 1516: describe_timestamp(suite) -> 1517: []; 1518: describe_timestamp(Config) when is_list(Config) -> 1519: 1520: Ref = ?config(connection_ref, Config), 1521: Table = ?config(tableName, Config), 1522: 1523: {updated, _} = % Value == 0 || -1 driver dependent! 1524: odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ 1525: ?RDBMS:create_timestamp_table()), 1526: 1527: Decs = ?RDBMS:describe_timestamp(), 1528: 1529: Decs = odbc:describe_table(Ref, Table), 1530: ok. 1531: 1532: %%------------------------------------------------------------------------- 1533: describe_no_such_table(doc) -> 1534: ["Test what happens if you try to describe a table that does not exist."]; 1535: describe_no_such_table(suite) -> 1536: []; 1537: describe_no_such_table(Config) when is_list(Config) -> 1538: 1539: Ref = ?config(connection_ref, Config), 1540: Table = ?config(tableName, Config), 1541: 1542: {error, _ } = odbc:describe_table(Ref, Table), 1543: ok. 1544: 1545: %%------------------------------------------------------------------------- 1546: %% Internal functions 1547: %%------------------------------------------------------------------------- 1548: 1549: is_driver_error(Error) -> 1550: case is_list(Error) of 1551: true -> 1552: test_server:format("Driver error ~p~n", [Error]), 1553: ok; 1554: false -> 1555: test_server:fail(Error) 1556: end. 1557: is_supported_multiple_resultsets(sqlserver) -> 1558: true; 1559: is_supported_multiple_resultsets(_) -> 1560: false.