00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "db/db.hpp"
00029 #include "base/list.hpp"
00030 #include "base/vector.hpp"
00031 #include "base/memory.hpp"
00032 #include "base/template.hpp"
00033 #include "base/common.hpp"
00034 #include "base/string.hpp"
00035 #include "base/numeric.h"
00036 #include "alg/algorith.hpp"
00037
00038 BEGIN_TERIMBER_NAMESPACE
00039 #pragma pack(4)
00040
00041
00042 exception_item dbMsgs[] =
00043 {
00044 {ex_invalid, "Module is invalid"},
00045 {ex_not_init, "Server is not initialized"},
00046 {ex_already_init, "Server is already initialized"},
00047 {ex_not_connect, "Database is not connected"},
00048 {ex_already_connect, "Database is already connected"},
00049 {ex_not_transaction, "Database is not in transaction"},
00050 {ex_already_transaction, "Database is already in transaction"},
00051 {ex_not_sql_open, "Query is not open"},
00052 {ex_already_sql_open, "Query is already open"},
00053 {ex_sql_in_action, "Query is working"},
00054 {ex_bad_pointer, "NULL input parameter pointer"},
00055 {ex_invalid_param_count, "Incorrect number of parameters"},
00056 {ex_timeout, "Timeout occured"},
00057 {ex_unknown_server_type, "Unknown server type"},
00058 {ex_out_of_bounders, "Index is out of bounders"},
00059 {0, 0},
00060 };
00061
00062 exception_table dbMsgTable(dbMsgs);
00063
00064
00066 binder::~binder()
00067 {
00068 deallocate_value();
00069 }
00070
00071 binder::binder() :
00072 _in_out(db_param_unknown),
00073 _type(db_unknown),
00074 _name(0),
00075 _scale(0),
00076 _precision(0),
00077 _max_length(0),
00078 _bind_type(0),
00079 _native_type(0),
00080 _real_length(0),
00081 _bind_buffer(0),
00082 _user_code(0),
00083 _responsible(false)
00084 {
00085 _value.nullVal = true;
00086 memset(&_value.val, 0, sizeof(terimber_xml_value));
00087 }
00088
00089
00090
00091
00092 binder::binder(const binder& x) :
00093 _in_out(db_param_unknown),
00094 _type(db_unknown),
00095 _name(0),
00096 _scale(0),
00097 _precision(0),
00098 _max_length(0),
00099 _bind_type(0),
00100 _native_type(0),
00101 _real_length(0),
00102 _bind_buffer(0),
00103 _user_code(0),
00104 _responsible(false)
00105 {
00106 x.clone(*this);
00107 }
00108
00109 binder&
00110 binder::operator=(const binder& x)
00111 {
00112 deallocate_value();
00113 x.clone(*this);
00114 return *this;
00115 }
00116
00117 void
00118 binder::set_name(byte_allocator* data_allocator, const char* x)
00119 {
00120 _name = copy_string(x, *data_allocator, os_minus_one);
00121 }
00122
00123
00124 void*
00125 binder::allocate_value(size_t n)
00126 {
00127 _responsible = true;
00128 switch (_type)
00129 {
00130 case db_unknown:
00131 case db_bool:
00132 case db_sb1:
00133 case db_ub1:
00134 case db_sb2:
00135 case db_ub2:
00136 case db_sb4:
00137 case db_ub4:
00138 case db_float:
00139 assert(false);
00140 return 0;
00141 #ifdef OS_64BIT
00142 case db_double:
00143 case db_sb8:
00144 case db_ub8:
00145 case db_date:
00146 assert(false);
00147 return 0;
00148 #else
00149 case db_double:
00150 return (double*)check_pointer((void*)(_value.val.dblVal = new double));
00151 case db_date:
00152 case db_sb8:
00153 return (sb8_t*)check_pointer((void*)(_value.val.intVal = new sb8_t));
00154 case db_ub8:
00155 return (ub8_t*)check_pointer((void*)(_value.val.uintVal = new ub8_t));
00156 #endif
00157 case db_string:
00158 {
00159 char* retVal = (char*)check_pointer((void*)(_value.val.strVal = new char[n + 1]));
00160 retVal[n] = 0;
00161 return retVal;
00162 }
00163 case db_wstring:
00164 {
00165 wchar_t* retVal = (wchar_t*)check_pointer((void*)(_value.val.wstrVal = new wchar_t[n + 1]));
00166 retVal[n] = 0;
00167 return retVal;
00168 }
00169 case db_decimal:
00170 case db_numeric:
00171 return (ub1_t*)check_pointer((void*)(_value.val.bufVal = new ub1_t[n]));
00172 case db_binary:
00173 {
00174 ub1_t* retVal = (ub1_t*)check_pointer((void*)(_value.val.bufVal = new ub1_t[n + sizeof(size_t)]));
00175 *(size_t*)retVal = n;
00176 return retVal + sizeof(size_t);
00177 }
00178 case db_guid:
00179 return (guid_t*)check_pointer((void*)(_value.val.guidVal = new guid_t));
00180 default:
00181 assert(false);
00182 }
00183
00184 return 0;
00185 }
00186
00187 void
00188 binder::deallocate_value()
00189 {
00190 if (!_responsible)
00191 return;
00192
00193 switch (_type)
00194 {
00195 case db_unknown:
00196 return;
00197 case db_bool:
00198 case db_sb1:
00199 case db_ub1:
00200 case db_sb2:
00201 case db_ub2:
00202 case db_sb4:
00203 case db_ub4:
00204 case db_float:
00205
00206 break;
00207 #ifdef OS_64BIT
00208 case db_double:
00209 case db_sb8:
00210 case db_ub8:
00211 case db_date:
00212
00213 break;
00214 #else
00215 case db_double:
00216 if (_value.val.dblVal)
00217 {
00218 delete (double*)_value.val.dblVal;
00219 _value.val.dblVal = 0;
00220 }
00221 break;
00222 case db_date:
00223 case db_sb8:
00224 if (_value.val.intVal)
00225 {
00226 delete (sb8_t*)_value.val.intVal;
00227 _value.val.intVal = 0;
00228 }
00229 break;
00230 case db_ub8:
00231 if (_value.val.uintVal)
00232 {
00233 delete (ub8_t*)_value.val.uintVal;
00234 _value.val.uintVal = 0;
00235 }
00236 break;
00237 #endif
00238 case db_string:
00239 if (_value.val.strVal)
00240 {
00241 delete [] (char*)_value.val.strVal;
00242 _value.val.strVal = 0;
00243 }
00244 break;
00245 case db_wstring:
00246 if (_value.val.wstrVal)
00247 {
00248 delete [] (wchar_t*)_value.val.wstrVal;
00249 _value.val.wstrVal = 0;
00250 }
00251 break;
00252 case db_decimal:
00253 case db_numeric:
00254 case db_binary:
00255 if (_value.val.bufVal)
00256 {
00257 delete [] (ub1_t*)_value.val.bufVal;
00258 _value.val.bufVal = 0;
00259 }
00260 break;
00261 case db_guid:
00262 if (_value.val.guidVal)
00263 {
00264 delete (guid_t*)_value.val.guidVal;
00265 _value.val.guidVal = 0;
00266 }
00267 break;
00268 default:
00269 assert(false);
00270 }
00271
00272 _responsible = false;
00273 }
00274
00275 void
00276 binder::clone(binder& out) const
00277 {
00278 out._in_out = _in_out;
00279 out._type = _type;
00280 out._name = _name;
00281 out._scale = _scale;
00282 out._precision = _precision;
00283 out._max_length = _max_length;
00284 out._bind_type = _bind_type;
00285 out._native_type = _native_type;
00286 out._real_length = _real_length;
00287 out._bind_buffer = _bind_buffer;
00288 out._user_code = _user_code;
00289 out._responsible = _responsible;
00290 out._value.nullVal = _value.nullVal;
00291 memset(&out._value.val, 0, sizeof(out._value.val));
00292
00293 if (_responsible && !_value.nullVal)
00294 {
00295 switch (_type)
00296 {
00297 case db_unknown:
00298 return;
00299 case db_bool:
00300 case db_sb1:
00301 case db_ub1:
00302 case db_sb2:
00303 case db_ub2:
00304 case db_sb4:
00305 case db_ub4:
00306 case db_float:
00307 out._value.val = _value.val;
00308 break;
00309 #ifdef OS_64BIT
00310 case db_double:
00311 case db_sb8:
00312 case db_ub8:
00313 case db_date:
00314 out._value.val = _value.val;
00315 break;
00316 #else
00317 case db_double:
00318 if (_value.val.dblVal)
00319 *(double*)check_pointer((void*)(out._value.val.dblVal = new double)) = *_value.val.dblVal;
00320 break;
00321 case db_date:
00322 case db_sb8:
00323 if (_value.val.intVal)
00324 *(sb8_t*)check_pointer((void*)(out._value.val.intVal = new sb8_t)) = *_value.val.intVal;
00325 break;
00326 case db_ub8:
00327 if (_value.val.uintVal)
00328 *(ub8_t*)check_pointer((void*)(out._value.val.uintVal = new ub8_t)) = *_value.val.uintVal;
00329 break;
00330 #endif
00331 case db_string:
00332 if (_value.val.strVal)
00333 {
00334 size_t n = str_template::strlen(_value.val.strVal);
00335 char* ret = (char*)check_pointer((void*)(out._value.val.strVal = new char[n + 1]));
00336 memcpy(ret, _value.val.strVal, n + 1);
00337 }
00338 break;
00339 case db_wstring:
00340 {
00341 size_t n = str_template::strlen(_value.val.wstrVal);
00342 wchar_t* ret = (wchar_t*)check_pointer((void*)(out._value.val.wstrVal = new wchar_t[n + 1]));
00343 memcpy(ret, _value.val.wstrVal, sizeof(wchar_t) * (n + 1));
00344 }
00345 break;
00346 case db_decimal:
00347 case db_numeric:
00348 if (_value.val.bufVal)
00349 {
00350
00351 numeric conv;
00352 conv.parse_orcl(_value.val.bufVal);
00353 size_t n = conv.orcl_len();
00354 ub1_t* ret = (ub1_t*)check_pointer((void*)(out._value.val.bufVal = new ub1_t[n]));
00355 memcpy(ret, _value.val.bufVal, n);
00356 }
00357 break;
00358 case db_binary:
00359 if (_value.val.bufVal)
00360 {
00361 size_t n = *(size_t*)_value.val.bufVal;
00362 ub1_t* ret = (ub1_t*)check_pointer((void*)(out._value.val.bufVal = new ub1_t[n + sizeof(size_t)]));
00363 *(size_t*)ret = n;
00364 memcpy(ret + sizeof(size_t), _value.val.bufVal + sizeof(size_t), n);
00365 }
00366 break;
00367 case db_guid:
00368 if (_value.val.guidVal)
00369 {
00370 guid_t* ret = (guid_t*)check_pointer((void*)(out._value.val.guidVal = new guid_t));
00371 memcpy(ret, _value.val.guidVal, sizeof(guid_t));
00372 }
00373 break;
00374 default:
00375 assert(false);
00376 }
00377 }
00378 else
00379 {
00380 out._value.nullVal = _value.nullVal;
00381 out._value.val = _value.val;
00382 }
00383 }
00384
00386 dbserver_impl::callback_finder::callback_finder(const async_db_notify* obj) :
00387 _obj(obj)
00388 {
00389 }
00390
00391 dbserver_impl::callback_fire::callback_fire(bool noerrors, size_t ident) :
00392 _noerrors(noerrors), _ident(ident)
00393 {
00394 }
00396 dbserver_impl::dbserver_impl(size_t ident) :
00397
00398 _ident(ident),
00399 _code(0),
00400
00401 _connection(false),
00402 _transaction(false),
00403 _trusted(false),
00404 _columns_allocator(0),
00405 _data_allocator(0),
00406 _bulk_allocator(0),
00407 _sql(&_sql_allocator),
00408 _quote(':'),
00409 _start_row(0),
00410 _requested_rows(0),
00411 _fetched_rows(0),
00412 _forward(true),
00413 _bulk_rows(100),
00414
00415 _state(STATE_OK),
00416 _action(ACTION_NONE),
00417 _is_open(false),
00418 _list_callback(16),
00419 _iter(_data.end())
00420 {
00421 _temp_allocator = _manager.loan_object();
00422 _columns_allocator = _manager.loan_object();
00423 _data_allocator = _manager.loan_object();
00424 _bulk_allocator = _manager.loan_object();
00425 }
00426
00427
00428 dbserver_impl::~dbserver_impl()
00429 {
00430
00431 _thread.cancel_job();
00432 _thread.stop();
00433 _manager.return_object(_temp_allocator);
00434 _manager.return_object(_columns_allocator);
00435 _manager.return_object(_data_allocator);
00436 _manager.return_object(_bulk_allocator);
00437 }
00438
00439 size_t
00440 dbserver_impl::get_ident() const
00441 {
00442 return _ident;
00443 }
00444
00445 bool
00446 dbserver_impl::is_ready() const
00447 {
00448 return get_state() == STATE_OK;
00449 }
00450
00451 size_t
00452 dbserver_impl::get_code() const
00453 {
00454 return _code;
00455 }
00456
00457 const char*
00458 dbserver_impl::get_error() const
00459 {
00460 return _error;
00461 }
00462
00463
00464
00465
00466
00467 bool
00468 dbserver_impl::connect(bool trusted_connection, const char* connection_string)
00469 {
00470 DB_TRY
00471 _check_disconnect();
00472 v_connect(trusted_connection, connection_string);
00473 _trusted = trusted_connection;
00474 _connect_string = connection_string;
00475 _set_connect();
00476
00477 format_logging(0, __FILE__, __LINE__, en_log_info, "connect succeeded, login: %s", connection_string);
00478
00479 DB_CATCH_DB
00480 }
00481
00482
00483 bool
00484 dbserver_impl::disconnect()
00485 {
00486 DB_TRY
00487 _check_connect();
00488 v_disconnect();
00489 _trusted = false;
00490 _connect_string = 0;
00491 _set_disconnect();
00492 DB_CATCH_DB
00493 }
00494
00495
00496 bool
00497 dbserver_impl::start_transaction()
00498 {
00499 DB_TRY
00500 _check_out_transaction();
00501 v_start_transaction();
00502 _set_in_transaction();
00503 DB_CATCH_DB
00504 }
00505
00506
00507 bool
00508 dbserver_impl::commit()
00509 {
00510 DB_TRY
00511 _check_in_transaction();
00512 v_commit();
00513 _set_out_transaction();
00514 DB_CATCH_DB
00515 }
00516
00517
00518 bool
00519 dbserver_impl::rollback()
00520 {
00521 DB_TRY
00522 _check_in_transaction();
00523 v_rollback();
00524 _set_out_transaction();
00525 DB_CATCH_DB
00526 }
00527
00528
00529 bool
00530 dbserver_impl::is_connect() const
00531 {
00532 return _is_connect();
00533 }
00534
00535
00536 bool
00537 dbserver_impl::is_in_transaction() const
00538 {
00539 return _is_in_transaction();
00540 }
00541
00542
00543 bool
00544 dbserver_impl::is_connect_alive()
00545 {
00546 return v_is_connect_alive();
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556 bool
00557 dbserver_impl::resize_params(size_t size)
00558 {
00559 try
00560 {
00561
00562 size_t num = _params.size();
00563
00564 if (num != size && !_bulk_params.empty())
00565 _bulk_params.clear();
00566
00567
00568 _params.resize(size);
00569 }
00570 catch (exception& x)
00571 {
00572 _error = x.what();
00573 _code = x.get_code();
00574 return false;
00575 }
00576
00577 return true;
00578 }
00579
00580
00581
00582
00583 size_t
00584 dbserver_impl::get_param_count() const
00585 {
00586 return _params.size();
00587 }
00588
00589
00590
00591
00592 dbtypes
00593 dbserver_impl::get_param_type(size_t index) const
00594 {
00595 return index >= _params.size() ? db_unknown : _params[index]._type;
00596 }
00597
00598
00599
00600
00601 db_param_type
00602 dbserver_impl::get_param_in_out(size_t index) const
00603 {
00604 return index >= _params.size() ? db_param_unknown : _params[index]._in_out;
00605 }
00606
00607
00608
00609
00610 bool
00611 dbserver_impl::get_param_is_null(size_t index) const
00612 {
00613 return index >= _params.size() || _params[index]._value.nullVal;
00614 }
00615
00616
00617
00618
00619
00620 bool
00621 dbserver_impl::get_param_as_bool(size_t index) const
00622 {
00623 return get_param_as_value(index, vt_bool).boolVal;
00624 }
00625
00626 sb1_t
00627 dbserver_impl::get_param_as_char(size_t index) const
00628 {
00629 return get_param_as_value(index, vt_sb1).cVal;
00630 }
00631
00632 ub1_t
00633 dbserver_impl::get_param_as_byte(size_t index) const
00634 {
00635 return get_param_as_value(index, vt_ub1).bVal;
00636 }
00637
00638 sb2_t
00639 dbserver_impl::get_param_as_short(size_t index) const
00640 {
00641 return get_param_as_value(index, vt_sb2).iVal;
00642 }
00643
00644 ub2_t
00645 dbserver_impl::get_param_as_word(size_t index) const
00646 {
00647 return get_param_as_value(index, vt_ub2).uiVal;
00648 }
00649
00650 sb4_t
00651 dbserver_impl::get_param_as_long(size_t index) const
00652 {
00653 return get_param_as_value(index, vt_sb4).lVal;
00654 }
00655
00656 ub4_t
00657 dbserver_impl::get_param_as_dword(size_t index) const
00658 {
00659 return get_param_as_value(index, vt_ub4).ulVal;
00660 }
00661
00662 float
00663 dbserver_impl::get_param_as_float(size_t index) const
00664 {
00665 return get_param_as_value(index, vt_float).fltVal;
00666 }
00667
00668 double
00669 dbserver_impl::get_param_as_double(size_t index) const
00670 {
00671 #ifdef OS_64BIT
00672 return get_param_as_value(index, vt_double).dblVal;
00673 #else
00674 const double* ret = get_param_as_value(index, vt_double).dblVal;
00675 return ret ? *ret : 0.0;
00676 #endif
00677 }
00678
00679 sb8_t
00680 dbserver_impl::get_param_as_long64(size_t index) const
00681 {
00682 #ifdef OS_64BIT
00683 return get_param_as_value(index, vt_sb8).intVal;
00684 #else
00685 const sb8_t* ret = get_param_as_value(index, vt_sb8).intVal;
00686 return ret ? *ret : 0;
00687 #endif
00688 }
00689
00690 ub8_t
00691 dbserver_impl::get_param_as_dword64(size_t index) const
00692 {
00693 #ifdef OS_64BIT
00694 return get_param_as_value(index, vt_ub8).uintVal;
00695 #else
00696 const ub8_t* ret = get_param_as_value(index, vt_ub8).uintVal;
00697 return ret ? *ret : 0;
00698 #endif
00699 }
00700
00701
00702 bool
00703 dbserver_impl::get_param_as_guid(size_t index, guid_t& val) const
00704 {
00705 const guid_t* ret = get_param_as_value(index, vt_guid).guidVal;
00706
00707 if (!ret)
00708 return false;
00709
00710 val = *ret;
00711 return true;
00712 }
00713
00714
00715
00716 const char*
00717 dbserver_impl::get_param_as_numeric(size_t index, char delimeter) const
00718 {
00719 const ub1_t* retVal = get_param_as_value(index, vt_numeric).bufVal;
00720
00721 if(!retVal)
00722 return 0;
00723
00724 numeric num;
00725 if (!num.parse_orcl(retVal))
00726 return 0;
00727
00728 size_t len = num.is_zero() ? 2 : num.precision() + (num.sign() ? 1 : 0) + (num.scale() ? 1 : 0) + (num.precision() == num.scale()) + 1;
00729 char* retStr = (char*)_temp_allocator->allocate(len);
00730 num.format(retStr, delimeter);
00731 return retStr;
00732 }
00733
00734
00735
00736 const char*
00737 dbserver_impl::get_param_as_decimal(size_t index, char delimeter) const
00738 {
00739 return get_param_as_numeric(index, delimeter);
00740 }
00741
00742
00743 bool
00744 dbserver_impl::get_param_as_date(size_t index, ub4_t& year, ub1_t& month, ub1_t& day, ub1_t& hour, ub1_t& minute, ub1_t& second, ub2_t& millisec, ub1_t& wday, ub2_t& yday) const
00745 {
00746 #ifdef OS_64BIT
00747 date dt(get_param_as_value(index, vt_date).intVal);
00748 #else
00749 const sb8_t* val = get_param_as_value(index, vt_date).intVal;
00750 if (!val)
00751 return false;
00752 date dt(*val);
00753 #endif
00754 return date::convert_from(dt, year, month, day, hour, minute, second, millisec, wday, yday);
00755 }
00756
00757
00758 const char*
00759 dbserver_impl::get_param_as_string(size_t index) const
00760 {
00761 return get_param_as_value(index, vt_string).strVal;
00762 }
00763
00764
00765 const wchar_t*
00766 dbserver_impl::get_param_as_wstring(size_t index) const
00767 {
00768 return get_param_as_value(index, vt_wstring).wstrVal;
00769 }
00770
00771
00772 const ub1_t*
00773 dbserver_impl::get_param_as_binary(size_t index, size_t& len) const
00774 {
00775 const ub1_t* buf = get_param_as_value(index, vt_binary).bufVal;
00776 len = buf ? *(size_t*)buf : 0;
00777 return buf ? buf + sizeof(size_t) : 0;
00778 }
00779
00780
00781
00782
00783 const ub1_t*
00784 dbserver_impl::get_param_as_binary_ptr(size_t index) const
00785 {
00786 return get_param_as_value(index, vt_binary).bufVal;
00787 }
00788
00789
00791 bool
00792 dbserver_impl::set_param_as_null(size_t index, db_param_type in_out, dbtypes type)
00793 {
00794 if (index >= _params.size())
00795 return false;
00796 else
00797 {
00798 if (!_bulk_params.empty() && type != _params[index]._type)
00799 _bulk_params.clear();
00800
00801 return _params[index].set_as_null(in_out, type);
00802 }
00803 }
00804
00805 bool
00806 dbserver_impl::set_param_as_bool(size_t index, db_param_type in_out, bool val)
00807 {
00808 if (index >= _params.size())
00809 return false;
00810 else
00811 {
00812 if (!_bulk_params.empty() && db_bool != _params[index]._type)
00813 _bulk_params.clear();
00814
00815 return _params[index].set_as_bool(in_out, val);
00816 }
00817 }
00818
00819 bool
00820 dbserver_impl::set_param_as_char(size_t index, db_param_type in_out, sb1_t val)
00821 {
00822 if (index >= _params.size())
00823 return false;
00824 else
00825 {
00826 if (!_bulk_params.empty() && db_sb1 != _params[index]._type)
00827 _bulk_params.clear();
00828
00829 return _params[index].set_as_char(in_out, val);
00830 }
00831 }
00832
00833 bool
00834 dbserver_impl::set_param_as_byte(size_t index, db_param_type in_out, ub1_t val)
00835 {
00836 if (index >= _params.size())
00837 return false;
00838 else
00839 {
00840 if (!_bulk_params.empty() && db_ub1 != _params[index]._type)
00841 _bulk_params.clear();
00842
00843 return _params[index].set_as_byte(in_out, val);
00844 }
00845 }
00846
00847 bool
00848 dbserver_impl::set_param_as_short(size_t index, db_param_type in_out, sb2_t val)
00849 {
00850 if (index >= _params.size())
00851 return false;
00852 else
00853 {
00854 if (!_bulk_params.empty() && db_sb2 != _params[index]._type)
00855 _bulk_params.clear();
00856
00857 return _params[index].set_as_short(in_out, val);
00858 }
00859 }
00860
00861 bool
00862 dbserver_impl::set_param_as_word(size_t index, db_param_type in_out, ub2_t val)
00863 {
00864 if (index >= _params.size())
00865 return false;
00866 else
00867 {
00868 if (!_bulk_params.empty() && db_ub2 != _params[index]._type)
00869 _bulk_params.clear();
00870
00871 return _params[index].set_as_word(in_out, val);
00872 }
00873 }
00874
00875 bool
00876 dbserver_impl::set_param_as_long(size_t index, db_param_type in_out, sb4_t val)
00877 {
00878 if (index >= _params.size())
00879 return false;
00880 else
00881 {
00882 if (!_bulk_params.empty() && db_sb4 != _params[index]._type)
00883 _bulk_params.clear();
00884
00885 return _params[index].set_as_long(in_out, val);
00886 }
00887 }
00888
00889 bool
00890 dbserver_impl::set_param_as_dword(size_t index, db_param_type in_out, ub4_t val)
00891 {
00892 if (index >= _params.size())
00893 return false;
00894 else
00895 {
00896 if (!_bulk_params.empty() && db_sb4 != _params[index]._type)
00897 _bulk_params.clear();
00898
00899 return _params[index].set_as_dword(in_out, val);
00900 }
00901 }
00902
00903 bool
00904 dbserver_impl::set_param_as_float(size_t index, db_param_type in_out, float val)
00905 {
00906 if (index >= _params.size())
00907 return false;
00908 else
00909 {
00910 if (!_bulk_params.empty() && db_float != _params[index]._type)
00911 _bulk_params.clear();
00912
00913 return _params[index].set_as_float(in_out, val);
00914 }
00915 }
00916
00917 bool
00918 dbserver_impl::set_param_as_double(size_t index, db_param_type in_out, double val)
00919 {
00920 if (index >= _params.size())
00921 return false;
00922 else
00923 {
00924 if (!_bulk_params.empty() && db_double != _params[index]._type)
00925 _bulk_params.clear();
00926
00927 return _params[index].set_as_double(in_out, val);
00928 }
00929 }
00930
00931 bool
00932 dbserver_impl::set_param_as_long64(size_t index, db_param_type in_out, sb8_t val)
00933 {
00934 if (index >= _params.size())
00935 return false;
00936 else
00937 {
00938 if (!_bulk_params.empty() && db_sb8 != _params[index]._type)
00939 _bulk_params.clear();
00940
00941 return _params[index].set_as_long64(in_out, val);
00942 }
00943 }
00944
00945 bool
00946 dbserver_impl::set_param_as_dword64(size_t index, db_param_type in_out, ub8_t val)
00947 {
00948 if (index >= _params.size())
00949 return false;
00950 else
00951 {
00952 if (!_bulk_params.empty() && db_ub8 != _params[index]._type)
00953 _bulk_params.clear();
00954
00955 return _params[index].set_as_dword64(in_out, val);
00956 }
00957 }
00958
00959 bool
00960 dbserver_impl::set_param_as_guid(size_t index, db_param_type in_out, const guid_t& val)
00961 {
00962 if (index >= _params.size())
00963 return false;
00964 else
00965 {
00966 if (!_bulk_params.empty() && db_guid != _params[index]._type)
00967 _bulk_params.clear();
00968
00969 return _params[index].set_as_guid(in_out, val);
00970 }
00971 }
00972
00973
00974
00975
00976
00977
00978
00979 bool
00980 dbserver_impl::set_param_as_numeric(size_t index, db_param_type in_out, const char* val, char delimeter)
00981 {
00982 if (index >= _params.size() || !val)
00983 return false;
00984 else
00985 {
00986 if (!_bulk_params.empty() && db_decimal != _params[index]._type && db_numeric != _params[index]._type)
00987 _bulk_params.clear();
00988
00989 return _params[index].set_as_numeric(in_out, val, delimeter);
00990 }
00991 }
00992
00993 bool
00994 dbserver_impl::set_param_as_decimal(size_t index, db_param_type in_out, const char* val, char delimeter)
00995 {
00996 if (index >= _params.size() || !val)
00997 return false;
00998 else
00999 {
01000 if (!_bulk_params.empty() && db_decimal != _params[index]._type && db_numeric != _params[index]._type)
01001 _bulk_params.clear();
01002
01003 return _params[index].set_as_decimal(in_out, val, delimeter);
01004 }
01005 }
01006
01007
01008 bool
01009 dbserver_impl::set_param_as_date(size_t index, db_param_type in_out, ub4_t year, ub1_t month, ub1_t day, ub1_t hour, ub1_t minute, ub1_t second, ub2_t millisec)
01010 {
01011 if (index >= _params.size())
01012 return false;
01013 else
01014 {
01015 if (!_bulk_params.empty() && db_date != _params[index]._type)
01016 _bulk_params.clear();
01017
01018 return _params[index].set_as_date(in_out, year, month, day, hour, minute, second, millisec);
01019 }
01020 }
01021
01022
01023
01024 bool
01025 dbserver_impl::set_param_as_string(size_t index, db_param_type in_out, const char* val, size_t len, size_t max_len)
01026 {
01027 if (index >= _params.size() || !val)
01028 return false;
01029 else
01030 {
01031 if (!_bulk_params.empty() && db_string != _params[index]._type)
01032 _bulk_params.clear();
01033
01034 _params[index]._max_length = max_len;
01035 return _params[index].set_as_string(in_out, val, len);
01036 }
01037 }
01038
01039
01040
01041
01042
01043
01044 bool
01045 dbserver_impl::set_param_as_string_ptr(size_t index, const char* val)
01046 {
01047 if (index >= _params.size() || !val)
01048 return false;
01049 else
01050 {
01051 if (!_bulk_params.empty() && db_string != _params[index]._type)
01052 _bulk_params.clear();
01053
01054 return _params[index].set_as_string_ptr(val);
01055 }
01056 }
01057
01058
01059
01060 bool
01061 dbserver_impl::set_param_as_wstring(size_t index, db_param_type in_out, const wchar_t* val, size_t len, size_t max_len)
01062 {
01063 if (index >= _params.size() || !val)
01064 return false;
01065 else
01066 {
01067 if (!_bulk_params.empty() && db_wstring != _params[index]._type)
01068 _bulk_params.clear();
01069
01070 _params[index]._max_length = max_len;
01071 return _params[index].set_as_wstring(in_out, val, len);
01072 }
01073 }
01074
01075
01076
01077
01078
01079
01080
01081 bool
01082 dbserver_impl::set_param_as_wstring_ptr(size_t index, const wchar_t* val)
01083 {
01084 if (index >= _params.size() || !val)
01085 return false;
01086 else
01087 {
01088 if (!_bulk_params.empty() && db_wstring != _params[index]._type)
01089 _bulk_params.clear();
01090
01091 return _params[index].set_as_wstring_ptr(val);
01092 }
01093 }
01094
01095
01096
01097 bool
01098 dbserver_impl::set_param_as_binary(size_t index, db_param_type in_out, const ub1_t* val, size_t len, size_t max_len)
01099 {
01100 if (index >= _params.size() || !val || !len)
01101 return false;
01102 else
01103 {
01104 if (!_bulk_params.empty() && db_binary != _params[index]._type)
01105 _bulk_params.clear();
01106
01107 _params[index]._max_length = max_len;
01108 return _params[index].set_as_binary(in_out, val, len);
01109 }
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120 bool
01121 dbserver_impl::set_param_as_binary_ptr(size_t index, const ub1_t* val)
01122 {
01123 if (index >= _params.size() || !val)
01124 return false;
01125 else
01126 {
01127 if (!_bulk_params.empty() && db_binary != _params[index]._type)
01128 _bulk_params.clear();
01129
01130 return _params[index].set_as_binary_ptr(val);
01131 }
01132 }
01133
01135
01136
01137
01138
01139
01140
01141
01142 size_t
01143 dbserver_impl::get_column_count() const
01144 {
01145 return _cols.size();
01146 }
01147
01148
01149
01150 dbtypes
01151 dbserver_impl::get_column_type(size_t index) const
01152 {
01153
01154 return index >= _cols.size() ? db_unknown : (_cols.begin() + index)->_type;
01155 }
01156
01157
01158
01159 const char*
01160 dbserver_impl::get_column_name(size_t index) const
01161 {
01162
01163 return index >= _cols.size() ? 0 : (_cols.begin() + index)->_name;
01164 }
01165
01166
01167
01168
01169 bool
01170 dbserver_impl::get_column_nullable(size_t index) const
01171 {
01172
01173 return index >= _cols.size() ? false : (_cols.begin() + index)->_value.nullVal;
01174 }
01175
01176
01177
01178
01179 size_t
01180 dbserver_impl::get_column_scale(size_t index) const
01181 {
01182
01183 return index >= _cols.size() ? 0 : (_cols.begin() + index)->_scale;
01184 }
01185
01186
01187
01188
01189 size_t
01190 dbserver_impl::get_column_precision(size_t index) const
01191 {
01192
01193 return index >= _cols.size() ? 0 : (_cols.begin() + index)->_precision;
01194 }
01195
01196
01197
01198
01199 size_t
01200 dbserver_impl::get_column_max_length(size_t index) const
01201 {
01202
01203 return index >= _cols.size() ? 0 : (_cols.begin() + index)->_max_length;
01204 }
01205
01206
01207
01208
01209
01210
01211
01212
01213 size_t
01214 dbserver_impl::get_row_count() const
01215 {
01216 return _fetched_rows;
01217 }
01218
01219
01220
01221
01222 void
01223 dbserver_impl::reset() const
01224 {
01225 _iter = get_iter_end();
01226 }
01227
01228
01229
01230
01231 bool
01232 dbserver_impl::next() const
01233 {
01234 if (_iter != get_iter_end())
01235 ++_iter;
01236 else
01237 _iter = get_iter_begin();
01238
01239 return _iter != get_iter_end();
01240 }
01241
01242
01243
01244
01245 bool
01246 dbserver_impl::prev() const
01247 {
01248 if (_iter != get_iter_begin())
01249 --_iter;
01250 else
01251 _iter = get_iter_end();
01252
01253 return _iter != get_iter_end();
01254 }
01255
01257 bool
01258 dbserver_impl::get_value_is_null(size_t index) const
01259 {
01260 return _iter == get_iter_end() || index >= _cols.size() || (*_iter)[index].nullVal;
01261 }
01262
01263 bool
01264 dbserver_impl::get_value_as_bool(size_t index) const
01265 {
01266 return get_value_as_value(index, vt_bool).boolVal;
01267 }
01268
01269 sb1_t
01270 dbserver_impl::get_value_as_char(size_t index) const
01271 {
01272 return get_value_as_value(index, vt_sb1).cVal;
01273 }
01274
01275 ub1_t
01276 dbserver_impl::get_value_as_byte(size_t index) const
01277 {
01278 return get_value_as_value(index, vt_ub1).bVal;
01279 }
01280
01281 sb2_t
01282 dbserver_impl::get_value_as_short(size_t index) const
01283 {
01284 return get_value_as_value(index, vt_sb2).iVal;
01285 }
01286
01287 ub2_t
01288 dbserver_impl::get_value_as_word(size_t index) const
01289 {
01290 return get_value_as_value(index, vt_ub2).uiVal;
01291 }
01292
01293 sb4_t
01294 dbserver_impl::get_value_as_long(size_t index) const
01295 {
01296 return get_value_as_value(index, vt_sb4).lVal;
01297 }
01298
01299 ub4_t
01300 dbserver_impl::get_value_as_dword(size_t index) const
01301 {
01302 return get_value_as_value(index, vt_ub4).ulVal;
01303 }
01304
01305 float
01306 dbserver_impl::get_value_as_float(size_t index) const
01307 {
01308 return get_value_as_value(index, vt_float).fltVal;
01309 }
01310
01311 double
01312 dbserver_impl::get_value_as_double(size_t index) const
01313 {
01314 #ifdef OS_64BIT
01315 return get_value_as_value(index, vt_double).dblVal;
01316 #else
01317 const double* ret = get_value_as_value(index, vt_double).dblVal;
01318 return ret ? *ret : 0.0;
01319 #endif
01320 }
01321
01322 sb8_t
01323 dbserver_impl::get_value_as_long64(size_t index) const
01324 {
01325 #ifdef OS_64BIT
01326 return get_value_as_value(index, vt_sb8).intVal;
01327 #else
01328 const sb8_t* ret = get_value_as_value(index, vt_sb8).intVal;
01329 return ret ? *ret : 0;
01330 #endif
01331 }
01332
01333 ub8_t
01334 dbserver_impl::get_value_as_dword64(size_t index) const
01335 {
01336 #ifdef OS_64BIT
01337 return get_value_as_value(index, vt_ub8).uintVal;
01338 #else
01339 const ub8_t* ret = get_value_as_value(index, vt_ub8).uintVal;
01340 return ret ? *ret : 0;
01341 #endif
01342 }
01343
01344
01345 bool
01346 dbserver_impl::get_value_as_guid(size_t index, guid_t& val) const
01347 {
01348 const guid_t* ret = get_value_as_value(index, vt_guid).guidVal;
01349 if (!ret)
01350 return false;
01351
01352 val = *ret;
01353 return true;
01354 }
01355
01356
01357
01358 const char*
01359 dbserver_impl::get_value_as_numeric(size_t index, char delimeter) const
01360 {
01361 const ub1_t* retVal = get_value_as_value(index, vt_numeric).bufVal;
01362
01363 if(!retVal)
01364 {
01365 assert(false);
01366 return 0;
01367 }
01368
01369 numeric num;
01370 if (!num.parse_orcl(retVal))
01371 {
01372 assert(false);
01373 return 0;
01374 }
01375
01376 size_t len = num.is_zero() ? 2 : num.precision() + (num.sign() ? 1 : 0) + (num.scale() ? 1 : 0) + (num.precision() == num.scale()) + 1;
01377 char* retStr = (char*)_temp_allocator->allocate(len);
01378 num.format(retStr, delimeter);
01379 return retStr;
01380 }
01381
01382
01383
01384 const char*
01385 dbserver_impl::get_value_as_decimal(size_t index, char delimeter) const
01386 {
01387 return get_value_as_numeric(index, delimeter);
01388 }
01389
01390
01391 bool
01392 dbserver_impl::get_value_as_date(size_t index, ub4_t& year, ub1_t& month, ub1_t& day, ub1_t& hour, ub1_t& minute, ub1_t& second, ub2_t& millisec, ub1_t& wday, ub2_t& yday) const
01393 {
01394 #ifdef OS_64BIT
01395 date dt(get_value_as_value(index, vt_date).intVal);
01396 #else
01397 const sb8_t* val = get_value_as_value(index, vt_date).intVal;
01398 if (!val)
01399 return false;
01400 date dt(*val);
01401 #endif
01402
01403 return date::convert_from(dt, year, month, day, hour, minute, second, millisec, wday, yday);
01404 }
01405
01406
01407 const char*
01408 dbserver_impl::get_value_as_string(size_t index) const
01409 {
01410 return get_value_as_value(index, vt_string).strVal;
01411 }
01412
01413
01414 const wchar_t*
01415 dbserver_impl::get_value_as_wstring(size_t index) const
01416 {
01417 return get_value_as_value(index, vt_wstring).wstrVal;
01418 }
01419
01420
01421
01422 const ub1_t*
01423 dbserver_impl::get_value_as_binary(size_t index, size_t& len) const
01424 {
01425 const ub1_t* buf = get_value_as_value(index, vt_binary).bufVal;
01426 len = buf ? *(size_t*)buf : 0;
01427 return buf ? buf + sizeof(size_t) : 0;
01428 }
01429
01430
01431
01432
01433
01434 const ub1_t*
01435 dbserver_impl::get_value_as_binary_ptr(size_t index) const
01436 {
01437 return get_value_as_value(index, vt_binary).bufVal;
01438 }
01439
01440
01441
01442
01443
01444 bool
01445 dbserver_impl::is_open_sql() const
01446 {
01447 return _is_open_sql();
01448 }
01449
01450
01451
01452 bool
01453 dbserver_impl::open_sql(bool async, const char* sql)
01454 {
01455 DB_TRY
01456 _check_state();
01457 _check_close();
01458 _check_action();
01459 _set_action(async ? ACTION_OPEN_SQL_ASYNC : ACTION_OPEN_SQL);
01460 _process_sql(sql);
01461 _get_number_params();
01462 _bind_params();
01463
01464 if (async)
01465 _start_thread();
01466 else
01467 {
01468 v_execute();
01469 _set_open();
01470 _get_columns_info();
01471 _set_action(ACTION_NONE);
01472 }
01473 DB_CATCH
01474 }
01475
01476
01477
01478 bool
01479 dbserver_impl::exec_sql(bool async, const char* sql)
01480 {
01481 DB_TRY
01482 _check_state();
01483 _check_close();
01484 _check_action();
01485 _set_action(async ? ACTION_EXEC_SQL_ASYNC : ACTION_EXEC_SQL);
01486 _process_sql(sql);
01487 _get_number_params();
01488 _bind_params();
01489
01490 if (async)
01491 _start_thread();
01492 else
01493 {
01494 v_execute();
01495 _set_open();
01496 _rebind_params();
01497 _set_action(ACTION_NONE);
01498 }
01499 DB_CATCH
01500 }
01501
01502
01503
01504 bool
01505 dbserver_impl::open_proc(bool async, const char* name)
01506 {
01507 DB_TRY
01508 _check_state();
01509 _check_close();
01510 _check_action();
01511 _set_action(async ? ACTION_OPEN_PROC_ASYNC : ACTION_OPEN_PROC);
01512 _process_sql(name);
01513 _get_number_params();
01514 _bind_params();
01515
01516 if (async)
01517 _start_thread();
01518 else
01519 {
01520 v_execute();
01521 _set_open();
01522 _get_columns_info();
01523 _rebind_params();
01524 _set_action(ACTION_NONE);
01525 }
01526 DB_CATCH
01527 }
01528
01529
01530
01531 bool
01532 dbserver_impl::exec_proc(bool async, const char* name)
01533 {
01534 DB_TRY
01535 _check_state();
01536 _check_close();
01537 _check_action();
01538 _set_action(async ? ACTION_EXEC_PROC_ASYNC : ACTION_EXEC_PROC);
01539 _process_sql(name);
01540 _get_number_params();
01541 _bind_params();
01542
01543 if (async)
01544 _start_thread();
01545 else
01546 {
01547 v_execute();
01548 _set_open();
01549 _rebind_params();
01550 _set_action(ACTION_NONE);
01551 }
01552 DB_CATCH
01553 }
01554
01555
01556
01557
01558 bool
01559 dbserver_impl::fetch_data(bool async, size_t start_row, size_t num_rows, bool forward)
01560 {
01561 DB_TRY
01562 _check_state();
01563 _check_open();
01564
01565
01566 _data.clear();
01567 _temp_allocator->reset();
01568 _data_allocator->reset();
01569
01570 _set_action(async ? ACTION_FETCH_ASYNC : ACTION_FETCH);
01571 _bind_columns();
01572 _start_row = start_row;
01573 _fetched_rows = 0;
01574 _requested_rows = num_rows;
01575 _forward = forward;
01576 _iter = get_iter_end();
01577
01578 if (async)
01579 _start_thread();
01580 else
01581 {
01582 v_fetch();
01583 }
01584 DB_CATCH
01585 }
01586
01587
01588
01589
01590 bool
01591 dbserver_impl::close_sql()
01592 {
01593 DB_TRY
01594 _check_state();
01595 _check_open();
01596 _thread.cancel_job();
01597 v_close();
01598 _set_close();
01599 _set_action(ACTION_NONE);
01600
01601 _sql = 0;
01602 _data.clear();
01603 _start_row = 0;
01604 _fetched_rows = 0;
01605 _forward = true;
01606 _bulk_rows = 100;
01607 _iter = get_iter_end();
01608
01609 _sql_allocator.reset();
01610 _temp_allocator->reset();
01611 _data_allocator->reset();
01612 _columns_allocator->reset();
01613
01614 _set_state(STATE_OK);
01615 DB_CATCH
01616 }
01617
01618 bool
01619 dbserver_impl::interrupt_request()
01620 {
01621
01622 if (get_state() == STATE_WORKING)
01623 {
01624
01625 _set_state(STATE_INTERRUPTED);
01626 v_interrupt_async();
01627 _thread.cancel_job();
01628 _set_state(STATE_OK);
01629 v_close();
01630
01631 _set_action(ACTION_NONE);
01632 }
01633
01634 return true;
01635 }
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 bool
01646 dbserver_impl::set_quote(char quote)
01647 {
01648 mutex_keeper keeper(_mtx);
01649 _quote = quote;
01650 return true;
01651 }
01652
01653 void
01654 dbserver_impl::set_callback(async_db_notify* target)
01655 {
01656 callback_finder finder(target);
01657 algorithm::push_back_if(_list_callback, finder, target, _mtx);
01658 }
01659
01660 void
01661 dbserver_impl::remove_callback(async_db_notify* target)
01662 {
01663 callback_finder finder(target);
01664 algorithm::remove_if(_list_callback, finder, _mtx);
01665 }
01666
01667
01668 void
01669 dbserver_impl::_get_number_params()
01670 {
01671
01672 v_form_sql_string();
01673
01674 v_replace_quote();
01675 }
01676
01677 void
01678 dbserver_impl::_bind_params()
01679 {
01680
01681 v_before_execute();
01682
01683 size_t count_params = _params.size();
01684
01685 for (size_t cur_param = 0; cur_param < count_params; ++cur_param)
01686
01687 v_bind_one_param(cur_param);
01688 }
01689
01690 void
01691 dbserver_impl::_rebind_params()
01692 {
01693
01694 v_after_execute();
01695
01696 size_t count_params = _params.size();
01697
01698 for (size_t cur_param = 0; cur_param < count_params; ++cur_param)
01699 {
01700
01701 v_rebind_one_param(cur_param);
01702 }
01703 }
01704
01705 void
01706 dbserver_impl::_bind_columns()
01707 {
01708
01709 size_t count_columns = _cols.size();
01710
01711
01712 size_t cur_column;
01713 size_t total_memory_per_row = 1;
01714
01715 for (cur_column = 0; cur_column < count_columns; ++cur_column)
01716 {
01717
01718 if (_cols[cur_column]._max_length < 1024*64)
01719 total_memory_per_row += _cols[cur_column]._max_length;
01720 }
01721
01722
01723
01724
01725 _bulk_rows = __max((size_t)1, __min((size_t)1024*1024 / total_memory_per_row, (size_t)1024));
01726
01727
01728
01729 v_before_bind_columns();
01730
01731
01732
01733 for (cur_column = 0; cur_column < count_columns; ++cur_column)
01734 {
01735
01736 v_bind_one_column(cur_column);
01737 }
01738 }
01739
01740 void
01741 dbserver_impl::_get_columns_info()
01742 {
01743 _cols.clear();
01744
01745
01746 size_t count_columns = v_get_number_columns();
01747
01748 _cols.resize(*_columns_allocator, count_columns);
01749
01750
01751 for (size_t cur_column = 0; cur_column < count_columns; ++cur_column)
01752 {
01753
01754 v_get_one_column_info(cur_column);
01755 _cols[cur_column]._type = v_native_type_to_client_type(_cols[cur_column]._native_type);
01756 }
01757 }
01758
01759 void
01760 dbserver_impl::_process_sql(const char* sql)
01761 {
01762 _sql = sql;
01763 }
01764
01765 void
01766 dbserver_impl::_start_thread()
01767 {
01768 if (THREAD_CLOSE == _thread.get_state())
01769 _thread.start();
01770
01771 job_task task(this, 0, INFINITE, 0);
01772 _set_state(STATE_WORKING);
01773 _thread.assign_job(task);
01774 _thread.wakeup();
01775 }
01776
01777 bool
01778 dbserver_impl::v_has_job(size_t ident, void* user_data)
01779 {
01780 module_state state = get_state();
01781 action action_ = get_action();
01782
01783 if (state == STATE_WORKING
01784 &&
01785 (action_ == ACTION_OPEN_SQL_ASYNC
01786 || action_ == ACTION_OPEN_PROC_ASYNC
01787 || action_ == ACTION_EXEC_SQL_ASYNC
01788 || action_ == ACTION_EXEC_PROC_ASYNC
01789 || action_ == ACTION_FETCH_ASYNC)
01790 )
01791 return true;
01792 else
01793 return false;
01794 }
01795
01796 void
01797 dbserver_impl::v_do_job(size_t ident, void* user_data)
01798 {
01799 module_state state = get_state();
01800 action action_ = get_action();
01801 if (state != STATE_WORKING)
01802 return;
01803
01804 try
01805 {
01806 switch(action_)
01807 {
01808 case ACTION_OPEN_SQL_ASYNC:
01809 v_execute();
01810 _set_open();
01811 _get_columns_info();
01812 break;
01813 case ACTION_OPEN_PROC_ASYNC:
01814 v_execute();
01815 _set_open();
01816 _get_columns_info();
01817 _rebind_params();
01818 break;
01819 case ACTION_EXEC_SQL_ASYNC:
01820 v_execute();
01821 _set_open();
01822 _rebind_params();
01823 break;
01824 case ACTION_EXEC_PROC_ASYNC:
01825 v_execute();
01826 _set_open();
01827 _rebind_params();
01828 break;
01829 case ACTION_FETCH_ASYNC:
01830 v_fetch();
01831 break;
01832 default:
01833 break;
01834 }
01835
01836
01837 _set_action(ACTION_NONE);
01838 _set_state(STATE_OK);
01839 _notify_async(true, _ident);
01840 }
01841 catch( exception& ex )
01842 {
01843 _thread.cancel_job();
01844 _code = ex.get_code();
01845 _error = ex.what();
01846 _set_state(STATE_OK);
01847 _notify_async(false, _ident);
01848 }
01849 catch(...)
01850 {
01851 _thread.cancel_job();
01852 _set_state(STATE_OK);
01853 _notify_async(false, _ident);
01854 }
01855 }
01856
01857 void
01858 dbserver_impl::_notify_async(bool noerrors, size_t ident)
01859 {
01860 callback_fire fire(noerrors, ident);
01861 algorithm::for_each(_list_callback, fire, _mtx);
01862 }
01863
01864 bool
01865 dbserver_impl::_is_asynchronous_action() const
01866 {
01867 switch (get_action())
01868 {
01869 case ACTION_OPEN_SQL_ASYNC:
01870 case ACTION_OPEN_PROC_ASYNC:
01871 case ACTION_EXEC_SQL_ASYNC:
01872 case ACTION_EXEC_PROC_ASYNC:
01873 case ACTION_FETCH_ASYNC:
01874 return true;
01875 default:
01876 return false;
01877 }
01878 }
01879
01880
01881
01882
01883
01884 bool
01885 dbserver_impl::param_bulk_store()
01886 {
01887
01888 size_t num = _params.size();
01889 if (!num)
01890 return false;
01891
01892 size_t capacity = _bulk_params.size();
01893
01894 if (capacity >= 1024)
01895 return false;
01896
01897
01898 _vector< binder > item;
01899
01900 bulk_params_t::iterator iter_vec = _bulk_params.push_back(item);
01901 if (iter_vec == _bulk_params.end())
01902 return false;
01903
01904 if (!iter_vec->resize(*_bulk_allocator, num))
01905 return false;
01906
01907
01908 for (size_t index = 0; index < num; ++index)
01909 {
01910
01911 _params[index].clone((*iter_vec)[index]);
01912 }
01913
01914 return true;
01915 }
01916
01917
01918 bool
01919 dbserver_impl::param_bulk_remove()
01920 {
01921 if (_bulk_params.empty())
01922 return false;
01923
01924 try
01925 {
01926 _vector< binder >& r_vec = _bulk_params.back();
01927
01928
01929 size_t num = r_vec.size();
01930
01931 for (size_t index = 0; index < num; ++index)
01932 {
01933
01934 _params[index].deallocate_value();
01935
01936 r_vec[index].clone(_params[index]);
01937
01938 r_vec[index].deallocate_value();
01939 }
01940
01941
01942 _bulk_params.pop_back();
01943
01944 if (_bulk_params.empty())
01945 _bulk_allocator->reset();
01946
01947 }
01948 catch (...)
01949 {
01950 return false;
01951 }
01952
01953 return true;
01954 }
01955
01956 bool
01957 dbserver_impl::param_bulk_remove_all()
01958 {
01959 if (_bulk_params.empty())
01960 return false;
01961
01962 try
01963 {
01964
01965 for (bulk_params_t::iterator it_list = _bulk_params.begin(); it_list != _bulk_params.end(); ++it_list)
01966 {
01967 for (_vector< binder >::iterator it_vec = it_list->begin(); it_vec != it_list->end(); ++it_vec)
01968 {
01969 it_vec->deallocate_value();
01970 }
01971 }
01972
01973 _bulk_params.clear();
01974 _bulk_allocator->reset();
01975 }
01976 catch (...)
01977 {
01978 return false;
01979 }
01980
01981 return true;
01982 }
01983
01984
01986
01988 db_arg::db_arg( size_t ident,
01989 bool trusted,
01990 const char* login_string
01991 ) :
01992 _ident(ident),
01993 _trusted(trusted),
01994 _login_string(login_string)
01995 {
01996 }
01997
01999 db_entry::db_entry(size_t ident,
02000 bool trusted,
02001 const char* login_string
02002 ) :
02003 db_arg(ident, trusted, login_string),
02004 _obj(0)
02005 {
02006 }
02007
02008
02009 #pragma pack()
02010 END_TERIMBER_NAMESPACE