42 #include <msodbcsql.h>
48 #define DEFAULT_ODBC_DRIVER_NAME "ODBC Driver 18 for SQL Server"
50 #define NCBI_USE_ERRCODE_X Dbapi_Odbc_Conn
52 #undef NCBI_DATABASE_THROW
53 #define NCBI_DATABASE_THROW(ex_class, message, err_code, severity) \
54 NCBI_ODBC_THROW(ex_class, message, err_code, severity)
62 #define GetDbgInfo() 0
93 m_query_timeout(cntx.GetTimeout()),
94 m_cancel_timeout(cntx.GetCancelTimeout())
127 x_Connect(cntx, params, opening_reporter);
160 string conn_str_suffix =
";SERVER=" + server_name;
164 ";ADDRESS=" + server_name +
172 ";TrustServerCertificate=yes"
184 connect_str =
"DRIVER={" + driver_name +
"}";
189 connect_str += conn_str_suffix;
195 const_cast<TSqlChar*
>(connect_str_ss.data()),
196 connect_str_ss.size(),
207 const_cast<TSqlChar*
>(server_name_ss.data()),
208 server_name_ss.size(),
209 const_cast<TSqlChar*
>(username_ss.data()),
211 const_cast<TSqlChar*
>(password_ss.data()),
218 err +=
"Cannot connect to the server '" + server_name;
230 SQLULEN timeout, login_timeout;
245 #ifdef SQL_COPT_SS_BCP
258 enum EState {eStInitial, eStSingleQuote};
259 vector<string> driver_names;
260 const string odbc_driver_name =
269 ITERATE(vector<string>, it, driver_names) {
270 bool complete_deriver_name =
false;
271 const string cur_str(*it);
274 if (
state == eStInitial) {
275 if (cur_str[0] ==
'\'') {
276 if (cur_str[cur_str.size() - 1] ==
'\'') {
278 driver_name = it->substr(1, cur_str.size() - 2);
279 complete_deriver_name =
true;
282 driver_name = it->substr(1);
283 state = eStSingleQuote;
286 driver_name = cur_str;
287 complete_deriver_name =
true;
289 }
else if (
state == eStSingleQuote) {
290 if (cur_str[cur_str.size() - 1] ==
'\'') {
292 driver_name +=
" " + cur_str.substr(0, cur_str.size() - 1);
294 complete_deriver_name =
true;
296 driver_name +=
" " + cur_str;
300 if (complete_deriver_name) {
311 string str_version =
"TDS_Version=";
316 str_version +=
"4.2;Port=2158";
319 str_version +=
"4.6";
322 str_version +=
"5.0;Port=2158";
325 str_version +=
"7.0";
376 string err_message =
"No bcp on this connection." +
GetDbgInfo();
387 unsigned int batch_size)
446 string err_message =
"Cannot prepare a command." +
GetDbgInfo();
511 string err_message =
"SQLDisconnect failed (memory corruption suspected)." +
GetDbgInfo();
537 #ifdef SQL_DRIVER_NAME
554 #ifdef SQL_DRIVER_VER
591 string q =
"update ";
599 #if defined(SQL_TEXTPTR_LOGGING)
629 if (
stmt.IsMultibyteClientEncoding()) {
712 size_t invalid_len = 0;
714 while((
len = stream.
Read(buff + invalid_len,
sizeof(buff) - invalid_len - 1)) != 0 ) {
752 invalid_len =
len - valid_len;
764 if (valid_len <
len) {
765 memmove(buff, buff + valid_len, invalid_len);
802 if (invalid_len > 0) {
812 string err_message =
"Not all the data were sent." +
GetDbgInfo();
818 string err_message =
"SQLParamData failed." +
GetDbgInfo();
831 string err_message =
"SQLMoreResults failed." +
GetDbgInfo();
836 string err_message =
"SQLMoreResults failed (memory corruption suspected)." +
GetDbgInfo();
859 const string& cursor_name,
860 const string&
query) :
930 string err_message =
"Invalid handle." +
GetDbgInfo();
959 err_message.append(
msg);
960 err_message.append(
" (memory corruption suspected).");
989 err_message.append(
msg);
990 err_message.append(
" (memory corruption suspected).");
1013 type_str =
"smallint";
1016 type_str =
"tinyint";
1019 type_str =
"numeric";
1025 type_str =
"nvarchar(4000)";
1027 type_str =
"varchar(8000)";
1039 type_str =
"nvarchar(4000)";
1041 type_str =
"varchar(8000)";
1047 type_str =
"varbinary(8000)";
1052 type_str =
"varbinary(8000)";
1061 type_str =
"smalldatetime";
1064 type_str =
"datetime";
1082 type_str =
"nvarchar(max)";
1084 type_str =
"varchar(max)";
1088 type_str =
"varbinary(max)";
1101 unsigned int pos)
const
1107 switch (data_type) {
1119 switch (data_type) {
1122 default: scale = 0;
break;
1136 indicator_base + pos);
1138 CheckSIE(rc,
"SQLBindParameter failed", 420066);
1434 return dynamic_cast<const CDB_String&
>(param).Size()
1437 return dynamic_cast<const CDB_Binary&
>(param).Size();
1468 data =
dynamic_cast<const CDB_Int&
>(param).BindVal();
1483 data =
const_cast<wchar_t *
>(
dynamic_cast<const CDB_String&
>(param)
1511 ts->
year =
t.Year();
1514 ts->
hour =
t.Hour();
1529 ts->
year =
t.Year();
1532 ts->
hour =
t.Hour();
1549 ts->
year =
t.Year();
1552 ts->
hour =
t.Hour();
1556 ts->
fraction =
t.NanoSecond() / 100 * 100;
1566 size_t n = par.
Size();
1574 wstring wdata = CUtf8::AsBasicString<TSqlChar>(utf_data);
1578 memcpy(
data, wdata.data(),
n);
1587 size_t n = par.
Size();
1647 bool dump_results) :
1649 impl::CSendDataCmd(
conn, nof_bytes),
1653 m_HasMoreResults(
false),
1654 m_DumpResults(dump_results)
1661 string err_message =
"Cannot prepare a command." +
GetDbgInfo();
1669 if(nof_bytes < 1)
return 0;
1705 size_t valid_len = 0;
1708 CTempString(
static_cast<const char*
>(chunk_ptr),nof_bytes));
1710 if (valid_len < nof_bytes) {
1716 (
CTempString(
static_cast<const char*
>(chunk_ptr), valid_len),
1719 nof_bytes = valid_len;
1756 string err_message =
"Not all the data were sent." +
GetDbgInfo();
1762 string err_message =
"SQLParamData failed." +
GetDbgInfo();
1775 string err_message =
"SQLMoreResults failed." +
GetDbgInfo();
1780 string err_message =
"SQLMoreResults failed (memory corruption suspected)." +
GetDbgInfo();
1830 string err_message =
"A command has to be sent first." +
GetDbgInfo();
1842 "SQLNumResultCols failed", 420011);
1848 "SQLRowCount failed", 420013);
1882 string err_message =
"SQLMoreResults failed." +
GetDbgInfo();
1887 string err_message =
"SQLMoreResults failed (memory corruption suspected)." +
GetDbgInfo();
Convenience extension of basic_string, supporting implicit conversion to const TChar* in most situati...
void * Alloc(size_t nof_bytes)
static CNcbiApplication * Instance(void)
Singleton method.
SQLHENV GetODBCContext(void) const
bool GetUseDSN(void) const
const CODBC_Reporter & GetReporter(void) const
SQLUINTEGER GetPacketSize(void) const
bool CheckSIE(int rc, SQLHDBC con, const CODBC_Reporter &opening_reporter)
virtual CDB_CursorCmd * Cursor(const string &cursor_name, const string &query, unsigned int batch_size=1)
Cursor.
friend class CODBC_RPCCmd
virtual I_DriverContext::TConnectionMode ConnectMode(void) const
Get the bitmask for the connection mode (BCP, secure login, ...)
CODBC_LangCmd * xLangCmd(const string &lang_query)
size_t GetCancelTimeout() const
friend class CODBC_LangCmd
virtual bool IsAlive(void)
Check out if connection is alive (this function doesn't ping the server, it just checks the status of...
void x_Connect(CODBCContext &cntx, const CDBConnParams ¶ms, const CODBC_Reporter &opening_reporter) const
virtual string GetVersionString(void) const
friend class CODBC_CursorCmdExpl
virtual string GetDriverName(void) const
static string x_GetDriverName(const IRegistry ®istry)
virtual CDB_SendDataCmd * SendDataCmd(I_BlobDescriptor &desc, size_t data_size, bool log_it=true, bool dump_results=true)
"Send-data" command
friend class CODBC_BCPInCmd
bool x_SendData(CDB_BlobDescriptor::ETDescriptorType descr_type, CStatementBase &stmt, CDB_Stream &stream)
virtual CDB_RPCCmd * RPC(const string &rpc_name)
Remote procedure call.
virtual void SetTimeout(size_t nof_secs)
friend class CODBC_SendDataCmd
const TDbgInfo & GetDbgInfo(void) const
virtual bool Abort(void)
abort the connection Attention: it is not recommended to use this method unless you absolutely have t...
virtual bool Refresh(void)
Reset the connection to the "ready" state (cancel all active commands)
CODBC_Reporter m_Reporter
static string x_MakeFreeTDSVersion(int version)
virtual void SetCancelTimeout(size_t nof_secs)
void x_SetConnAttributesBefore(const CODBCContext &cntx, const CDBConnParams ¶ms)
CStatementBase * m_ActiveStmt
void x_SetupErrorReporter(const CDBConnParams ¶ms)
size_t GetTimeout() const
virtual ~CODBC_Connection(void)
CODBC_Connection(CODBCContext &cntx, const CDBConnParams ¶ms)
virtual CDB_LangCmd * LangCmd(const string &lang_query)
These methods: LangCmd(), RPC(), BCPIn(), Cursor() and SendDataCmd() create and return a "command" ob...
friend class CODBC_CursorCmd
virtual bool SendData(I_BlobDescriptor &desc, CDB_Stream &lob, bool log_it=true)
Shortcut to send text and image to the server without using the "Send-data" command (SendDataCmd)
virtual bool Close(void)
Close an open connection.
virtual CDB_BCPInCmd * BCPIn(const string &table_name)
"Bulk copy in" command
void SetHandlerStack(impl::CDBHandlerStack &hs)
void SetServerName(const string &server_name)
void ReportErrors(void) const
void SetHandle(SQLHANDLE h)
void SetUserName(const string &username)
virtual bool HasMoreResults(void) const
bool xCheck4MoreResults(void)
virtual ~CODBC_SendDataCmd(void)
virtual CDB_Result * Result(void)
Get result set.
CODBC_SendDataCmd(CODBC_Connection &conn, CDB_BlobDescriptor &descr, size_t nof_bytes, bool logit, bool dump_results)
const CDB_BlobDescriptor::ETDescriptorType m_DescrType
virtual bool Cancel(void)
virtual size_t SendChunk(const void *chunk_ptr, size_t nof_bytes)
Send chunk of data to the server.
const CODBC_Connection::TDbgInfo & GetDbgInfo(void) const
bool CheckRC(int rc) const
bool x_BindParam_ODBC(const CDB_Object ¶m, CMemPot &bind_guard, SQLLEN *indicator_base, unsigned int pos) const
virtual int RowCount(void) const
Get the number of rows affected by the command Special case: negative on error or if there is no way ...
CODBC_Reporter m_Reporter
bool IsMultibyteClientEncoding(void) const
SQLULEN x_GetMaxDataSize(const CDB_Object ¶m) const
string Type2String(const CDB_Object ¶m) const
SQLHSTMT GetHandle(void) const
SQLSMALLINT x_GetCType(const CDB_Object ¶m) const
SQLLEN x_GetIndicator(const CDB_Object ¶m) const
SQLLEN x_GetCurDataSize(const CDB_Object ¶m) const
CStatementBase(CODBC_Connection &conn, const string &query)
int CheckSIE(int rc, const char *msg, unsigned int msg_num) const
bool ResetParams(void) const
EEncoding GetClientEncoding(void) const
SQLSMALLINT x_GetSQLType(const CDB_Object ¶m) const
CODBC_Connection & GetConnection(void)
int CheckSIENd(int rc, const char *msg, unsigned int msg_num) const
SQLPOINTER x_GetData(const CDB_Object ¶m, CMemPot &bind_guard) const
void ReportErrors(void) const
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
void SetWasSent(bool flag=true)
static CDB_Result * Create_Result(CResult &result)
bool IsBCPable(void) const
const CDBHandlerStack & GetMsgHandlers(void) const
CDB_CursorCmd * Create_CursorCmd(CBaseCmd &cursor_cmd)
CDB_RPCCmd * Create_RPCCmd(CBaseCmd &rpc_cmd)
void DropCmd(impl::CCommand &cmd)
void SetServerType(CDBConnParams::EServerType type)
bool HasSecureLogin(void) const
CDB_SendDataCmd * Create_SendDataCmd(CSendDataCmd &senddata_cmd)
CDriverContext & GetCDriverContext(void)
CDB_BCPInCmd * Create_BCPInCmd(CBaseCmd &bcpin_cmd)
void DeleteAllCommands(void)
CDB_LangCmd * Create_LangCmd(CBaseCmd &lang_cmd)
These methods to allow the children of CConnection to create various command-objects.
EEncoding GetClientEncoding(void) const
virtual CRWLock & x_GetCtxLock(void) const
void DetachSendDataIntf(void)
void SetBytes2Go(size_t value)
size_t GetBytes2Go(void) const
static CS_CONNECTION * conn
#define SQLSetConnectAttr(h, n, p, t)
static const char table_name[]
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
element_type * get(void) const
Get pointer.
void reset(element_type *p=0)
Reset will delete the old pointer, set content to the new value, and assume the ownership upon the ne...
#define DATABASE_DRIVER_ERROR(message, err_code)
virtual const impl::CDBHandlerStack & GetOpeningMsgHandlers(void) const =0
virtual string GetPassword(void) const =0
virtual string GetDriverName(void) const
virtual Uint4 GetHost(void) const =0
virtual string GetServerName(void) const =0
virtual Uint2 GetPort(void) const =0
virtual string GetUserName(void) const =0
virtual string GetParam(const string &key) const =0
Parameters, which are not listed above explicitly, should be retrieved via SetParam() method.
const string & SearchConditions() const
ETDescriptorType GetColumnType(void) const
const string & ColumnName() const
const string & TableName() const
static EBlobType GetBlobType(EDB_Type db_type)
size_type byte_count(void) const
virtual EDB_Type GetType() const =0
virtual bool MoveTo(size_t byte_number)
virtual size_t Read(void *buff, size_t nof_bytes)
virtual size_t Size() const
#define NCBI_CURRENT_FUNCTION
Get current function name.
#define NCBI_CATCH_ALL_X(err_subcode, message)
virtual string GetString(const string §ion, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
static TNumeric StringToNumeric(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to a numeric value.
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
static CStringUTF8 AsUTF8(const CTempString &src, EEncoding encoding, EValidate validate=eNoValidate)
Convert into UTF8 from a C/C++ string.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition of all error codes used in dbapi libraries (dbapi_driver.lib and others).
const string version
version string
string ConvertN2A(Uint4 host)
SIZE_TYPE GetValidUTF8Len(const CTempString &ts)
const struct ncbi::grid::netcache::search::fields::SIZE size
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define DEFAULT_ODBC_DRIVER_NAME
static bool ODBC_xSendDataGetId(CStatementBase &stmt, SQLPOINTER *id)
static bool ODBC_xCheckSIE(int rc, CStatementBase &stmt)
static bool ODBC_xSendDataPrepare(CStatementBase &stmt, CDB_BlobDescriptor &descr_in, SQLLEN size, bool is_text, bool logit, SQLPOINTER id, SQLLEN *ph)
TSqlString x_MakeTSqlString(const CTempString &s, EEncoding enc)
CGenericSqlString< TSqlChar > TSqlString
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
SQLRETURN SQLRowCount(SQLHSTMT StatementHandle, SQLINTEGER *RowCount)
SQLRETURN SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLINTEGER StrLen_or_Ind)
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
SQLRETURN SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSMALLINT NameLength1, SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3)
SQLRETURN SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
SQLRETURN SQLExecute(SQLHSTMT StatementHandle)
SQLRETURN SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option)
#define SQL_TYPE_TIMESTAMP
SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength)
#define SQL_INVALID_HANDLE
#define SQL_SUCCESS_WITH_INFO
SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle)
SQLRETURN SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount)
SQLRETURN SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
#define SQL_SUCCEEDED(rc)
SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength)
SQLRETURN SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value)
#define SQL_ATTR_CONNECTION_TIMEOUT
#define SQL_C_TYPE_TIMESTAMP
SQLRETURN SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLUINTEGER cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue)
#define SQL_LONGVARBINARY
#define SQL_LEN_DATA_AT_EXEC(length)
#define SQL_ATTR_LOGIN_TIMEOUT
#define SQL_ATTR_CONNECTION_DEAD
#define SQL_ATTR_QUERY_TIMEOUT
#define SQL_ATTR_PACKET_SIZE
SQLRETURN SQLMoreResults(SQLHSTMT hstmt)
#define SQL_DRIVER_NOPROMPT
SQLRETURN SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut, SQLUSMALLINT fDriverCompletion)
unsigned long SQLUINTEGER
signed short int SQLSMALLINT
TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT