RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 18-Mar-2012 20:26:15 Branch: rpm-5_4 Handle: 2012031819261400 Modified files: (Branch: rpm-5_4) rpm/rpmio librpmio.vers rpmodbc.c rpmodbc.h todbc.c Log: - odbc: WIP. Summary: Revision Changes Path 2.199.2.9 +3 -1 rpm/rpmio/librpmio.vers 1.1.2.5 +194 -53 rpm/rpmio/rpmodbc.c 1.1.2.5 +3 -3 rpm/rpmio/rpmodbc.h 1.1.2.4 +72 -20 rpm/rpmio/todbc.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmio/librpmio.vers ============================================================================ $ cvs diff -u -r2.199.2.8 -r2.199.2.9 librpmio.vers --- rpm/rpmio/librpmio.vers 18 Mar 2012 14:02:14 -0000 2.199.2.8 +++ rpm/rpmio/librpmio.vers 18 Mar 2012 19:26:14 -0000 2.199.2.9 @@ -215,12 +215,14 @@ odbcColumns; odbcConnect; odbcDisconnect; - odbcFetch; + odbcExecute; + odbcExecDirect; odbcListDataSources; odbcListDrivers; odbcNCols; odbcNew; odbcPrepare; + odbcPrint; odbcTables; Open; _Open; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmodbc.c ============================================================================ $ cvs diff -u -r1.1.2.4 -r1.1.2.5 rpmodbc.c --- rpm/rpmio/rpmodbc.c 18 Mar 2012 15:47:06 -0000 1.1.2.4 +++ rpm/rpmio/rpmodbc.c 18 Mar 2012 19:26:14 -0000 1.1.2.5 @@ -20,23 +20,48 @@ #include "debug.h" /*@unchecked@*/ -int _odbc_debug = -1; +int _odbc_debug = 0; + +#define DBG(_t, _l) \ + if ((_t) || _odbc_debug) fprintf _l #define SPEW(_t, _rc, _odbc) \ - { if ((_t) || _odbc_debug ) \ + { if ((_t) || _odbc_debug) \ fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, (_odbc), \ (_rc)); \ } /*==============================================================*/ +static int Xchkodbc(/*@unused@*/ ODBC_t odbc, const char * msg, + int error, int printit, + const char * func, const char * fn, unsigned ln) +{ + int rc = error; + + /* XXX filter SQL_NO_DATA(100) return. */ + if (printit && !SQL_SUCCEEDED(rc) && rc != SQL_NO_DATA) { +#define odbc_strerror(_e) "" /* XXX odbc_strerror? */ + rpmlog(RPMLOG_ERR, "%s:%s:%u: %s(%d): %s\n", + func, fn, ln, msg, rc, odbc_strerror(rc)); + } + + return rc; +} +#define CHECK(_odbc, _msg, _error) \ + Xchkodbc(_odbc, _msg, _error, _odbc_debug, __FUNCTION__, __FILE__, __LINE__) + +/*==============================================================*/ int odbcConnect(ODBC_t odbc, const char * uri) { const char * db = NULL; urlinfo u = NULL; int rc = -1; +int xx; -fprintf(stderr, "--> %s(%p,%s)\n", __FUNCTION__, odbc, uri); +DBG(0, (stderr, "--> %s(%p,%s)\n", __FUNCTION__, odbc, uri)); + + /*XXX FIXME: SQLConnect by DSN should be done here. */ if (uri) { const char * dbpath = NULL; @@ -51,22 +76,56 @@ assert(u); assert(db); -fprintf(stderr, "\tdb: %s\n", db); -fprintf(stderr, "\t u: %s\n", u->user); -fprintf(stderr, "\tpw: %s\n", u->password); +DBG(0, (stderr, "\tdb: %s\n", db)); +DBG(0, (stderr, "\t u: %s\n", u->user)); +DBG(0, (stderr, "\tpw: %s\n", u->password)); #if defined(WITH_UNIXODBC) assert(odbc->env); if (odbc->dbc == NULL) { - SQLAllocHandle(SQL_HANDLE_DBC, odbc->env, &odbc->dbc); + xx = CHECK(odbc, "SQLAllocHandle(DBC)", + SQLAllocHandle(SQL_HANDLE_DBC, odbc->env, &odbc->dbc)); assert(odbc->dbc); } - /* XXX FIXME: odbc->u->user and odbc->u->password */ - rc = SQLConnect(odbc->dbc, - (SQLCHAR *) db, SQL_NTS, - (SQLCHAR *) u->user, SQL_NTS, - (SQLCHAR *) u->password, SQL_NTS); + rc = CHECK(odbc, "SQLConnect", + SQLConnect(odbc->dbc, + (SQLCHAR *) db, SQL_NTS, + (SQLCHAR *) u->user, SQL_NTS, + (SQLCHAR *) u->password, SQL_NTS)); + + /* XXX FIXME: SQLDriverConnect should print once?. */ + if (rc == 0) { + SQLCHAR dbms_name[256]; + SQLCHAR dbms_ver[256]; + SQLUINTEGER getdata_support; + SQLUSMALLINT max_concur_act; + + xx = CHECK(odbc, "SQLGetInfo(DBMS_NAME)", + SQLGetInfo(odbc->dbc, SQL_DBMS_NAME, (SQLPOINTER)dbms_name, + sizeof(dbms_name), NULL)); + xx = CHECK(odbc, "SQLGetInfo(DBMS_NAME)", + SQLGetInfo(odbc->dbc, SQL_DBMS_VER, (SQLPOINTER)dbms_ver, + sizeof(dbms_ver), NULL)); + xx = CHECK(odbc, "SQLGetInfo(DBMS_NAME)", + SQLGetInfo(odbc->dbc, SQL_GETDATA_EXTENSIONS, (SQLPOINTER)&getdata_support, + 0, 0)); + xx = CHECK(odbc, "SQLGetInfo(DBMS_NAME)", + SQLGetInfo(odbc->dbc, SQL_MAX_CONCURRENT_ACTIVITIES, &max_concur_act, 0, 0)); + +fprintf(stderr, "\tDBMS Name: %s\n", dbms_name); +fprintf(stderr, "\tDBMS Version: %s\n", dbms_ver); +fprintf(stderr, "\tSQL_MAX_CONCURRENT_ACTIVITIES = %u\n", max_concur_act); + + /* XXX FIXME: dig out and print all the bleeping attribute bits. */ +fprintf(stderr, "\tSQLGetData - %s\n", ((getdata_support & SQL_GD_ANY_ORDER) + ? "columns can be retrieved in any order" + : "columns must be retrieved in order\n")); +fprintf(stderr, "\tSQLGetData - %s\n", ((getdata_support & SQL_GD_ANY_COLUMN) + ? "can retrieve columns before last bound one" + : "columns must be retrieved after last bound one")); + + } #endif SPEW(0, rc, odbc); @@ -77,12 +136,25 @@ int odbcDisconnect(ODBC_t odbc) { int rc = 0; +int xx; #if defined(WITH_UNIXODBC) assert(odbc->env); assert(odbc->dbc); - SQLDisconnect(odbc->dbc); - SQLFreeHandle(SQL_HANDLE_DBC, odbc->dbc ); + rc = CHECK(odbc, "SQLDisconnect", + SQLDisconnect(odbc->dbc)); + if (odbc->desc) { + xx = CHECK(odbc, "SQLFreeHandle(DESC)", + SQLFreeHandle(SQL_HANDLE_DESC, odbc->desc)); + odbc->desc = NULL; + } + if (odbc->stmt) { + xx = CHECK(odbc, "SQLFreeHandle(STMT)", + SQLFreeHandle(SQL_HANDLE_STMT, odbc->stmt)); + odbc->stmt = NULL; + } + xx = CHECK(odbc, "SQLFreeHandle(DBC)", + SQLFreeHandle(SQL_HANDLE_DBC, odbc->dbc)); odbc->dbc = NULL; #endif @@ -104,6 +176,7 @@ SQLRETURN ret; assert(odbc->env); +/* XXX CHECK */ while (SQL_SUCCEEDED(ret = SQLDrivers(odbc->env, direction, dsn, sizeof(dsn), &dsn_ret, desc, sizeof(desc), &desc_ret))) @@ -134,6 +207,7 @@ SQLRETURN ret; assert(odbc->env); +/* XXX CHECK */ while (SQL_SUCCEEDED(ret = SQLDrivers(odbc->env, direction, driver, sizeof(driver), &driver_ret, attr, sizeof(attr), &attr_ret))) @@ -150,89 +224,126 @@ return rc; } -int odbcTables(ODBC_t odbc) +int odbcNCols(ODBC_t odbc) { int rc = 0; #if defined(WITH_UNIXODBC) + SQLSMALLINT columns; + assert(odbc->env); assert(odbc->dbc); - if (odbc->stmt == NULL) { - SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt); assert(odbc->stmt); - } - - SQLTables(odbc->stmt, NULL, 0, NULL, 0, NULL, 0, - (SQLCHAR *) "TABLE", SQL_NTS); + rc = CHECK(odbc, "SQLNumResultCols", + SQLNumResultCols(odbc->stmt, &columns)); + rc = columns; #endif SPEW(0, rc, odbc); return rc; } -int odbcColumns(ODBC_t odbc) +int odbcPrint(ODBC_t odbc, void * _fp) { + FILE * fp = (_fp ? _fp : stderr); int rc = 0; +int xx; + +DBG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, odbc, _fp)); #if defined(WITH_UNIXODBC) + assert(odbc->env); assert(odbc->dbc); - if (odbc->stmt == NULL) { - SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt); assert(odbc->stmt); - } - SQLColumns(odbc->stmt, NULL, 0, NULL, 0, NULL, 0, - (SQLCHAR *) "TABLE", SQL_NTS); + odbc->ncols = odbcNCols(odbc); + + odbc->nrows = 0; + /* XXX filter SQL_NO_DATA(100) return. */ + while (SQL_SUCCEEDED((xx = CHECK(odbc, "SQLFetch", + SQLFetch(odbc->stmt))))) + { + int i; + + fprintf(fp, "Row %d\n", ++odbc->nrows); + for (i = 0; i < odbc->ncols; i++) { + SQLLEN got; + char b[BUFSIZ]; + size_t nb = sizeof(b); + /* XXX filter -1 return (columns start with 1 not 0). */ + xx = CHECK(odbc, "SQLGetData", + SQLGetData(odbc->stmt, i+1, SQL_C_CHAR, b, nb, &got)); + if (SQL_SUCCEEDED(xx)) { + if (got == 0) strcpy(b, "NULL"); + fprintf(fp, " Column %d : %s\n", i+1, b); + } + } + } + if (odbc->stmt) { + xx = CHECK(odbc, "SQLFreeHandle(STMT)", + SQLFreeHandle(SQL_HANDLE_STMT, odbc->stmt)); + odbc->stmt = NULL; + } #endif SPEW(0, rc, odbc); + return rc; } -int odbcNCols(ODBC_t odbc) +int odbcTables(ODBC_t odbc) { int rc = 0; +int xx; #if defined(WITH_UNIXODBC) - SQLSMALLINT columns; - assert(odbc->env); assert(odbc->dbc); + if (odbc->stmt == NULL) { + xx = CHECK(odbc, "SQLAllocHandle(STMT)", + SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt)); assert(odbc->stmt); - SQLNumResultCols(odbc->stmt, &columns); - rc = columns; + } + + rc = CHECK(odbc, "SQLTables", + SQLTables(odbc->stmt, NULL, 0, NULL, 0, NULL, 0, + (SQLCHAR *) "TABLE", SQL_NTS)); #endif SPEW(0, rc, odbc); return rc; } -int odbcExecDirect(ODBC_t odbc, const char * s, size_t ns) +int odbcColumns(ODBC_t odbc) { int rc = 0; - - if (ns == 0) - ns = strlen(s); +int xx; #if defined(WITH_UNIXODBC) assert(odbc->env); assert(odbc->dbc); if (odbc->stmt == NULL) { - SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt); + xx = CHECK(odbc, "SQLAllocHandle(STMT)", + SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt)); assert(odbc->stmt); } - rc = SQLExecDirect(odbc->stmt, (SQLCHAR *) s, (SQLINTEGER) ns); + rc = CHECK(odbc, "SQLTables", + SQLColumns(odbc->stmt, NULL, 0, NULL, 0, NULL, 0, + (SQLCHAR *) "TABLE", SQL_NTS)); #endif SPEW(0, rc, odbc); return rc; } -int odbcPrepare(ODBC_t odbc, const char * s, size_t ns) +int odbcExecDirect(ODBC_t odbc, const char * s, size_t ns) { int rc = 0; +int xx; + +DBG(0, (stderr, "--> %s(%p,%s,%u)\n", __FUNCTION__, odbc, s, (unsigned)ns)); if (ns == 0) ns = strlen(s); @@ -241,43 +352,64 @@ assert(odbc->env); assert(odbc->dbc); if (odbc->stmt == NULL) { - SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt); + xx = CHECK(odbc, "SQLAllocHandle(STMT)", + SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt)); assert(odbc->stmt); } - rc = SQLPrepare(odbc->stmt, (SQLCHAR *) s, (SQLINTEGER) ns); + rc = CHECK(odbc, "SQLExecDirect", + SQLExecDirect(odbc->stmt, (SQLCHAR *) s, (SQLINTEGER) ns)); #endif SPEW(0, rc, odbc); return rc; } -int odbcExecute(ODBC_t odbc) +int odbcPrepare(ODBC_t odbc, const char * s, size_t ns) { - int rc = -1; + int rc = 0; +int xx; + +DBG(0, (stderr, "--> %s(%p,%s,%u)\n", __FUNCTION__, odbc, s, (unsigned)ns)); + + if (ns == 0) + ns = strlen(s); #if defined(WITH_UNIXODBC) assert(odbc->env); assert(odbc->dbc); + /* XXX FIXME: programmer error */ + if (odbc->stmt) { + xx = CHECK(odbc, "SQLFreeHandle(STMT)", + SQLFreeHandle(SQL_HANDLE_STMT, odbc->stmt)); + odbc->stmt = NULL; + } +assert(odbc->stmt == NULL); + if (odbc->stmt == NULL) { + xx = CHECK(odbc, "SQLAllocHandle(STMT)", + SQLAllocHandle(SQL_HANDLE_STMT, odbc->dbc, &odbc->stmt)); assert(odbc->stmt); + } - rc = SQLExecute(odbc->stmt); + rc = CHECK(odbc, "SQLPrepare", + SQLPrepare(odbc->stmt, (SQLCHAR *) s, (SQLINTEGER) ns)); #endif SPEW(0, rc, odbc); return rc; } -int odbcFetch(ODBC_t odbc) +int odbcExecute(ODBC_t odbc) { - int rc = 0; + int rc = -1; #if defined(WITH_UNIXODBC) assert(odbc->env); assert(odbc->dbc); assert(odbc->stmt); - rc = SQLFetch(odbc->stmt); + rc = CHECK(odbc, "SQLExecute", + SQLExecute(odbc->stmt)); #endif SPEW(0, rc, odbc); @@ -293,20 +425,25 @@ ODBC_t odbc = _odbc; #if defined(WITH_UNIXODBC) +int xx; if (odbc->desc) { - SQLFreeHandle(SQL_HANDLE_DESC, odbc->desc); + xx = CHECK(odbc, "SQLFreeHandle(DESC)", + SQLFreeHandle(SQL_HANDLE_DESC, odbc->desc)); odbc->desc = NULL; } if (odbc->stmt) { - SQLFreeHandle(SQL_HANDLE_DESC, odbc->stmt); + xx = CHECK(odbc, "SQLFreeHandle(STMT)", + SQLFreeHandle(SQL_HANDLE_STMT, odbc->stmt)); odbc->stmt = NULL; } if (odbc->dbc) { - SQLFreeHandle(SQL_HANDLE_DBC, odbc->dbc); + xx = CHECK(odbc, "SQLFreeHandle(DBC)", + SQLFreeHandle(SQL_HANDLE_DBC, odbc->dbc)); odbc->dbc = NULL; } if (odbc->env) { - SQLFreeHandle(SQL_HANDLE_ENV, odbc->env); + xx = CHECK(odbc, "SQLFreeHandle(ENV)", + SQLFreeHandle(SQL_HANDLE_ENV, odbc->env)); odbc->env = NULL; } #endif @@ -340,6 +477,7 @@ ODBC_t odbcNew(const char * fn, int flags) { ODBC_t odbc = odbcGetPool(_odbcPool); +int xx; if (fn == NULL) fn = _odbc_uri; @@ -356,9 +494,12 @@ } #if defined(WITH_UNIXODBC) - SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc->env); + xx = CHECK(odbc, "SQLAllocHandle(ENV)", + SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc->env)); assert(odbc->env); - SQLSetEnvAttr(odbc->env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + xx = CHECK(odbc, "SQLSetEnvAttr", + SQLSetEnvAttr(odbc->env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); + /* XXX FIXME: SQLDriverConnect should be done here. */ #endif return odbcLink(odbc); @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmodbc.h ============================================================================ $ cvs diff -u -r1.1.2.4 -r1.1.2.5 rpmodbc.h --- rpm/rpmio/rpmodbc.h 18 Mar 2012 15:47:06 -0000 1.1.2.4 +++ rpm/rpmio/rpmodbc.h 18 Mar 2012 19:26:14 -0000 1.1.2.5 @@ -112,6 +112,9 @@ int odbcNCols(ODBC_t odbc) /*@*/; +int odbcPrint(ODBC_t odbc, void * _fp) + /*@*/; + int odbcExecDirect(ODBC_t odbc, const char * s, size_t ns) /*@*/; @@ -121,9 +124,6 @@ int odbcExecute(ODBC_t odbc) /*@*/; -int odbcFetch(ODBC_t odbc) - /*@*/; - #ifdef __cplusplus } #endif @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/todbc.c ============================================================================ $ cvs diff -u -r1.1.2.3 -r1.1.2.4 todbc.c --- rpm/rpmio/todbc.c 18 Mar 2012 15:47:06 -0000 1.1.2.3 +++ rpm/rpmio/todbc.c 18 Mar 2012 19:26:14 -0000 1.1.2.4 @@ -10,14 +10,31 @@ #include "debug.h" +static char * _odbc_uri = "mysql://luser:jasnl@localhost/test"; +static int _odbc_flags = 0; + #define SPEW(_t, _rc, _odbc) \ { if ((_t) || _odbc_debug ) \ fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, (_odbc), \ (_rc)); \ } +/*==============================================================*/ +static int Xchkodbc(/*@unused@*/ ODBC_t odbc, const char * msg, + int error, int printit, + const char * func, const char * fn, unsigned ln) +{ + int rc = error; + + if (printit && rc) { +#define odbc_strerror(_e) "" /* XXX odbc_strerror? */ + rpmlog(RPMLOG_ERR, "%s:%s:%u: %s(%d): %s\n", + func, fn, ln, msg, rc, odbc_strerror(rc)); + } -static char * _odbc_uri = "mysql://luser:jasnl@localhost/test"; -static int _odbc_flags = 0; + return rc; +} +#define CHECK(_odbc, _msg, _error) \ + Xchkodbc(_odbc, _msg, _error, _odbc_debug, __FUNCTION__, __FILE__, __LINE__) /*==============================================================*/ @@ -85,6 +102,43 @@ } /*==============================================================*/ +static const char *const _odbc_stmts[] = { + "SHOW DATABASES;", + "USE test;", + "SHOW TABLES;", + "DROP TABLE Packages;", +"CREATE TABLE Packages (\n\ + i INTEGER PRIMARY KEY NOT NULL,\n\ + Nvra VARCHAR(64)\n\ +);", + "DESCRIBE Packages;", + "INSERT INTO Packages VALUES( 1, 'Bing' );", + "INSERT INTO Packages VALUES( 2, 'Bang' );", + "INSERT INTO Packages VALUES( 3, 'Boom' );", + "SELECT * from Packages;", + "DROP TABLE Packages;", + NULL +}; + +static int odbcRun(ODBC_t odbc, const char *const stmts[], void * _fp) +{ + FILE * fp = (_fp ? _fp : stderr); + const char * s; + int rc = -1; + int i; + + for (i = 0; (s = stmts[i]) != NULL; i++) { +fprintf(fp, "==> %s\n", s); + rc = odbcPrepare(odbc, s, 0); + rc = odbcExecute(odbc); + rc = odbcPrint(odbc, fp); + } + +SPEW(0, rc, odbc); + return rc; +} + +/*==============================================================*/ static struct poptOption odbcOptionsTable[] = { { NULL, 'f', POPT_ARG_INT, &_odbc_flags, -1, @@ -111,31 +165,29 @@ int rc = 0; int xx; +fprintf(_odbc_fp, "==> %s\n", "ListDrivers"); rc = odbcListDrivers(odbc, _odbc_fp); +fprintf(_odbc_fp, "==> %s\n", "ListDataSources"); rc = odbcListDataSources(odbc, _odbc_fp); +fprintf(_odbc_fp, "==> %s\n", "Connect"); rc = odbcConnect(odbc, _uri); +fprintf(_odbc_fp, "==> %s\n", "Tables"); + xx = odbcTables(odbc); + xx = odbcPrint(odbc, _odbc_fp); + +fprintf(_odbc_fp, "==> %s\n", "Columns"); xx = odbcColumns(odbc); - odbc->ncols = odbcNCols(odbc); - odbc->nrows = 0; - while ((xx = odbcFetch(odbc)) != SQL_NO_DATA) { - int i; - - fprintf(stdout, "Row %d\n", odbc->nrows++); - for (i = 0; i <= odbc->ncols; i++) { - SQLRETURN ret; - SQLLEN got; - char b[512]; - size_t nb = sizeof(b); - ret = SQLGetData(odbc->stmt, i, SQL_C_CHAR, b, nb, &got); - if (SQL_SUCCEEDED(ret)) { - if (got == 0) strcpy(b, "NULL"); - fprintf(stdout, " Column %d : %s\n", i, b); - } - } - } + xx = odbcPrint(odbc, _odbc_fp); + +fprintf(_odbc_fp, "==> %s\n", "ExecDirect"); + xx = odbcExecDirect(odbc, "SHOW DATABASES;", 0); + xx = odbcPrint(odbc, _odbc_fp); + + xx = odbcRun(odbc, _odbc_stmts, _odbc_fp); +fprintf(_odbc_fp, "<== %s\n", "Disconnect"); rc = odbcDisconnect(odbc); xx = odbcOpen(odbc); @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org