94 if ((strncmp(db,
"odbc", 4)!=0) || (strlen(db)<8)) {
95 SetError(-1,
"db argument should be started from odbc...",
"TODBCServer");
99 if (strncmp(db,
"odbc://", 7)==0) {
102 SetError(-1,
Form(
"not valid URL: %s", db),
"TODBCServer");
105 const char* driver =
"MyODBC";
106 const char* dbase = url.
GetFile();
108 if (*dbase==
'/') dbase++;
110 if (((uid==0) || (*uid==0)) && (strlen(url.
GetUser())>0)) {
117 connstr.
Form(
"DRIVER={%s};"
123 driver, url.
GetHost(), dbase, uid, pw);
132 if (strncmp(db,
"odbcd://", 8)==0) {
136 if (strncmp(db,
"odbcn://", 8)==0) {
138 simpleconnect =
kTRUE;
140 SetError(-1,
"db argument is invalid",
"TODBCServer");
144 retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &
fHenv);
148 retcode = SQLSetEnvAttr(
fHenv, SQL_ATTR_ODBC_VERSION, (
void*)SQL_OV_ODBC3, 0);
152 retcode = SQLAllocHandle(SQL_HANDLE_DBC,
fHenv, &
fHdbc);
156 retcode = SQLSetConnectAttr(
fHdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER) 5, 0);
167 retcode = SQLConnect(
fHdbc, (SQLCHAR*) connstr.
Data(), SQL_NTS,
168 (SQLCHAR*) uid, SQL_NTS,
169 (SQLCHAR*) pw, SQL_NTS);
171 retcode = SQLDriverConnect(
fHdbc, hwnd,
172 (SQLCHAR*) connstr.
Data(), SQL_NTS,
173 (SQLCHAR*) sbuf,
sizeof(sbuf), &reslen, SQL_DRIVER_NOPROMPT);
179 retcode = SQLGetInfo(
fHdbc, SQL_USER_NAME, sbuf,
sizeof(sbuf), &reslen);
183 retcode = SQLGetInfo(
fHdbc, SQL_DBMS_NAME, sbuf,
sizeof(sbuf), &reslen);
188 retcode = SQLGetInfo(
fHdbc, SQL_DBMS_VER, sbuf,
sizeof(sbuf), &reslen);
194 retcode = SQLGetConnectAttr(
fHdbc, SQL_ATTR_CURRENT_CATALOG, sbuf,
sizeof(sbuf), &reslen1);
198 retcode = SQLGetInfo(
fHdbc, SQL_SERVER_NAME, sbuf,
sizeof(sbuf), &reslen);
244 retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
245 if ((retcode!=SQL_SUCCESS) && (retcode!=SQL_SUCCESS_WITH_INFO))
return 0;
247 retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (
void*)SQL_OV_ODBC3, 0);
248 if ((retcode!=SQL_SUCCESS) && (retcode!=SQL_SUCCESS_WITH_INFO))
return 0;
252 char namebuf[2048], optbuf[2048];
253 SQLSMALLINT reslen1, reslen2;
256 strlcpy(namebuf,
"",2048);
257 strlcpy(optbuf,
"",2048);
259 retcode = SQLDrivers(henv, (lst==0 ? SQL_FETCH_FIRST : SQL_FETCH_NEXT),
260 (SQLCHAR*) namebuf,
sizeof(namebuf), &reslen1,
261 (SQLCHAR*) optbuf,
sizeof(optbuf), &reslen2);
263 retcode = SQLDataSources(henv, (lst==0 ? SQL_FETCH_FIRST : SQL_FETCH_NEXT),
264 (SQLCHAR*) namebuf,
sizeof(namebuf), &reslen1,
265 (SQLCHAR*) optbuf,
sizeof(optbuf), &reslen2);
267 if (retcode==SQL_NO_DATA)
break;
268 if ((retcode==SQL_SUCCESS) || (retcode==SQL_SUCCESS_WITH_INFO)) {
273 for (
int n=0;
n<reslen2-1;
n++)
274 if (optbuf[
n]==
'\0') optbuf[
n] =
';';
278 }
while ((retcode==SQL_SUCCESS) || (retcode==SQL_SUCCESS_WITH_INFO));
280 SQLFreeHandle(SQL_HANDLE_ENV, henv);
305 std::cout <<
"List of ODBC drivers:" << std::endl;
308 while ((
n = (
TNamed*) iter()) != 0)
309 std::cout <<
" " <<
n->
GetName() <<
" : " <<
n->GetTitle() << std::endl;
331 std::cout <<
"List of ODBC data sources:" << std::endl;
334 while ((
n = (
TNamed*) iter()) != 0)
335 std::cout <<
" " <<
n->
GetName() <<
" : " <<
n->GetTitle() << std::endl;
344 if ((retcode==SQL_SUCCESS) || (retcode==SQL_SUCCESS_WITH_INFO))
return kFALSE;
352 while (SQLGetDiagRec(SQL_HANDLE_ENV,
fHenv, ++i, state, &native,
text,
353 sizeof(
text), &len ) == SQL_SUCCESS)
359 while (SQLGetDiagRec(SQL_HANDLE_DBC,
fHdbc, ++i, state, &native,
text,
360 sizeof(
text), &len ) == SQL_SUCCESS)
368#define CheckConnect(method, res) \
371 if (!IsConnected()) { \
372 SetError(-1,"ODBC driver is not connected",method); \
382 SQLDisconnect(
fHdbc);
383 SQLFreeHandle(SQL_HANDLE_DBC,
fHdbc);
384 SQLFreeHandle(SQL_HANDLE_ENV,
fHenv);
400 SQLAllocHandle(SQL_HANDLE_STMT,
fHdbc, &hstmt);
402 retcode = SQLExecDirect(hstmt, (SQLCHAR*) sql, SQL_NTS);
404 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
422 SQLAllocHandle(SQL_HANDLE_STMT,
fHdbc, &hstmt);
424 retcode = SQLExecDirect(hstmt, (SQLCHAR*) sql, SQL_NTS);
428 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
442 SQLRETURN retcode = SQLSetConnectAttr(
fHdbc, SQL_ATTR_CURRENT_CATALOG, (SQLCHAR*) db, SQL_NTS);
476 SQLAllocHandle(SQL_HANDLE_STMT,
fHdbc, &hstmt);
478 SQLCHAR* schemaName = 0;
479 SQLSMALLINT schemaNameLength = 0;
493 SQLCHAR* tableName = 0;
494 SQLSMALLINT tableNameLength = 0;
496 if ((wild!=0) && (strlen(wild)!=0)) {
497 tableName = (SQLCHAR*) wild;
498 tableNameLength = strlen(wild);
499 SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID, (SQLPOINTER) SQL_FALSE, 0);
502 retcode = SQLTables(hstmt, NULL, 0, schemaName, schemaNameLength, tableName, tableNameLength, (SQLCHAR*)
"TABLE", 5);
504 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
520 if (res==0)
return 0;
526 while ((row = res->
Next())!=0) {
527 const char* tablename = row->
GetField(2);
553 #define STR_LEN 128+1
554 #define REM_LEN 254+1
562 SQLLEN columnSize, bufferLength, charOctetLength, ordinalPosition;
563 SQLSMALLINT dataType, decimalDigits, numPrecRadix, nullable;
564 SQLSMALLINT sqlDataType, datetimeSubtypeCode;
570 SQLLEN cbCatalog, cbSchema, cbTableName, cbColumnName;
571 SQLLEN cbDataType, cbTypeName, cbColumnSize, cbBufferLength;
572 SQLLEN cbDecimalDigits, cbNumPrecRadix, cbNullable, cbRemarks;
573 SQLLEN cbColumnDefault, cbSQLDataType, cbDatetimeSubtypeCode, cbCharOctetLength;
574 SQLLEN cbOrdinalPosition, cbIsNullable;
577 SQLAllocHandle(SQL_HANDLE_STMT,
fHdbc, &hstmt);
579 retcode = SQLColumns(hstmt, NULL, 0, NULL, 0, (SQLCHAR*) tablename, SQL_NTS, NULL, 0);
581 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
589 SQLBindCol(hstmt, 1, SQL_C_CHAR, szCatalog,
STR_LEN,&cbCatalog);
590 SQLBindCol(hstmt, 2, SQL_C_CHAR, szSchema,
STR_LEN, &cbSchema);
591 SQLBindCol(hstmt, 3, SQL_C_CHAR, szTableName,
STR_LEN,&cbTableName);
592 SQLBindCol(hstmt, 4, SQL_C_CHAR, szColumnName,
STR_LEN, &cbColumnName);
593 SQLBindCol(hstmt, 5, SQL_C_SSHORT, &dataType, 0, &cbDataType);
594 SQLBindCol(hstmt, 6, SQL_C_CHAR, szTypeName,
STR_LEN, &cbTypeName);
595 SQLBindCol(hstmt, 7, SQL_C_SLONG, &columnSize, 0, &cbColumnSize);
596 SQLBindCol(hstmt, 8, SQL_C_SLONG, &bufferLength, 0, &cbBufferLength);
597 SQLBindCol(hstmt, 9, SQL_C_SSHORT, &decimalDigits, 0, &cbDecimalDigits);
598 SQLBindCol(hstmt, 10, SQL_C_SSHORT, &numPrecRadix, 0, &cbNumPrecRadix);
599 SQLBindCol(hstmt, 11, SQL_C_SSHORT, &nullable, 0, &cbNullable);
600 SQLBindCol(hstmt, 12, SQL_C_CHAR, szRemarks,
REM_LEN, &cbRemarks);
601 SQLBindCol(hstmt, 13, SQL_C_CHAR, szColumnDefault,
STR_LEN, &cbColumnDefault);
602 SQLBindCol(hstmt, 14, SQL_C_SSHORT, &sqlDataType, 0, &cbSQLDataType);
603 SQLBindCol(hstmt, 15, SQL_C_SSHORT, &datetimeSubtypeCode, 0, &cbDatetimeSubtypeCode);
604 SQLBindCol(hstmt, 16, SQL_C_SLONG, &charOctetLength, 0, &cbCharOctetLength);
605 SQLBindCol(hstmt, 17, SQL_C_SLONG, &ordinalPosition, 0, &cbOrdinalPosition);
606 SQLBindCol(hstmt, 18, SQL_C_CHAR, szIsNullable,
STR_LEN, &cbIsNullable);
608 retcode = SQLFetch(hstmt);
610 while ((retcode==SQL_SUCCESS) || (retcode==SQL_SUCCESS_WITH_INFO)) {
614 Int_t data_size = -1;
615 Int_t data_length = -1;
616 Int_t data_scale = -1;
617 Int_t data_sign = -1;
622 data_size = columnSize;
623 data_length = charOctetLength;
626 case SQL_LONGVARCHAR:
628 data_size = columnSize;
629 data_length = charOctetLength;
634 data_size = columnSize;
635 data_length = columnSize;
636 data_scale = decimalDigits;
642 data_size = columnSize;
647 data_size = columnSize;
652 data_size = columnSize;
657 case SQL_LONGVARBINARY:
659 data_size = columnSize;
661 case SQL_TYPE_TIMESTAMP:
663 data_size = columnSize;
667 if (lst==0) lst =
new TList;
670 (
const char*) szTypeName,
678 retcode = SQLFetch(hstmt);
681 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
699 SQLAllocHandle(SQL_HANDLE_STMT,
fHdbc, &hstmt);
701 retcode = SQLColumns(hstmt, NULL, 0, NULL, 0, (SQLCHAR*) table, SQL_NTS, NULL, 0);
703 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
717 SQLUINTEGER info = 0;
720 retcode = SQLGetInfo(
fHdbc, SQL_MAX_IDENTIFIER_LEN, (SQLPOINTER)&info,
sizeof(info), NULL);
722 if (
ExtractErrors(retcode,
"GetMaxIdentifierLength"))
return 20;
789 SetError(-1,
"no query string specified",
"Statement");
803 retcode = SQLAllocHandle(SQL_HANDLE_STMT,
fHdbc, &hstmt);
806 retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS);
808 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
824 SQLUINTEGER info = 0;
827 retcode = SQLGetInfo(
fHdbc, SQL_TXN_CAPABLE, (SQLPOINTER)&info,
sizeof(info), NULL);
831 SetError(-1,
"Transactions not supported",
"StartTransaction");
837 retcode = SQLSetConnectAttr(
fHdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_OFF, 0);
849 const char* method = commit ?
"Commit" :
"Rollback";
853 SQLRETURN retcode = SQLEndTran(SQL_HANDLE_DBC,
fHdbc, commit ? SQL_COMMIT : SQL_ROLLBACK);
856 retcode = SQLSetConnectAttr(
fHdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, 0);
#define CheckConnect(method, res)
char * Form(const char *fmt,...)
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Add(TObject *obj)
The TNamed class is the base class for all named ROOT classes.
virtual const char * GetName() const
Returns name of object.
Bool_t ExtractErrors(SQLRETURN retcode, const char *method)
Extract errors, produced by last ODBC function call.
static void PrintDrivers()
Print list of ODBC drivers in form: <name> : <options list>
TSQLResult * GetTables(const char *dbname, const char *wild=nullptr) final
List all tables in the specified database.
TSQLResult * GetDataBases(const char *wild=nullptr) final
List all available databases.
Int_t Shutdown() final
Shutdown the database server.
static TList * ListData(Bool_t isdrivers)
Produce TList object with list of available ODBC drivers (isdrivers = kTRUE) or data sources (isdrive...
TODBCServer(const char *db, const char *uid, const char *pw)
Open a connection to a ODBC server.
TSQLStatement * Statement(const char *sql, Int_t=100) final
Creates ODBC statement for provided query.
Bool_t EndTransaction(Bool_t commit)
Complete current transaction (commit = kTRUE) or rollback Switches on autocommit mode of ODBC driver.
Int_t Reload() final
Reload permission tables.
Bool_t StartTransaction() final
Starts transaction.
Int_t SelectDataBase(const char *dbname) final
Select a database.
virtual ~TODBCServer()
Close connection to MySQL DB server.
void Close(Option_t *opt="") final
Close connection to MySQL DB server.
Int_t GetMaxIdentifierLength() final
returns maximum allowed length of identifier (table name, column name, index name)
TSQLTableInfo * GetTableInfo(const char *tablename) final
Produces SQL table info Object must be deleted by user.
static TList * GetDrivers()
Produce TList object with list of available ODBC drivers User must delete TList object aftewards Name...
Bool_t Rollback() final
Rollback transaction.
Int_t DropDataBase(const char *dbname) final
Drop (i.e.
static void PrintDataSources()
Print list of ODBC data sources in form: <name> : <options list>
const char * ServerInfo() final
Return server info.
TSQLResult * Query(const char *sql) final
Execute SQL command.
Int_t CreateDataBase(const char *dbname) final
Create a database. Returns 0 if successful, non-zero otherwise.
static TList * GetDataSources()
Produce TList object with list of available ODBC data sources User must delete TList object aftewards...
TSQLResult * GetColumns(const char *dbname, const char *table, const char *wild=nullptr) final
List all columns in specified table in the specified database.
TList * GetTablesList(const char *wild=nullptr) final
Return list of tables in database See TSQLServer::GetTablesList() for details.
Bool_t Commit() final
Commit transaction.
Bool_t Exec(const char *sql) final
Executes query which does not produce any results set Return kTRUE if successfull.
Collectable string class.
virtual TSQLRow * Next()=0
virtual const char * GetField(Int_t field)=0
void SetError(Int_t code, const char *msg, const char *method=nullptr)
set new values for error fields if method is specified, displays error message
virtual Bool_t IsConnected() const
const char * Data() const
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
This class represents a WWW compatible URL.
const char * GetFile() const
const char * GetUser() const
const char * GetHost() const
const char * GetPasswd() const
const char * GetOptions() const