Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 1 commit
  • 6 files changed
  • 0 comments
  • 1 contributor
Oct 31, 2012
Martynas Pumputis Add odbc:auto_commit/2,3
New API call allows to change auto_commit mode after connection is
established. Might be useful with Oracle DB due to buggy unixodbc-oracle
driver.
e63b25c
21 lib/odbc/c_src/odbcserver.c
@@ -148,6 +148,7 @@ static db_result_msg db_select_count(byte *sql,db_state *state);
148 148 static db_result_msg db_select(byte *args, db_state *state);
149 149 static db_result_msg db_param_query(byte *buffer, db_state *state);
150 150 static db_result_msg db_describe_table(byte *sql, db_state *state);
  151 +static db_result_msg db_auto_commit(byte *how, db_state *state);
151 152
152 153 /* ------------- Encode/decode functions -------- ------------------------*/
153 154
@@ -418,6 +419,8 @@ static db_result_msg handle_db_request(byte *reqstring, db_state *state)
418 419 return db_param_query(args, state);
419 420 case DESCRIBE:
420 421 return db_describe_table(args, state);
  422 + case AUTO_COMMIT:
  423 + return db_auto_commit(args, state);
421 424 default:
422 425 DO_EXIT(EXIT_FAILURE); /* Should not happen */
423 426 }
@@ -934,6 +937,24 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
934 937 return msg;
935 938 }
936 939
  940 +static db_result_msg db_auto_commit(byte *how, db_state *state)
  941 +{
  942 + SQLLEN auto_commit_mode;
  943 +
  944 + if(how[0] == ON) {
  945 + auto_commit_mode = SQL_AUTOCOMMIT_ON;
  946 + } else {
  947 + auto_commit_mode = SQL_AUTOCOMMIT_OFF;
  948 + }
  949 +
  950 + if(!sql_success(SQLSetConnectAttr(connection_handle(state),
  951 + SQL_ATTR_AUTOCOMMIT,
  952 + (SQLPOINTER)auto_commit_mode, 0)))
  953 + DO_EXIT(EXIT_AUTO_COMMIT);
  954 +
  955 + return encode_atom_message("ok");
  956 +}
  957 +
937 958
938 959 /* ----------------- Encode/decode functions -----------------------------*/
939 960
2  lib/odbc/c_src/odbcserver.h
@@ -61,6 +61,7 @@
61 61 #define PARAM_QUERY 16
62 62 #define DESCRIBE 17
63 63 #define SHUTDOWN 18
  64 +#define AUTO_COMMIT 19
64 65 #define LENGTH_INDICATOR_SIZE 4
65 66 #define INT_VALUE 1
66 67 #define STR_VALUE 2
@@ -91,6 +92,7 @@
91 92 #define EXIT_DESC 21
92 93 #define EXIT_BIND 22
93 94 #define EXIT_DRIVER_INFO 23
  95 +#define EXIT_AUTO_COMMIT 24
94 96
95 97 /* COL_SIZE */
96 98 #define COL_SQL_SMALLINT 5
14 lib/odbc/doc/src/odbc.xml
@@ -119,6 +119,20 @@
119 119 </section>
120 120 <funcs>
121 121 <func>
  122 + <name>auto_commit(Ref, How) -></name>
  123 + <name>auto_commit(Ref, How, TimeOut) -> ok | {error, Reason} </name>
  124 + <fsummary>Changes auto_commit mode. after connection is established.</fsummary>
  125 + <type>
  126 + <v>Ref = connection_reference() </v>
  127 + <v>How = on | off</v>
  128 + <v>TimeOut = time_out()</v>
  129 + </type>
  130 + <desc>
  131 + <p>Changes auto_commit mode after connection is established.</p>
  132 + </desc>
  133 + </func>
  134 +
  135 + <func>
122 136 <name>commit(Ref, CommitMode) -></name>
123 137 <name>commit(Ref, CommitMode, TimeOut) -> ok | {error, Reason} </name>
124 138 <fsummary>Commits or rollbacks a transaction. </fsummary>
36 lib/odbc/src/odbc.erl
@@ -32,7 +32,7 @@
32 32 sql_query/3, select_count/2, select_count/3, first/1, first/2,
33 33 last/1, last/2, next/1, next/2, prev/1, prev/2, select/3,
34 34 select/4, param_query/3, param_query/4, describe_table/2,
35   - describe_table/3]).
  35 + describe_table/3, auto_commit/2, auto_commit/3]).
36 36
37 37 %%-------------------------------------------------------------------------
38 38 %% supervisor callbacks
@@ -103,7 +103,6 @@ stop() ->
103 103 %% to the database.
104 104 %%-------------------------------------------------------------------------
105 105 connect(ConnectionStr, Options) when is_list(ConnectionStr), is_list(Options) ->
106   -
107 106 %% Spawn the erlang control process.
108 107 try supervisor:start_child(odbc_sup, [[{client, self()}]]) of
109 108 {ok, Pid} ->
@@ -400,6 +399,30 @@ describe_table(ConnectionReference, Table, TimeOut)
400 399 when is_pid(ConnectionReference),is_list(Table),is_integer(TimeOut),TimeOut>0 ->
401 400 ODBCCmd = [?DESCRIBE, "SELECT * FROM " ++ Table],
402 401 call(ConnectionReference, {describe_table, ODBCCmd}, TimeOut).
  402 +
  403 +%%--------------------------------------------------------------------------
  404 +%% auto_commit(ConnectionReference, How, <TimeOut>) -> ok.
  405 +%%
  406 +%% How - on | off.
  407 +%% Description: Enable or dissable auto commit for given connection.
  408 +%%--------------------------------------------------------------------------
  409 +auto_commit(ConnectionReference, How) ->
  410 + auto_commit(ConnectionReference, How, ?DEFAULT_TIMEOUT).
  411 +
  412 +auto_commit(ConnectionReference, How, TimeOut) when
  413 + is_pid(ConnectionReference) andalso is_atom(How) andalso
  414 + (
  415 + (is_integer(TimeOut) andalso TimeOut > 0) orelse
  416 + TimeOut =:= infinity
  417 + ) ->
  418 + AutoCommitMode =
  419 + case How of
  420 + on -> ?ON;
  421 + off -> ?OFF
  422 + end,
  423 + ODBCCmd = [?AUTO_COMMIT, AutoCommitMode],
  424 + call(ConnectionReference, {auto_commit, ODBCCmd}, TimeOut).
  425 +
403 426 %%%=========================================================================
404 427 %%% Start/stop
405 428 %%%=========================================================================
@@ -565,6 +588,15 @@ handle_msg({describe_table, ODBCCmd}, Timeout, State) ->
565 588 odbc_send(State#state.odbc_socket, ODBCCmd),
566 589 {noreply, State#state{result_set = undefined}, Timeout};
567 590
  591 +handle_msg({auto_commit, ODBCCmd}, Timeout, State) ->
  592 + odbc_send(State#state.odbc_socket, ODBCCmd),
  593 + How =
  594 + case ODBCCmd of
  595 + [_, ?ON] -> on;
  596 + [_, ?OFF] -> off
  597 + end,
  598 + {noreply, State#state{auto_commit_mode=How}, Timeout};
  599 +
568 600 handle_msg({select_count, ODBCCmd}, Timeout, State) ->
569 601 odbc_send(State#state.odbc_socket, ODBCCmd),
570 602 {noreply, State#state{result_set = exists}, Timeout};
4 lib/odbc/src/odbc_internal.hrl
@@ -49,6 +49,7 @@
49 49 -define(PARAM_QUERY, 16).
50 50 -define(DESCRIBE, 17).
51 51 -define(SHUTDOWN, 18).
  52 +-define(AUTO_COMMIT, 19).
52 53 -define(LENGTH_INDICATOR_SIZE, 4).
53 54 -define(INT_VALUE, 1).
54 55 -define(STR_VALUE, 2).
@@ -104,6 +105,7 @@
104 105 -define(EXIT_DESC, 21).
105 106 -define(EXIT_BIND, 22).
106 107 -define(EXIT_DRIVER_INFO, 23).
  108 +-define(EXIT_AUTO_COMMIT, 24).
107 109
108 110 %% Misc constants
109 111 -define(DEFAULT_TIMEOUT, infinity).
@@ -160,6 +162,8 @@
160 162 could_not_bind_data_buffers;
161 163 (?EXIT_DRIVER_INFO) ->
162 164 collecting_of_driver_information_faild;
  165 + (?EXIT_AUTO_COMMIT) ->
  166 + changing_auto_commit;
163 167 (_) ->
164 168 killed
165 169 end)).
36 lib/odbc/test/odbc_query_SUITE.erl
@@ -49,6 +49,7 @@ all() ->
49 49 not_connection_owner, no_result_set, query_error,
50 50 {group, multiple_result_sets},
51 51 {group, parameterized_queries}, {group, describe_table},
  52 + auto_commit,
52 53 delete_nonexisting_row];
53 54 Other -> {skip, Other}
54 55 end.
@@ -1458,6 +1459,41 @@ describe_no_such_table(Config) when is_list(Config) ->
1458 1459 ok.
1459 1460
1460 1461 %%-------------------------------------------------------------------------
  1462 +
  1463 +auto_commit(doc) ->
  1464 + ["Test auto_commit/2 after connection is established."];
  1465 +auto_commit(suite) ->
  1466 + [];
  1467 +auto_commit(Config) when is_list(Config) ->
  1468 + Ref1 = ?config(connection_ref, Config),
  1469 + {ok, Ref2} = odbc:connect(?RDBMS:connection_string(),
  1470 + odbc_test_lib:platform_options()),
  1471 +
  1472 + Table = ?config(tableName, Config),
  1473 +
  1474 + {updated, _} =
  1475 + odbc:sql_query(Ref1,
  1476 + "CREATE TABLE " ++ Table ++
  1477 + " (ID integer, DATA varchar(10))"),
  1478 +
  1479 + ok = odbc:auto_commit(Ref1, off),
  1480 +
  1481 + {updated, 1} =
  1482 + odbc:sql_query(Ref1, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
  1483 + {ok, 0} = odbc:select_count(Ref2, "SELECT * FROM " ++ Table),
  1484 +
  1485 + ok = odbc:commit(Ref1, commit),
  1486 + {ok, 1} = odbc:select_count(Ref2, "SELECT * FROM " ++ Table),
  1487 +
  1488 + ok = odbc:auto_commit(Ref1, on),
  1489 +
  1490 + odbc:sql_query(Ref1, "INSERT INTO " ++ Table ++ " VALUES(2,'foo')"),
  1491 + {ok, 2} = odbc:select_count(Ref2, "SELECT * FROM " ++ Table),
  1492 +
  1493 + ok = odbc:disconnect(Ref1),
  1494 + ok = odbc:disconnect(Ref2).
  1495 +
  1496 +%%-------------------------------------------------------------------------
1461 1497 %% Internal functions
1462 1498 %%-------------------------------------------------------------------------
1463 1499

No commit comments for this range

Something went wrong with that request. Please try again.