40 #ifdef HAVE_SQL_STORAGE
51 #include <opencog/util/platform.h>
58 #define PRINT_SQLERR(HTYPE,HAN) \
65 SQLGetDiagRec(HTYPE, HAN, 1, (SQLCHAR *) sql_stat, \
66 &err, (SQLCHAR*) msg, sizeof(msg), &msglen); \
67 PERR("(%ld) %s\n", (long int) err, msg); \
73 const char * _username,
74 const char * _authentication)
85 PERR(
"No DB specified");
91 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
93 PERR(
"Can't SQLAllocEnv, rc=%d", rc);
98 rc = SQLSetEnvAttr(
sql_henv, SQL_ATTR_ODBC_VERSION,
99 (
void*)SQL_OV_ODBC3, 0);
100 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
102 PERR(
"Can't SQLSetEnv, rc=%d", rc);
103 PRINT_SQLERR (SQL_HANDLE_ENV,
sql_henv);
104 SQLFreeHandle(SQL_HANDLE_ENV,
sql_henv);
111 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
113 PERR (
"Can't SQLAllocConnect handle rc=%d", rc);
114 PRINT_SQLERR (SQL_HANDLE_ENV,
sql_henv);
115 SQLFreeHandle(SQL_HANDLE_ENV,
sql_henv);
123 if (NULL == _authentication) _authentication =
"";
125 (SQLCHAR*) _dbname, SQL_NTS,
126 (SQLCHAR*) _username, SQL_NTS,
127 (SQLCHAR*) _authentication, SQL_NTS);
129 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
131 PERR (
"Can't perform SQLConnect rc=%d", rc);
132 PRINT_SQLERR (SQL_HANDLE_DBC,
sql_hdbc);
133 SQLFreeHandle(SQL_HANDLE_DBC,
sql_hdbc);
134 SQLFreeHandle(SQL_HANDLE_ENV,
sql_henv);
152 SQLFreeHandle(SQL_HANDLE_DBC,
sql_hdbc);
158 SQLFreeHandle(SQL_HANDLE_ENV,
sql_henv);
176 #define DEFAULT_NUM_COLS 50
209 ret = SQLGetDiagRec(SQL_HANDLE_ENV,
sql_henv, ++i, state, &native, text,
211 if (SQL_SUCCEEDED(ret))
212 PERR(
"\t%s : %d : %d : %s\n", state, i, native, text);
213 }
while (ret == SQL_SUCCESS);
227 if (!rs)
return NULL;
229 rc = SQLExecDirect(rs->
sql_hstmt, (SQLCHAR *)buff, SQL_NTS);
234 if (SQL_NO_DATA == rc)
240 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
242 PERR (
"Can't perform query rc=%d ", rc);
243 PRINT_SQLERR (SQL_HANDLE_STMT, rs->
sql_hstmt);
245 PERR (
"\tQuery was: %s\n", buff);
258 #define DEFAULT_COLUMN_NAME_SIZE 121
259 #define DEFAULT_VARCHAR_SIZE 4040
301 values =
new char*[new_ncols];
302 vsizes =
new int[new_ncols];
305 for (i = 0; i<new_ncols; i++)
317 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
319 PERR(
"Can't allocate statement handle, rc=%d", rc);
320 PRINT_SQLERR (SQL_HANDLE_STMT,
sql_hstmt);
326 for (i=0; i<new_ncols; i++)
337 values[i] =
new char[DEFAULT_VARCHAR_SIZE];
338 vsizes[i] = DEFAULT_VARCHAR_SIZE;
341 rc = SQLBindCol(
sql_hstmt, i+1, SQL_C_CHAR,
343 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
345 PERR (
"Can't bind col=%d rc=%d", i, rc);
346 PRINT_SQLERR (SQL_HANDLE_STMT,
sql_hstmt);
359 if (NULL == _conn)
return;
386 SQLFreeHandle(SQL_HANDLE_STMT,
sql_hstmt);
427 if (0 <=
ncols)
return;
434 rc = SQLNumResultCols(
sql_hstmt, &_ncols);
435 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
437 PERR (
"Can't get num columns rc=%d", rc);
438 PRINT_SQLERR (SQL_HANDLE_STMT,
sql_hstmt);
442 if (_ncols > arrsize)
444 PERR(
"screwed not enough columns !! ");
448 for (i=0; i<_ncols; i++)
453 SQLSMALLINT datatype;
454 SQLSMALLINT decimal_digits;
455 SQLSMALLINT nullable;
458 (SQLCHAR *) namebuff, 299, &namelen,
459 &datatype, &column_size, &decimal_digits, &nullable);
460 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
462 PERR (
"Can't describe col rc=%d", rc);
463 PRINT_SQLERR (SQL_HANDLE_STMT,
sql_hstmt);
467 namebuff[namelen] = 0x0;
470 strncpy(
column_labels[i], namebuff, DEFAULT_COLUMN_NAME_SIZE);
496 if (SQL_NO_DATA == rc)
return 0;
497 if (SQL_NULL_DATA == rc)
return 0;
499 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
501 PERR (
"Can't fetch row rc=%d", rc);
502 PRINT_SQLERR (SQL_HANDLE_STMT,
sql_hstmt);
518 for (i=0; i<
ncols; i++)
524 fp = strrchr (fieldname,
'.');
528 for (i=0; i<
ncols; i++)
539 if (!
this)
return NULL;
552 if (0 > column)
return NULL;
560 #ifdef UNIT_TEST_EXAMPLE
566 bool column_cb(
const char *colname,
const char * colvalue)
568 printf (
"%s = %s\n", colname, colvalue);
573 printf (
"---- New row found ----\n");
587 #ifdef MAKE_SOME_DATA
589 "INSERT INTO Atoms VALUES (3,1,0.5, 0.5, 'umm');");
593 rs = conn->
exec(
"SELECT * FROM Atoms;");
597 printf (
"found column with value %s\n", n);
602 Ola *ola =
new Ola();
603 rs = conn->
exec(
"SELECT * FROM Atoms;");
606 printf(
"--- method 2 has row:\n");
613 rs = conn->
exec(
"SELECT * FROM Atoms;");
626 #if OLD_UNPORTED_C_CODE
631 dui_odbc_connection_tables (DuiDBConnection *dbc)
633 DuiODBCConnection *conn = (DuiODBCConnection *) dbc;
634 DuiODBCRecordSet *rs;
637 ENTER (
"(conn=%p)", conn);
638 if (!conn)
return NULL;
640 rs = dui_odbc_recordset_new (conn);
641 if (!rs)
return NULL;
643 rc = SQLTables (rs->sql_hstmt,NULL, 0, NULL, 0, NULL,0, NULL, 0);
645 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
647 PERR (
"Can't perform query rc=%d", rc);
648 PRINT_SQLERR (SQL_HANDLE_STMT, rs->sql_hstmt);
649 dui_odbc_recordset_release (&rs->recset);
653 LEAVE (
"(conn=%p)", conn);
663 dui_odbc_connection_table_columns (DuiDBConnection *dbc,
664 const char * tablename)
666 DuiODBCConnection *conn = (DuiODBCConnection *) dbc;
667 DuiODBCRecordSet *rs;
670 ENTER (
"(conn=%p, table=%s)", conn, tablename);
671 if (!conn || !tablename)
return NULL;
673 rs = dui_odbc_recordset_new (conn);
674 if (!rs)
return NULL;
676 rc = SQLColumns (rs->sql_hstmt,NULL, 0, NULL, 0,
677 (
char *) tablename, SQL_NTS, NULL, 0);
679 if ((SQL_SUCCESS != rc) and (SQL_SUCCESS_WITH_INFO != rc))
681 PERR (
"Can't perform query rc=%d", rc);
682 PRINT_SQLERR (SQL_HANDLE_STMT, rs->sql_hstmt);
683 dui_odbc_recordset_release (&rs->recset);
687 LEAVE (
"(conn=%p, table=%s)", conn, tablename);
ODBCRecordSet * exec(const char *)
friend class ODBCRecordSet
int get_col_by_name(const char *)
ODBCConnection(const char *dbname, const char *username, const char *authentication)
std::stack< ODBCRecordSet * > free_pool
ODBCRecordSet(ODBCConnection *)
void get_column_labels(void)
void alloc_and_bind_cols(int ncols)
const char * get_value(const char *fieldname)
bool foreach_row(bool(T::*cb)(void), T *data)
bool connected(void) const
bool foreach_column(bool(T::*cb)(const char *, const char *), T *data)
void extract_error(const char *)
ODBCRecordSet * get_record_set(void)