35 #ifdef HAVE_LIBNCBICRYPT
36 # include <ncbi_key_lookup.h>
47 #include "../rw_impl.hpp"
50 #define NCBI_USE_ERRCODE_X Dbapi_Sdbapi
56 #define SDBAPI_CATCH_LOWLEVEL() \
57 catch (CDB_DeadlockEx& ex) { \
58 NCBI_RETHROW(ex, CSDB_DeadlockException, eLowLevel, ""); \
59 } catch (CDB_Exception& ex) { \
60 NCBI_RETHROW(ex, CSDB_Exception, eLowLevel, ""); \
63 #define SDBAPI_THROW(code, msg) \
64 NCBI_THROW(CSDB_Exception, code, \
65 CDB_Exception::SMessageInContext(msg, x_GetContext()))
247 "Conversion between " +
string(one_type) +
" and "
249 +
" is not supported");
252 #ifdef NCBI_COMPILER_WORKSHOP
253 #define CONVERTVALUE_STATIC
255 #define CONVERTVALUE_STATIC static
275 string str_val = from_val.
AsString();
277 to_var.
Append(str_val.data(), str_val.size());
290 to_var =
Int8(from_val);
302 to_var.
Append(str_val.data(), str_val.size());
315 to_var =
Int8(from_val);
318 to_var =
Int4(from_val);
330 to_var.
Append(str_val.data(), str_val.size());
343 to_var =
Int8(from_val);
346 to_var =
Int4(from_val);
349 to_var =
Int2(from_val);
361 to_var.
Append(str_val.data(), str_val.size());
374 to_var =
Int8(from_val);
377 to_var =
Int4(from_val);
380 to_var =
Int2(from_val);
383 to_var =
Uint1(from_val);
395 to_var.
Append(str_val.data(), str_val.size());
408 to_var =
Int8(from_val);
411 to_var =
Int4(from_val);
414 to_var =
Int2(from_val);
417 to_var =
Uint1(from_val);
420 to_var =
bool(from_val);
432 to_var.
Append(str_val.data(), str_val.size());
445 to_var = float(from_val);
448 to_var = double(from_val);
460 to_var.
Append(str_val.data(), str_val.size());
473 to_var = double(from_val);
485 to_var.
Append(str_val.data(), str_val.size());
515 to_var.
Append(from_val.data(), from_val.size());
524 to_var = NStr::StringToNumeric<Int2>(from_val);
527 to_var = NStr::StringToNumeric<Uint1>(from_val);
538 to_var =
CTime(from_val);
563 s_ConvertValue(
string(
reinterpret_cast<const char*
>(from_val.data()),
575 to_var.
Append(
reinterpret_cast<const char*
>(from_val.data()),
592 #undef CONVERTVALUE_STATIC
680 "Value for Int4 is out of bounds: "
683 to_val =
Int4(temp_val);
717 "Value for short is out of bounds: "
720 to_val = short(temp_val);
737 to_val =
static_cast<unsigned char>(from_var.
GetBit());
754 "Value for unsigned char is out of bounds: "
757 to_val =
static_cast<unsigned char>(temp_val);
772 to_val = from_var.
GetBit();
785 if (temp_val != 0 && temp_val != 1)
788 "Value for bool is out of bounds: "
791 to_val = temp_val == 1;
878 "fNBS_ZLib and fNBS_BZLib are mutually incompatible; "
879 "please specify at most one compression algorithm.");
930 || driver_name ==
"ftds100") {
933 ERR_POST_X(15,
"Unsupported driver name " << driver_name
977 "Password decryption failed.");
991 #ifdef HAVE_LIBNCBICRYPT
993 key = NCBICRYPT_FindBuiltinKey(
string(key_id).c_str());;
998 "Unknown password decryption key ID " +
string(key_id));
1036 "Connection parameters miss at least one essential part"
1037 " (host, user, password, or database [as \"path\"]): "
1062 if ( !it->value.empty() ) {
1082 static const char*
kDefault =
"default";
1090 #define COPY_PARAM_EX(en, gn, fn) \
1091 if (conf_params.Is##gn##Set()) \
1092 m_ParamMap[e##en] = conf_params.fn
1093 #define COPY_PARAM(en, fn) COPY_PARAM_EX(en, en, fn)
1094 #define COPY_BOOL_PARAM(en, gn, fn) \
1095 if (conf_params.Is##gn##Set()) \
1096 m_ParamMap[e##en] = conf_params.fn.empty() ? "default" \
1097 : NStr::StringToBool(conf_params.fn) ? "true" : "false"
1098 #define COPY_NUM_PARAM(en, gn, fn) \
1099 if (conf_params.Is##gn##Set()) \
1100 m_ParamMap[e##en] = conf_params.fn.empty() ? kDefault : conf_params.fn
1120 pool_allow_temp_overflow);
1122 continue_after_raiserror);
1123 COPY_NUM_PARAM (ConnPoolMaxConnUse, PoolMaxConnUse, pool_max_conn_use);
1124 COPY_BOOL_PARAM(LogMinorMessages, LogMinorMessages, log_minor_messages);
1126 #undef COPY_PARAM_EX
1128 #undef COPY_BOOL_PARAM
1129 #undef COPY_NUM_PARAM
1131 if ( !conf_params.
args.empty() ) {
1146 " password_file parameters are mutually exclusive.");
1165 password = it->second;
1168 if (pwfile.empty()) {
1175 "Unable to open password file " + pwfile +
": " +
1184 if ( !key_id.empty() ) {
1187 password = decryptor->Decrypt(password, key_id);
1188 ITERATE (
string, pit, password) {
1189 if ( !
isprint((
unsigned char)*pit) ) {
1192 "Invalid character in supposedly decrypted"
1211 if ( !port.empty() ) {
1219 if (params->
GetParam(
"is_pooled") ==
"true") {
1223 if ( !explicit_pool_name.empty() ) {
1224 params->
SetParam(
"pool_name", explicit_pool_name);
1230 params->
SetParam(
"pool_max_conn_use",
1246 typedef vector<CUrlArgs*> TAllArgs;
1250 unique_ptr<CUrlArgs> conf_args;
1254 conf_args.reset(
new CUrlArgs(it->second));
1255 all_args.push_back(conf_args.get());
1259 ITERATE (TAllArgs, ait, all_args) {
1262 const string& param_name = uit->name;
1263 const string& param_value = uit->value;
1265 params->
SetParam(param_name, param_value);
1270 params->
SetParam(
"do_not_read_conf",
"true");
1275 const string& name,
EParam id)
const
1289 if (code_value == reg_value) {
1298 conf_map[it->name] = it->value;
1302 TConfMap::const_iterator cmit = conf_map.find(uait->name);
1303 if (cmit != conf_map.end()) {
1308 ERR_POST_X(18,
Info <<
"Using privately configured service alias "
1309 << code_value <<
" -> " << reg_value);
1312 code_value =
"(redacted)";
1313 reg_value =
"(redacted)";
1316 <<
" parameter value " << code_value <<
" for "
1331 list<string> sections;
1333 ITERATE(list<string>, it, sections) {
1334 const string& name = *it;
1335 if (name.size() <= 10
1344 if (lower_params.
GetParam(
"is_pooled") ==
"true") {
1345 result &=
ctx->SatisfyPoolMinimum(lower_params);
1367 "CSDBAPI::UseDriver called with SDBAPI already in use.");
1477 list<string>* servers ,
1478 string* error_message )
1480 if (dbservice.empty()) {
1482 "Mirrored database service name cannot be empty");
1485 bool first_execution =
false;
1486 SMirrorInfo& mir_info = (*s_MirrorsData)[dbservice];
1489 first_execution =
true;
1498 first_execution =
true;
1501 if (conn_params.
GetParam(
"single_server") !=
"true") {
1503 "UpdateMirror cannot be used when configuration file "
1504 "doesn't have exclusive_server=true (for " + dbservice
1511 "UpdateMirror cannot work with non-standard "
1512 "connection factory");
1518 error_message->clear();
1523 bool need_reread_servers =
false;
1524 bool servers_reread =
false;
1525 bool has_master =
false;
1526 int cnt_switches = 0;
1529 if (serv_list.empty()) {
1530 list<string> servers;
1532 ITERATE(list<string>, it, servers) {
1534 serv_list.back()->server_name = *it;
1537 servers_reread =
true;
1539 else if (need_reread_servers) {
1540 list<string> new_serv_info;
1544 ITERATE(list<string>, it, new_serv_info) {
1545 if (*it == (*old_it)->server_name) {
1551 serv_list.erase(old_it);
1554 ITERATE(list<string>, new_it, new_serv_info) {
1557 if ((*old_it)->server_name == *new_it) {
1564 serv_list.back()->server_name = *new_it;
1568 servers_reread =
true;
1570 if (serv_list.empty()) {
1572 ERR_POST_X(3,
"No servers for service '" << service_name
1573 <<
"' are available");
1574 if (error_message) {
1575 *error_message =
"No servers for service '" + service_name
1576 +
"' are available";
1581 for (TMirrorServList::iterator it = serv_list.end(); it != serv_list.begin(); )
1585 const string& server_name = (*it)->server_name;
1590 if (!
conn->IsAlive()) {
1592 ERR_POST_X(7,
"Connection to server '" << server_name
1593 <<
"' for service '" << service_name
1599 serv_params.
SetParam(
"is_pooled",
"false");
1600 serv_params.
SetParam(
"do_not_dispatch",
"true");
1603 conn->Connect(serv_params);
1605 ERR_POST_X(8,
"Connection to server '" << server_name
1606 <<
"' for service '" << service_name
1607 <<
"' is restored.");
1615 ERR_POST_X(9,
"Cannot establish connection to server '"
1616 << server_name <<
"' for service '"
1617 << service_name <<
"'.");
1621 need_reread_servers =
true;
1624 bool success =
false;
1625 if (
conn->IsAlive()) {
1628 stmt->ExecuteUpdate(
"use " + db_name);
1637 if (!success && server_name == mir_info.
master) {
1639 string pool_name = conn_params.
GetParam(
"pool_name");
1641 ERR_POST_X(4,
"The master for database '" << db_name <<
1642 "' (service '" << service_name <<
1643 "') has become inaccessible. Because of this " <<
1644 invalidated_count <<
1645 " active connections got invalidated in the pool '" <<
1648 need_reread_servers =
true;
1650 else if (success && server_name != mir_info.
master) {
1652 string pool_name = conn_params.
GetParam(
"pool_name");
1653 size_t invalidated_count =
1656 conn->GetCDB_Connection()->Host(),
1657 conn->GetCDB_Connection()->Port());
1658 string msg_start =
"The master for database '" + db_name +
1659 "' (for service '" + service_name +
1660 "') switched to '" + server_name +
"' from ";
1661 string msg_end =
". Because of this " +
1663 " active connections got invalidated in the pool '" +
1666 if (mir_info.
master.empty()) {
1668 ERR_POST_X(5, Message << msg_start <<
"NONE" << msg_end);
1672 mir_info.
master <<
"'" << msg_end);
1677 mir_info.
master = server_name;
1678 serv_list.push_front(*it);
1679 TMirrorServList::iterator it_del = it++;
1680 serv_list.erase(it_del);
1681 need_reread_servers =
true;
1683 if (++cnt_switches == 10) {
1686 "Mirror database switches too frequently or "
1687 "it isn't mirrored: " + service_name);
1690 else if (success && server_name == mir_info.
master) {
1695 while (need_reread_servers && !servers_reread);
1697 if (first_execution && !has_master) {
1699 string pool_name = conn_params.
GetParam(
"pool_name");
1701 ERR_POST_X(10,
"The master for database '" << db_name <<
1702 "' (service '" << service_name <<
1703 "') is not accessible. Because of this " <<
1704 invalidated_count <<
1705 " active connections got invalidated in the pool '" <<
1711 servers->push_back((*it)->server_name);
1716 *error_message =
"All database instances are inaccessible";
1724 TNewBlobStoreFlags
flags,
1730 " variant of NewBlobStore that inspects column types"
1744 if (ex ==
nullptr) {
1756 const string& message)
1758 if (severity < 10 || (severity == 10 && msgnum == 0)) {
1759 if (severity == 0 || (severity == 10 && msgnum == 0)) {
1767 && (severity == 16 || (severity == 10 && msgnum > 0))) {
1780 (severity, msgnum, message);
1788 m_DefaultTimeout(0),
1789 m_HasCustomTimeout(
false),
1790 m_ContinueAfterRaiserror
1842 unsigned int sec, nanosec;
1843 timeout.
GetNano(&sec, &nanosec);
1887 conn->Connect(lower_params);
1901 : m_Conn(other.m_Conn),
1902 m_IsOpen(other.m_IsOpen),
1903 m_EverConnected(other.m_EverConnected)
2040 }
else if (check_method ==
eNoCheck) {
2046 if ( !
conn->IsAlive() ) {
2057 query.RequireRowCount(1);
2060 && row[1].AsInt4() == 1);
2063 }
catch (exception&) {
2079 #define CONNECT_AS_NEEDED() x_ConnectAsNeeded(NCBI_CURRENT_FUNCTION)
2097 const string& search_conditions,
2104 switch (column_type) {
2116 unique_ptr<I_BlobDescriptor> desc
2118 desc_type, has_legacy_type));
2126 TNewBlobStoreFlags
flags,
2132 " variant of NewBlobStore that inspects column types"
2143 const string& key_col_name,
2144 const string& num_col_name,
2145 const vector<string> blob_col_names,
2146 TNewBlobStoreFlags
flags,
2153 &blob_col_names[0], blob_col_names.size(),
2167 +
" when not connected.");
2176 : m_DBImpl(db_impl),
2178 m_Autoflush(autoflush),
2181 m_WriteStarted(
false),
2210 "Cannot write into completed CBulkInsert");
2217 "Cannot write into CBulkInsert when CDatabase was closed");
2219 if (col != 0 && col >
int(
m_Cols.size())) {
2221 "Too many values were written to CBulkInsert: "
2254 "Cannot bind columns when already started to insert");
2256 if (col - 1 !=
int(
m_Cols.size())) {
2258 "Cannot bind columns in CBulkInsert randomly");
2273 "Not enough values were written to CBulkInsert: "
2297 unique_ptr<IBulkInsert> bi(
m_BI);
2311 for (
unsigned int i = 0;
i <
m_Cols.size(); ++
i) {
2450 #if !NCBI_INT8_IS_LONG
2454 #if SIZEOF_LONG == 8
2526 : m_Basis(new
CParamQFB(v, q->x_GetContext(), param_type))
2536 : m_Basis(qf.m_Basis.release())
2595 : m_Fields(
r.m_Fields), m_MetaData(
r.m_MetaData)
2605 if (col == 0 || col > m_Fields.size()) {
2608 "No such column in the result set: "
2615 x_CheckColumnNumber(col);
2616 return m_Fields[col - 1];
2622 = m_MetaData->col_nums.find(col);
2623 if (it == m_MetaData->col_nums.end()) {
2626 "No such column in the result set: " + col +
". "
2629 return m_Fields[it->second - 1];
2635 return m_Fields.size();
2640 x_CheckColumnNumber(col);
2641 return m_MetaData->col_names[col - 1];
2646 x_CheckColumnNumber(col);
2647 return m_MetaData->col_types[col - 1];
2654 m_MetaData->exception_context.Reset(&q.
x_GetContext());
2659 m_Fields.reserve(cols_cnt);
2660 for (
unsigned int i = 1;
i <= cols_cnt; ++
i) {
2662 m_MetaData->col_nums[meta->
GetName(
i)] =
i;
2663 m_MetaData->col_names.emplace_back(meta->
GetName(
i));
2671 : m_DBImpl(db_impl),
2675 m_IgnoreBounds(
true),
2676 m_HasExplicitMode(
false),
2677 m_RSBeginned(
false),
2680 m_ReportedWrongRowCount(
false),
2682 m_RowUnderConstruction(
false),
2713 oss << (
m_IsSP ?
"RPC: " :
"SQL: ");
2717 oss <<
"; input parameter(s): ";
2721 oss << it->first <<
" = ";
2725 oss <<
value->GetData()->GetLogString();
2739 "CQuery is not operational because CDatabase was closed");
2745 "CQuery is closed or never executed");
2765 it->second.x_Detach();
2766 static_cast<CParamQFB&
>(*it->second.m_Impl->m_Basis)
2767 .SetParamType(param_type);
2775 const_cast<CVariant&
>(*it->second.m_Impl->GetValue()));
2792 it->second.x_Detach();
2793 static_cast<CParamQFB&
>(*it->second.m_Impl->m_Basis)
2794 .SetParamType(param_type);
2814 it->second.x_Detach();
2839 "Parameter '" +
string(name) +
"' doesn't exist. "
2841 }
else if (
static_cast<const CParamQFB&
>(*it->second.m_Impl->m_Basis)
2846 "CQuery::GetParameter called with some results still"
2861 it->second.x_Detach();
2871 p.second.x_Detach();
2912 "Problem while closing DB query "
2913 "(result was at row number " << orig_row_no <<
2914 " and is now at row number " <<
m_CurRowNo <<
").");
2958 "No statement to execute.");
2998 =
static_cast<const CParamQFB&
>(*it->second.m_Impl->m_Basis);
3057 "CQuery::GetRowCount called with some results still"
3070 "CQuery::GetStatus called with some results still"
3097 "Too many rows returned (limited to "
3103 "Not enough rows returned ("
3155 while (
stmt->HasMoreResults()) {
3169 for (
unsigned int i = 1;
i <= col_cnt; ++
i) {
3180 <<
"Multiple SDBAPI result sets found, but"
3181 " neither SingleSet nor MultiSet explicitly"
3182 " requested. Now defaulting to SingleSet. "
3234 if ( !has_more_rs ) {
3240 "All result sets in CQuery were already iterated through. "
3262 bool has_more =
true;
3270 while (has_more && rs !=
m_CurRS) {
3330 "RequireRowCount must follow Execute or ExecuteSP,"
3331 " which reset any requirements.");
3333 if (min_rows > max_rows) {
3335 "Inconsistent row-count constraints: "
3340 _TRACE(
"RequireRowCount(" << min_rows <<
", " << max_rows <<
')');
3353 bool missed_results =
false;
3383 if (missed_results) {
3412 nc_self.
m_Row = saved_row;
3455 : m_DBImpl(db_impl),
3537 : m_Query(ri.m_Query),
3555 return m_Query->x_GetContext();
3561 return m_Query->GetResultSetNo();
3567 return m_Query->GetRowNo();
3573 return m_Query->GetTotalColumns();
3579 return m_Query->GetColumnName(col);
3585 return m_Query->GetColumnType(col);
3593 else if (m_IsEnd ^ ri.
m_IsEnd) {
3594 return m_Query->IsFinished();
3603 if (m_IsEnd || m_Query->IsFinished()) {
3605 "Cannot increase end() iterator");
3614 return m_Query->GetRow()[col];
3620 return m_Query->GetRow()[col];
3625 return m_Query->GetRow();
3631 unique_ptr<IQueryFieldBasis> new_basis
3634 m_Basis.reset(new_basis.release());
3640 unique_ptr<IQueryFieldBasis> new_basis
3643 m_Basis.reset(new_basis.release());
3657 return m_Basis->x_GetContext();
3663 return m_Basis->GetValue();
3677 unsigned char value = 0;
3738 const vector<unsigned char>&
3742 string(
"Method is unsupported for this type of data: ")
3746 const vector<unsigned char>&
3749 const CVariant& var_val = *GetValue();
3754 const unsigned char* data
3755 =
reinterpret_cast<const unsigned char*
>(
value.data());
3757 m_Vector.insert(m_Vector.begin(), data, data +
value.size());
3761 const vector<unsigned char>&
3764 return m_Impl->AsVector();
3771 string(
"Method is unsupported for this type of data: ")
3778 const CVariant& var_val = *GetValue();
3788 return m_Impl->AsIStream();
3794 return m_Impl->GetValue()->IsNull();
3800 "Method requires a live field");
3806 const CVariant& var_val = *GetValue();
3812 blob_size,
flags,
false),
3823 string(
"Method is unsupported for this type of data: ")
3830 m_OStream.reset(m_Basis->GetOStream(blob_size,
flags));
3843 return GetOStream(blob_size,
3850 "Method requires a live field");
3855 const CVariant& var_val = *GetValue();
3865 string(
"Method is unsupported for this type of data: ")
3871 return m_Basis->GetBookmark();
3877 return m_Impl->GetBookmark();
3905 const string&
value,
3955 unsigned char value,
4079 "Exactly one row requested while RequireRowCount() set "
4084 "Exactly one row requested while RequireRowCount() set "
4091 "Expected exactly one row, but none are available");
4098 "Expected exactly one row, but more than one are available");
Helper class to allow safe initialization from higher-layer objects.
unique_ptr< I_BlobDescriptor > m_Descr
CRef< CDatabaseImpl > m_DBImpl
unique_ptr< CWStream > m_OStream
CNcbiOstream & GetOStream(size_t blob_size, TBlobOStreamFlags flags)
CBlobBookmarkImpl(CDatabaseImpl *db_impl, I_BlobDescriptor *descr)
Object used to store bookmarks to blobs to be changed later.
CBlobBookmark & operator=(const CBlobBookmark &bm)
CNcbiOstream & GetOStream(size_t blob_size, TBlobOStreamFlags flags=0) const
Get Blob output stream.
CRef< CBlobBookmarkImpl > m_Impl
Bookmark implementation object.
CBlobBookmark(void)
Empty constructor of bookmark object.
EBlobType
Blob type (if known).
void x_CheckCanWrite(int col)
CRef< CDB_Exception::SContext > m_Context
void Bind(int col, ESDB_Type type)
void AddOrderHint(CTempString columns)
void x_CheckWriteStarted(void)
CBulkInsertImpl(CDatabaseImpl *db_impl, const string &tableName, int autoflush)
const CDB_Exception::SContext & x_GetContext(void) const
void WriteVal(const T &val)
void SetHints(CTempString hints)
CRef< CDatabaseImpl > m_DBImpl
void AddHint(IBulkInsert::EHints hint, unsigned int value)
vector< CVariant > m_Cols
Object used to perform bulk-inserting operations to database.
CBulkInsert & operator<<(const string &val)
Put values of different type into bulk-insert row.
EHints
Type of hint that can be set for bulk insert.
void AddHint(EHints hint)
Add hint to the bulk insert.
void Complete()
Complete bulk insert.
void Bind(int col, ESDB_Type type)
Bind column for bulk insert.
void AddOrderHint(CTempString columns)
Add "ORDER" hint.
EHintsWithValue
Type of hint that requires some value to be provided with it.
void SetHints(CTempString hints)
Set hints by one call. Resets everything that was set by Add*Hint().
CRef< CBulkInsertImpl > m_Impl
Bulk-insert implementation object.
CBulkInsert(void)
Empty constructor of bulk-insert object.
CBulkInsert & operator=(const CBulkInsert &bi)
void SetTimeout(const CTimeout &timeout)
CRef< CDB_Exception::SContext > m_Context
virtual ~CConnHolder(void)
bool m_ContinueAfterRaiserror
list< string > m_PrintOutput
CRef< CSDB_UserHandler > m_Handler
IConnection * GetConn(void) const
CConnHolder(IConnection *conn, const CSDB_ConnectionParam ¶ms)
const CDB_Exception::SContext & GetContext(void) const
const list< string > & GetPrintOutput(void) const
Helper hook-up class that installs default logging/registry/locking (but only if they have not yet be...
void SetEncoding(EEncoding encoding)
void SetPassword(const string &passwd)
void SetDriverName(const string &name)
void SetParam(const string &key, const string &value)
void SetServerName(const string &name)
void SetDatabaseName(const string &name)
void SetUserName(const string &name)
void GetServersList(const string &validator_name, const string &service_name, list< string > *serv_list)
void WorkWithSingleServer(const string &validator_name, const string &service_name, const string &server)
CDataSourceInitializer(void)
void Connect(const CSDB_ConnectionParam ¶ms)
CRef< CConnHolder > m_Conn
const list< string > & GetPrintOutput(void) const
IConnection * GetConnection(void)
const CDB_Exception::SContext & GetContext(void) const
bool EverConnected() const
void SetTimeout(const CTimeout &timeout)
Database connection object.
void Close(void)
Close database object.
CDatabase & operator=(const CDatabase &db)
void Connect(void)
Explicitly (re)connect to the database server.
CQuery NewQuery(void)
Get new CQuery object for this database.
CDatabase Clone(void)
Clone database object.
CBlobBookmark NewBookmark(const string &table_name, const string &column_name, const string &search_conditions, CBlobBookmark::EBlobType column_type=CBlobBookmark::eUnknown, ETriState has_legacy_type=eTriState_Unknown)
Get new CBlobBookmark object.
CBulkInsert NewBulkInsert(const string &table_name, int autoflush)
Get new CBulkInsert object.
EConnectionCheckMethod
How thoroughly IsConnected should actually check the connection.
CRef< CDatabaseImpl > m_Impl
Database implementation object.
CBlobStoreStatic * NewBlobStore(const string &table_name, TNewBlobStoreFlags flags=TNewBlobStoreFlags(0), size_t image_limit=1<< 24)
Get new CBlobStoreStatic object (to be owned by caller).
bool IsConnected(EConnectionCheckMethod check_method=eNoCheck)
Check if database object was already connected to database server.
CSDB_ConnectionParam m_Params
Database parameters.
void x_ConnectAsNeeded(const char *operation)
CDatabase(void)
Empty constructor of database object.
CRef< IDBConnectionFactory > GetConnectionFactory(void) const
Retrieve a connection factory.
static CDbapiConnMgr & Instance(void)
Get access to the class instance.
Incapsulate compile time information such as __FILE__, __LINE__, NCBI_MODULE, current function.
const CVariant * GetValue(void) const override
static CNcbiApplication * Instance(void)
Singleton method.
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
ESP_ParamType GetParamType(void) const
CRef< CQueryFieldImpl > Detach(void) override
const vector< unsigned char > & AsVector(void) const override
CNcbiOstream & GetOStream(size_t blob_size, TBlobOStreamFlags flags) const override
CBlobBookmark GetBookmark(void) const override
CQueryBlobImpl(CQueryImpl *q, unsigned int col_num)
CNcbiIstream & AsIStream(void) const override
const CDB_Exception::SContext & x_GetContext(void) const
virtual CNcbiOstream & GetOStream(size_t blob_size, TBlobOStreamFlags flags) const
virtual CNcbiIstream & AsIStream(void) const
const CVariant * GetValue(void) const
virtual CRef< CQueryFieldImpl > Detach(void)
virtual const vector< unsigned char > & AsVector(void) const
CQueryFieldImpl(CQueryImpl *q, unsigned int col_num)
virtual CBlobBookmark GetBookmark(void) const
unsigned int GetRowNo(CQuery::EHowMuch how_much=CQuery::eAllResultSets) const
const list< string > & GetPrintOutput(void) const
void SetSql(CTempString sql)
ICallableStatement * m_CallStmt
unsigned int GetResultSetNo(void) const
void x_InitRSFields(void)
void ClearParameter(CTempString name)
unsigned int m_MaxRowCount
unsigned int GetMaxRowCount(void) const
void x_CheckCanWork(bool need_rs=false) const
void SetNullParameter(CTempString name, ESDB_Type type, ESP_ParamType param_type)
void x_SetOutParameter(const string &name, const CVariant &value)
void SetParameter(CTempString name, const T &value, ESDB_Type type, ESP_ParamType param_type)
CRef< CDatabaseImpl > m_DBImpl
int GetStatus(void) const
void x_InitBeforeExec(void)
void Execute(const CTimeout &timeout)
void ExecuteSP(CTempString sp, const CTimeout &timeout)
unsigned int GetMinRowCount(void) const
CDatabaseImpl * GetDatabase(void) const
void SetIgnoreBounds(bool is_ignore)
bool m_ReportedWrongRowCount
CQueryImpl(CDatabaseImpl *db_impl)
unsigned int m_MinRowCount
void x_ClearAllParams(void)
unsigned int GetTotalColumns(void) const
CRef< CDB_Exception::SContext > m_Context
string GetColumnName(unsigned int col) const
const CQuery::CField & GetParameter(CTempString name)
void ClearParameters(void)
IConnection * GetConnection(void)
const CQuery::CRow & GetRow(void) const
bool HasMoreResultSets(void)
bool m_RowUnderConstruction
void x_DetachAllFields(void)
ESDB_Type GetColumnType(unsigned int col) const
unsigned int m_CurRelRowNo
void RequireRowCount(unsigned int min_rows, unsigned int max_rows)
const CQuery::CField & GetColumn(const CDBParamVariant &col) const
void x_CheckRowCount(void)
bool IsFinished(CQuery::EHowMuch how_much=CQuery::eThisResultSet) const
void VerifyDone(CQuery::EHowMuch how_much=CQuery::eThisResultSet)
const CDB_Exception::SContext & x_GetContext(void) const
int GetRowCount(void) const
const CVariant & GetFieldValue(unsigned int col_num)
Class representing value in result set or output parameter of stored procedure.
CNcbiOstream & GetOStream(size_t blob_size, TBlobOStreamFlags flags=0) const
Get a blob output stream, on top of a cloned connection.
bool IsNull(void) const
Check if value is NULL.
bool AsBool(void) const
Get value as bool.
Int8 AsInt8(void) const
Get value as 8-byte integer.
const vector< unsigned char > & AsVector(void) const
Get value as vector of bytes.
Int4 AsInt4(void) const
Get value as 4-byte integer.
CNcbiIstream & AsIStream(void) const
Get value as input stream.
unsigned char AsByte(void) const
Get value as single byte.
CTime AsDateTime(void) const
Get value as CTime.
string AsString(void) const
Get value as UTF-8 string.
short AsShort(void) const
Get value as short integer.
double AsDouble(void) const
Get value as double.
CBlobBookmark GetBookmark(void) const
Get bookmark for the blob.
float AsFloat(void) const
Get value as float.
Iterator class doing main navigation through result sets.
ESDB_Type GetColumnType(unsigned int col) const
Get type of the column with given number in the current result set.
bool operator==(const CRowIterator &ri) const
Comparison of iterators.
unsigned int GetResultSetNo(void) const
Get number of currently active result set.
unsigned int GetTotalColumns(void) const
Get number of columns in the current result set.
const CDB_Exception::SContext & x_GetContext(void) const
CRowIterator(void)
Empty constructor of iterator.
const CRow & operator*(void) const
Get the full row. (The caller is welcome to keep a copy.)
CRowIterator & operator=(const CRowIterator &ri)
bool m_IsEnd
Flag showing whether this is constant pointer to the end or pointer to some particular row.
CRowIterator & operator++(void)
Advance iterator to the next row in the result set.
unsigned int GetRowNo(void) const
Get row number currently active.
string GetColumnName(unsigned int col) const
Get name of the column with given number in the current result set.
const CField & operator[](unsigned int col) const
Get column value by its number.
CRef< CQueryImpl > m_Query
Query iterator was created for.
A full row of result data.
void x_CheckColumnNumber(unsigned int col) const
CRef< SQueryRSMetaData > m_MetaData
ESDB_Type GetColumnType(unsigned int col) const
Get type of the column with given number in the row.
vector< CField > m_Fields
unsigned int GetTotalColumns(void) const
Get number of columns in the row.
const string & GetColumnName(unsigned int col) const
Get name of the column with given number in the row.
const CField & operator[](unsigned int col) const
Get column value by its number.
void x_Reset(CQueryImpl &q, IResultSet &rs)
const CDB_Exception::SContext & x_GetContext(void) const
Object used to execute queries and stored procedures on the database server and retrieve result sets.
bool HasMoreResultSets(void)
Check if any more result sets are available for reading.
CQuery & SetSql(CTempString sql)
Set current sql statement.
int GetStatus(void) const
Get return status of stored procedure.
CQuery & MultiSet(void)
Convert this query to not merge different result sets, i.e.
CRow GetTheOnlyRow(void)
Provides the only row for the executed query.
CQuery & ClearParameters(void)
Remove all parameters from parameter list.
unsigned int GetTotalColumns(void) const
Get total number of columns in the current result set.
EAllowLog
Allow transaction log (general, to avoid using bools).
@ eDisableLog
Disables log.
CRowIterator end(void) const
Get iterator pointing to the end of the current result set or to the end of all result sets (dependin...
ESDB_Type GetColumnType(unsigned int col) const
Get type of the column with given number in the current result set All columns are numbered starting ...
EHowMuch
Whether to consider just the current result set or all result sets, in MultiSet mode.
void VerifyDone(EHowMuch how_much=eThisResultSet)
Ensure that no unread rows or parameter results remain, and that the total number of rows satisfies a...
CRef< CQueryImpl > m_Impl
Query implementation object.
void Cancel(void)
Cancel the current statement or procedure call.
CQuery & SetNullParameter(CTempString name, ESDB_Type type, ESP_ParamType param_type=eSP_In)
Assign null value to the parameter.
CRowIterator begin(void) const
Start iterating through next result set.
const CField & GetParameter(CTempString name)
Get value of the parameter.
CQuery & ClearParameter(CTempString name)
Remove parameter with given name from parameter list.
CQuery & Execute(const CTimeout &timeout=CTimeout(CTimeout::eDefault))
Explicitly execute sql statement.
const list< string > & GetPrintOutput(void) const
Get any PRINT output from the latest procedure call (or statement).
void RequireRowCount(unsigned int n)
Indicate precisely how many rows the active query should return.
CQuery(void)
Empty constructor of query object.
CQuery & SetParameter(CTempString name, const string &value, ESDB_Type type=eSDB_String, ESP_ParamType param_type=eSP_In)
Assign string value to the parameter.
unsigned int GetRowNo(EHowMuch how_much=eAllResultSets) const
Get row number currently active.
CQuery & ExecuteSP(CTempString sp, const CTimeout &timeout=CTimeout(CTimeout::eDefault))
Execute stored procedure with given name.
int GetRowCount(void) const
Get number of rows read after statement execution.
unsigned int GetResultSetNo(void) const
Get number of currently active result set.
void PurgeResults(void)
Purge all remaining result sets; fill in all remaining parameter results.
CQuery & SingleSet(void)
Convert this query to work like only one result set was returned effectively merging all result sets ...
string GetColumnName(unsigned int col) const
Get name of the column with given number in the current result set.
CQuery & operator=(const CQuery &q)
@ fLogExceptions
Exceptions logged only.
@ fOwnWriter
Own the underlying writer.
CBlobBookmark GetBookmark(void) const override
const CDB_Exception::SContext & x_GetContext(void) const override
const CVariant * GetValue(void) const override
CNcbiOstream * GetOStream(size_t blob_size, TBlobOStreamFlags flags) const override
@ eMirror_Unavailable
All databases in the mirror are unavailable.
@ eMirror_Steady
Mirror is working on the same server as before.
@ eMirror_NewMaster
Switched to a new master.
static void UseDriver(EDriver driver)
Use the specified driver for all connections.
static EMirrorStatus UpdateMirror(const string &dbservice, list< string > *servers=NULL, string *error_message=NULL)
Check for master/mirror switch.
static CBlobStoreDynamic * NewBlobStore(const CSDB_ConnectionParam ¶m, const string &table_name, TNewBlobStoreFlags flags=TNewBlobStoreFlags(0), size_t image_limit=1<< 24)
Get new CBlobStoreDynamic object (to be owned by caller).
static bool Init(void)
Initialize SDBAPI.
static void SetApplicationName(const CTempString &name)
Report the specified application name to servers.
static string GetApplicationName(void)
Check SDBAPI's application name setting.
Convenience class to initialize database connection parameters from URL-like strings and/or applicati...
CSDB_ConnectionParam & Set(EParam param, const string &value, TSetFlags flags=0)
Set one of the "essential" database connection parameters, unless overridden in a configuration file.
static CRef< CSDB_Decryptor > GetGlobalDecryptor(void)
Get the current password decryptor, if any.
@ eService
Named service, interfaces-file alias, or raw server name, per http://ncbi.github.io/cxx-toolkit/pages...
@ eConnPoolAllowTempOverflow
@ ePort
DB server's port (when not using an alias or named service)
@ eContinueAfterRaiserror
void x_FillParamMap(void)
Populate m_ParamMap according to the current server or service name.
void x_FillLowerParams(CDBConnParamsBase *params) const
Fill parameters for low-level DBAPI from what is set here and in the configuration file.
static void SetGlobalDecryptor(CRef< CSDB_Decryptor > decryptor)
Use the specified password decryptor.
CUrl m_Url
URL storing all parameters set in code.
void x_FillBoolParam(CDBConnParamsBase *params, const string &name, EParam id) const
string ComposeUrl(TComposeUrlFlags flags=0) const
Compose database connection URL string out of this class.
static bool x_IsKnownArg(const string &name)
@ fThrowIfIncomplete
Throw an exception if missing any "essential" parameters.
string x_GetPassword() const
Determine what password to use, accounting for possible encryption or indirection.
void x_ReportOverride(const CTempString &name, CTempString code_value, CTempString reg_value) const
static const char * x_GetName(EParam param)
string Get(EParam param, EWithOverrides with_overrides=eWithoutOverrides) const
Get one of the "essential" database connection parameters.
void x_InitErrCode(CException::EErrCode err_code) override
Helper method for initializing error code.
void x_Init(const CDiagCompileInfo &info, const string &message, const CException *prev_exception, EDiagSev severity) override
Helper method for initializing exception data.
Database password decryptor.
virtual string x_GetKey(const CTempString &key_id)
virtual string x_Decrypt(const string &ciphertext, const string &key)
Exception class used throughout the API.
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
void x_Assign(const CException &src) override
Helper method for copying exception data.
void x_Init(const CDiagCompileInfo &info, const string &message, const CException *prev_exception, EDiagSev severity) override
Helper method for initializing exception data.
CConstRef< CDB_Exception::SContext > m_Context
virtual ERetriable GetRetriable(void) const override
Retrieve info about ability to retry an action caused the exception.
@ eOutOfBounds
Conversion of string to integer type exceeded limits of requested type.
@ eWrongParams
Wrong parameters provided to the method.
@ eLowLevel
Exception from low level DBAPI was re-thrown with this exception class.
@ eInconsistent
Operation logically incorrect is attempted to be made (increase past end() iterator,...
@ eStarted
CBulkInsert has already started to send data, no changes in meta-information can be made.
@ eNotExist
Field/parameter with given name/position does not exist.
@ eClosed
CDatabase/CQuery/CBulkInsert is tried to be used when no connection is opened.
@ eURLFormat
Incorrectly formated URL is used to create CSDB_ConnectionParam.
@ eUnsupported
Unsupported data type conversion is requested.
@ eNotInOrder
Columns cannot be bound to CBulkInsert randomly.
void ReportExtra(ostream &os) const override
Report "non-standard" attributes.
bool HandleIt(CDB_Exception *ex)
Handle the exceptions resulting from a native API call, one-by-one.
bool HandleMessage(int severity, int msgnum, const string &message)
Handle message resulting from a native API call.
static const TFlags kDefaults
@ fIsText
(N)TEXT or (N)VARCHAR(MAX)
@ fLogBlobs
Enable server-side logging.
@ fPreallocated
Don't create rows or clean up excess rows.
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
CTimeout – Timeout interval.
CUpdMirrorServerParams(const CDBConnParams &other)
virtual string GetServerName(void) const
virtual string GetPassword(void) const
virtual EEncoding GetEncoding(void) const
virtual string GetUserName(void) const
virtual Uint4 GetHost(void) const
const CDBConnParams & m_Other
~CUpdMirrorServerParams(void)
virtual string GetParam(const string &key) const
Parameters, which are not listed above explicitly, should be retrieved via SetParam() method.
virtual CRef< IConnValidator > GetConnValidator(void) const
virtual EServerType GetServerType(void) const
virtual Uint4 GetProtocolVersion(void) const
virtual string GetDatabaseName(void) const
virtual Uint2 GetPort(void) const
Writer-based output stream.
virtual CBlobBookmark GetBookmark(void) const
virtual CNcbiOstream * GetOStream(size_t blob_size, TBlobOStreamFlags flags) const
virtual string GetDatabaseName(void) const
virtual string GetParam(const string &key) const
Parameters, which are not listed above explicitly, should be retrieved via SetParam() method.
virtual string GetServerName(void) const
size_t CloseConnsForPool(const string &pool_name, Uint4 keep_host_ip=0, Uint2 keep_port=0)
void ReadDBConfParams(const string &service_name, SDBConfParams *params)
bool SatisfyPoolMinimum(const CDBConnParams ¶ms)
container_type::const_iterator const_iterator
container_type::iterator iterator
const_iterator end() const
iterator_bool insert(const value_type &val)
const_iterator find(const key_type &key) const
static CS_CONNECTION * conn