diff options
Diffstat (limited to 'odb/oracle/statement.cxx')
-rw-r--r-- | odb/oracle/statement.cxx | 223 |
1 files changed, 176 insertions, 47 deletions
diff --git a/odb/oracle/statement.cxx b/odb/oracle/statement.cxx index 13b9553..5ad867a 100644 --- a/odb/oracle/statement.cxx +++ b/odb/oracle/statement.cxx @@ -137,6 +137,9 @@ namespace odb statement:: ~statement () { + if (empty ()) + return; + { odb::tracer* t; if ((t = conn_.transaction_tracer ()) || @@ -192,22 +195,73 @@ namespace odb } statement:: - statement (connection_type& conn, const string& text) + statement (connection_type& conn, + const string& text, + statement_kind sk, + const binding* process, + bool optimize) : conn_ (conn), udata_ (0), usize_ (0) { - init (text.c_str (), text.size ()); + init (text.c_str (), text.size (), sk, process, optimize); } statement:: - statement (connection_type& conn, const char* text) + statement (connection_type& conn, + const char* text, + statement_kind sk, + const binding* process, + bool optimize) : conn_ (conn), udata_ (0), usize_ (0) { - init (text, strlen (text)); + init (text, strlen (text), sk, process, optimize); } void statement:: - init (const char* text, size_t text_size) + init (const char* text, + size_t text_size, + statement_kind sk, + const binding* proc, + bool optimize) { + string tmp; + if (proc != 0) + { + switch (sk) + { + case statement_select: + process_select (text, + &proc->bind->buffer, proc->count, sizeof (bind), + '"', '"', + optimize, + tmp, + false); // No AS in JOINs. + break; + case statement_insert: + process_insert (text, + &proc->bind->buffer, proc->count, sizeof (bind), + ':', + tmp); + break; + case statement_update: + process_update (text, + &proc->bind->buffer, proc->count, sizeof (bind), + ':', + tmp); + break; + case statement_delete: + case statement_generic: + assert (false); + } + + text = tmp.c_str (); + text_size = tmp.size (); + } + + // Empty statement. + // + if (*text == '\0') + return; + OCIError* err (conn_.error_handle ()); OCIStmt* handle (0); @@ -254,7 +308,7 @@ namespace odb return reinterpret_cast<char*> (s); } - void statement:: + ub4 statement:: bind_param (bind* b, size_t n) { // Figure out how many unbind elements we will need and allocate them. @@ -264,6 +318,9 @@ namespace odb for (size_t i (0); i < n; ++i) { + if (b[i].buffer == 0) // Skip NULL entries. + continue; + switch (b[i].type) { case bind::timestamp: @@ -301,13 +358,14 @@ namespace odb OCIError* err (conn_.error_handle ()); OCIEnv* env (conn_.database ().environment ()); - // The parameter position in OCIBindByPos is specified as a 1-based - // index. - // - n++; - - for (ub4 i (1); i < n; ++i, ++b) + ub4 i (0); + for (bind* end (b + n); b != end; ++b) { + if (b->buffer == 0) // Skip NULL entries. + continue; + + i++; // Column index is 1-based. + void* value; sb4 capacity; ub2* size (0); @@ -617,9 +675,11 @@ namespace odb translate_error (err, r); } } + + return i; } - void statement:: + ub4 statement:: bind_result (bind* b, size_t c, size_t p) { ODB_POTENTIALLY_UNUSED (p); @@ -628,8 +688,14 @@ namespace odb OCIError* err (conn_.error_handle ()); OCIEnv* env (conn_.database ().environment ()); - for (size_t i (1); i <= c; ++i, ++b) + ub4 i (0); + for (bind* end (b + c); b != end; ++b) { + if (b->buffer == 0) // Skip NULL entries. + continue; + + i++; // Column index is 1-based. + void* value; sb4 capacity; ub2* size (0); @@ -816,6 +882,8 @@ namespace odb translate_error (err, r); } } + + return i; } void statement:: @@ -826,8 +894,14 @@ namespace odb sword r; OCIEnv* env (conn_.database ().environment ()); - for (size_t i (1); i <= c; ++i, ++b) + ub4 i (0); + for (bind* end (b + c); b != end; ++b) { + if (b->buffer == 0) // Skip NULL entries. + continue; + + i++; // Column index is 1-based. + void* value; switch (b->type) @@ -971,8 +1045,11 @@ namespace odb { OCIError* err (conn_.error_handle ()); - for (size_t i (0); i < c; ++i, ++b) + for (bind* end (b + c); b != end; ++b) { + if (b->buffer == 0) // Skip NULL entries. + continue; + // Only stream if the bind specifies a LOB type. // if (b->type == bind::blob || @@ -1091,14 +1168,20 @@ namespace odb generic_statement:: generic_statement (connection_type& conn, const string& text) - : statement (conn, text), bound_ (false) + : statement (conn, + text, statement_generic, + 0, false), + bound_ (false) { init (); } generic_statement:: generic_statement (connection_type& conn, const char* text) - : statement (conn, text), bound_ (false) + : statement (conn, + text, statement_generic, + 0, false), + bound_ (false) { init (); } @@ -1270,65 +1353,93 @@ namespace odb select_statement:: select_statement (connection_type& conn, const string& text, + bool process, + bool optimize, binding& param, binding& result, size_t lob_prefetch_size) - : statement (conn, text), + : statement (conn, + text, statement_select, + (process ? &result : 0), optimize), result_ (result), - result_version_ (0), lob_prefetch_size_ (lob_prefetch_size), done_ (true) { - bind_param (param.bind, param.count); - bind_result (result.bind, result.count, lob_prefetch_size); - result_version_ = result_.version; + if (!empty ()) + { + bind_param (param.bind, param.count); + result_count_ = bind_result ( + result.bind, result.count, lob_prefetch_size); + result_version_ = result_.version; + } } select_statement:: select_statement (connection_type& conn, const char* text, + bool process, + bool optimize, binding& param, binding& result, size_t lob_prefetch_size) - : statement (conn, text), + : statement (conn, + text, statement_select, + (process ? &result : 0), optimize), result_ (result), - result_version_ (0), lob_prefetch_size_ (lob_prefetch_size), done_ (true) { - bind_param (param.bind, param.count); - bind_result (result.bind, result.count, lob_prefetch_size); - result_version_ = result_.version; + if (!empty ()) + { + bind_param (param.bind, param.count); + result_count_ = bind_result ( + result.bind, result.count, lob_prefetch_size); + result_version_ = result_.version; + } } select_statement:: select_statement (connection_type& conn, const string& text, + bool process, + bool optimize, binding& result, size_t lob_prefetch_size) - : statement (conn, text), + : statement (conn, + text, statement_select, + (process ? &result : 0), optimize), result_ (result), - result_version_ (0), lob_prefetch_size_ (lob_prefetch_size), done_ (true) { - bind_result (result.bind, result.count, lob_prefetch_size); - result_version_ = result_.version; + if (!empty ()) + { + result_count_ = bind_result ( + result.bind, result.count, lob_prefetch_size); + result_version_ = result_.version; + } } select_statement:: select_statement (connection_type& conn, const char* text, + bool process, + bool optimize, binding& result, size_t lob_prefetch_size) - : statement (conn, text), + : statement (conn, + text, statement_select, + (process ? &result : 0), optimize), result_ (result), - result_version_ (0), lob_prefetch_size_ (lob_prefetch_size), done_ (true) { - bind_result (result.bind, result.count, lob_prefetch_size); - result_version_ = result_.version; + if (!empty ()) + { + result_count_ = bind_result ( + result.bind, result.count, lob_prefetch_size); + result_version_ = result_.version; + } } void select_statement:: @@ -1374,7 +1485,7 @@ namespace odb // of this assertion is a native view with a number of data members // not matching the number of columns in the SELECT-list. // - assert (n == result_.count); + assert (n == result_count_); #endif } @@ -1495,9 +1606,12 @@ namespace odb insert_statement:: insert_statement (connection_type& conn, const string& text, + bool process, binding& param, bool returning) - : statement (conn, text) + : statement (conn, + text, statement_insert, + (process ? ¶m : 0), false) { init (param, returning); } @@ -1505,9 +1619,12 @@ namespace odb insert_statement:: insert_statement (connection_type& conn, const char* text, + bool process, binding& param, bool returning) - : statement (conn, text) + : statement (conn, + text, statement_insert, + (process ? ¶m : 0), false) { init (param, returning); } @@ -1515,7 +1632,7 @@ namespace odb void insert_statement:: init (binding& param, bool returning) { - bind_param (param.bind, param.count); + ub4 param_count (bind_param (param.bind, param.count)); if (returning) { @@ -1525,7 +1642,7 @@ namespace odb sword r (OCIBindByPos (stmt_, &h, err, - param.count + 1, + param_count + 1, 0, #if (OCI_MAJOR_VERSION == 11 && OCI_MINOR_VERSION >=2) \ || OCI_MAJOR_VERSION > 11 @@ -1636,19 +1753,27 @@ namespace odb update_statement:: update_statement (connection_type& conn, const string& text, + bool process, binding& param) - : statement (conn, text) + : statement (conn, + text, statement_update, + (process ? ¶m : 0), false) { - bind_param (param.bind, param.count); + if (!empty ()) + bind_param (param.bind, param.count); } update_statement:: update_statement (connection_type& conn, const char* text, + bool process, binding& param) - : statement (conn, text) + : statement (conn, + text, statement_update, + (process ? ¶m : 0), false) { - bind_param (param.bind, param.count); + if (!empty ()) + bind_param (param.bind, param.count); } unsigned long long update_statement:: @@ -1707,7 +1832,9 @@ namespace odb delete_statement (connection_type& conn, const string& text, binding& param) - : statement (conn, text) + : statement (conn, + text, statement_delete, + 0, false) { bind_param (param.bind, param.count); } @@ -1716,7 +1843,9 @@ namespace odb delete_statement (connection_type& conn, const char* text, binding& param) - : statement (conn, text) + : statement (conn, + text, statement_delete, + 0, false) { bind_param (param.bind, param.count); } |