Commit 736f821c authored by Sergei Golubchik's avatar Sergei Golubchik

Merge branch 'connect/10.1' into 10.1

parents 62e0a455 7e64b079
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*.cpp text *.cpp text
*.h text *.h text
*.test text *.test text
*.java text
# These files should be checked out as is # These files should be checked out as is
*.result -text -whitespace *.result -text -whitespace
...@@ -23,9 +24,11 @@ pcre/testdata/greppatN4 -text ...@@ -23,9 +24,11 @@ pcre/testdata/greppatN4 -text
*.frm binary *.frm binary
*.MYD binary *.MYD binary
*.MYI binary *.MYI binary
*.class binary
*.c diff=cpp *.c diff=cpp
*.h diff=cpp *.h diff=cpp
*.cc diff=cpp *.cc diff=cpp
*.ic diff=cpp *.ic diff=cpp
*.cpp diff=cpp *.cpp diff=cpp
*.java diff=cpp
...@@ -244,6 +244,8 @@ storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result ...@@ -244,6 +244,8 @@ storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result
*.exp *.exp
*.dep *.dep
*.idb *.idb
*.res
*.tlog
# Precompiled Headers # Precompiled Headers
*.gch *.gch
......
This diff was suppressed by a .gitattributes entry.
...@@ -307,7 +307,7 @@ public class JdbcInterface { ...@@ -307,7 +307,7 @@ public class JdbcInterface {
} // end of GetMaxValue } // end of GetMaxValue
public int GetColumns(String[] parms) { public int GetColumns(String[] parms) {
int ncol = 0; int ncol = -1;
try { try {
if (rs != null) rs.close(); if (rs != null) rs.close();
......
...@@ -129,7 +129,8 @@ ...@@ -129,7 +129,8 @@
#include "odbccat.h" #include "odbccat.h"
#endif // ODBC_SUPPORT #endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT) #if defined(JDBC_SUPPORT)
#include "jdbccat.h" #include "tabjdbc.h"
#include "jdbconn.h"
#endif // JDBC_SUPPORT #endif // JDBC_SUPPORT
#include "xtable.h" #include "xtable.h"
#include "tabmysql.h" #include "tabmysql.h"
...@@ -5163,7 +5164,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5163,7 +5164,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // ODBC_SUPPORT #endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT) #if defined(JDBC_SUPPORT)
PJPARM sjp= NULL; PJPARM sjp= NULL;
char *jpath= NULL;
char *driver= NULL; char *driver= NULL;
char *url= NULL; char *url= NULL;
char *tabtyp = NULL; char *tabtyp = NULL;
...@@ -5230,9 +5230,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5230,9 +5230,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
cnc= (!*ucnc || *ucnc == 'y' || *ucnc == 'Y' || atoi(ucnc) != 0); cnc= (!*ucnc || *ucnc == 'y' || *ucnc == 'Y' || atoi(ucnc) != 0);
#endif #endif
#if defined(JDBC_SUPPORT) #if defined(JDBC_SUPPORT)
jpath= GetListOption(g, "Jpath", topt->oplist, NULL);
driver= GetListOption(g, "Driver", topt->oplist, NULL); driver= GetListOption(g, "Driver", topt->oplist, NULL);
url= GetListOption(g, "URL", topt->oplist, NULL); // url= GetListOption(g, "URL", topt->oplist, NULL);
tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL); tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
#endif // JDBC_SUPPORT #endif // JDBC_SUPPORT
mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0")); mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
...@@ -5333,18 +5332,31 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5333,18 +5332,31 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_JDBC: case TAB_JDBC:
if (fnc & FNC_DRIVER) { if (fnc & FNC_DRIVER) {
ok= true; ok= true;
} else if (!url) { } else if (!(url= strz(g, create_info->connect_string))) {
strcpy(g->Message, "Missing URL"); strcpy(g->Message, "Missing URL");
} else { } else {
// Store ODBC additional parameters // Store JDBC additional parameters
int rc;
PJDBCDEF jdef= new(g) JDBCDEF();
jdef->SetName(create_info->alias);
sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM)); sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
sjp->Driver= driver; sjp->Driver= driver;
sjp->Fsize= 0;
sjp->Scrollable= false;
if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) {
sjp->Url= url; sjp->Url= url;
sjp->User= (char*)user; sjp->User= (char*)user;
sjp->Pwd= (char*)pwd; sjp->Pwd= (char*)pwd;
sjp->Fsize= 0;
sjp->Scrollable= false;
ok= true; ok= true;
} else if (rc == RC_NF) {
if (jdef->GetTabname())
tab= jdef->GetTabname();
ok= jdef->SetParms(sjp);
} // endif rc
} // endif's } // endif's
supfnc |= (FNC_DRIVER | FNC_TABLE); supfnc |= (FNC_DRIVER | FNC_TABLE);
...@@ -5496,7 +5508,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5496,7 +5508,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
break; break;
case FNC_TABLE: case FNC_TABLE:
qrp= ODBCTables(g, dsn, shm, tab, mxr, true, sop); qrp= ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop);
break; break;
case FNC_DSN: case FNC_DSN:
qrp= ODBCDataSources(g, mxr, true); qrp= ODBCDataSources(g, mxr, true);
...@@ -5517,15 +5529,14 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5517,15 +5529,14 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case FNC_NO: case FNC_NO:
case FNC_COL: case FNC_COL:
if (src) { if (src) {
qrp= JDBCSrcCols(g, jpath, (char*)src, sjp); qrp= JDBCSrcCols(g, (char*)src, sjp);
src= NULL; // for next tests src= NULL; // for next tests
} else } else
qrp= JDBCColumns(g, jpath, shm, tab, NULL, qrp= JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp);
mxr, fnc == FNC_COL, sjp);
break; break;
case FNC_TABLE: case FNC_TABLE:
qrp= JDBCTables(g, dsn, shm, tab, tabtyp, mxr, true, sjp); qrp= JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp);
break; break;
#if 0 #if 0
case FNC_DSN: case FNC_DSN:
...@@ -5533,7 +5544,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5533,7 +5544,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
break; break;
#endif // 0 #endif // 0
case FNC_DRIVER: case FNC_DRIVER:
qrp= JDBCDrivers(g, jpath, mxr, true); qrp= JDBCDrivers(g, mxr, true);
break; break;
default: default:
sprintf(g->Message, "invalid catfunc %s", fncn); sprintf(g->Message, "invalid catfunc %s", fncn);
...@@ -5784,12 +5795,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5784,12 +5795,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
switch (typ) { switch (typ) {
case TYPE_DOUBLE: case TYPE_DOUBLE:
case TYPE_DECIM:
// Some data sources do not count dec in length (prec) // Some data sources do not count dec in length (prec)
prec += (dec + 2); // To be safe prec += (dec + 2); // To be safe
break; break;
case TYPE_DECIM:
prec= len;
break;
default: default:
dec= 0; dec= 0;
} // endswitch typ } // endswitch typ
......
...@@ -21,9 +21,9 @@ typedef struct jdbc_parms { ...@@ -21,9 +21,9 @@ typedef struct jdbc_parms {
char *JDBCCheckConnection(PGLOBAL g, char *dsn, int cop); char *JDBCCheckConnection(PGLOBAL g, char *dsn, int cop);
#endif // PROMPT_OK #endif // PROMPT_OK
//PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info); //PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info);
PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table,
char *colpat, int maxres, bool info, PJPARM sop); char *colpat, int maxres, bool info, PJPARM sop);
PQRYRES JDBCSrcCols(PGLOBAL g, char *jpath, char *src, PJPARM sop); PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sop);
PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat,
char *tabtyp, int maxres, bool info, PJPARM sop); char *tabtyp, int maxres, bool info, PJPARM sop);
PQRYRES JDBCDrivers(PGLOBAL g, char *jpath, int maxres, bool info); PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info);
...@@ -17,17 +17,19 @@ ...@@ -17,17 +17,19 @@
#include <direct.h> // for getcwd #include <direct.h> // for getcwd
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro #define __MFC_COMPAT__ // To define min/max as macro
#endif #endif // __BORLANDC__
//#include <windows.h> //#include <windows.h>
#else #else // !__WIN__
#if defined(UNIX) #if defined(UNIX)
#include <errno.h> #include <errno.h>
#else #else // !UNIX
//nclude <io.h> //nclude <io.h>
#endif #endif // !UNIX
#include <stdio.h>
#include <stdlib.h> // for getenv
//nclude <fcntl.h> //nclude <fcntl.h>
#define NODW #define NODW
#endif #endif // !__WIN__
/***********************************************************************/ /***********************************************************************/
/* Required objects includes. */ /* Required objects includes. */
...@@ -36,7 +38,6 @@ ...@@ -36,7 +38,6 @@
#include "plgdbsem.h" #include "plgdbsem.h"
#include "xobject.h" #include "xobject.h"
#include "xtable.h" #include "xtable.h"
#include "jdbccat.h"
#include "tabjdbc.h" #include "tabjdbc.h"
//#include "jdbconn.h" //#include "jdbconn.h"
//#include "plgcnx.h" // For DB types //#include "plgcnx.h" // For DB types
...@@ -47,9 +48,24 @@ ...@@ -47,9 +48,24 @@
#if defined(__WIN__) #if defined(__WIN__)
extern "C" HINSTANCE s_hModule; // Saved module handle extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // __WIN__ #else // !__WIN__
#define nullptr 0
#endif // !__WIN__
int GetConvSize(); int GetConvSize();
extern char *JvmPath; // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_path global variable value
extern char *Wrapper; // The connect_java_wrapper global variable value
/***********************************************************************/
/* Static JDBConn objects. */
/***********************************************************************/
void *JDBConn::LibJvm = NULL;
CRTJVM JDBConn::CreateJavaVM = NULL;
GETJVM JDBConn::GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GETDEF JDBConn::GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
/***********************************************************************/ /***********************************************************************/
/* Some macro's (should be defined elsewhere to be more accessible) */ /* Some macro's (should be defined elsewhere to be more accessible) */
...@@ -62,6 +78,9 @@ int GetConvSize(); ...@@ -62,6 +78,9 @@ int GetConvSize();
#define DEBUG_ONLY(f) ((void)0) #define DEBUG_ONLY(f) ((void)0)
#endif // !_DEBUG #endif // !_DEBUG
// To avoid gcc warning
int TranslateJDBCType(int stp, int prec, int& len, char& v);
/***********************************************************************/ /***********************************************************************/
/* GetJDBCType: returns the SQL_TYPE corresponding to a PLG type. */ /* GetJDBCType: returns the SQL_TYPE corresponding to a PLG type. */
/***********************************************************************/ /***********************************************************************/
...@@ -102,6 +121,7 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) ...@@ -102,6 +121,7 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v)
break; break;
case 2: // NUMERIC case 2: // NUMERIC
case 3: // DECIMAL case 3: // DECIMAL
case -3: // VARBINARY
type = TYPE_DECIM; type = TYPE_DECIM;
break; break;
case 4: // INTEGER case 4: // INTEGER
...@@ -139,7 +159,6 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) ...@@ -139,7 +159,6 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v)
break; break;
case 0: // NULL case 0: // NULL
case -2: // BINARY case -2: // BINARY
case -3: // VARBINARY
case -4: // LONGVARBINARY case -4: // LONGVARBINARY
default: default:
type = TYPE_ERROR; type = TYPE_ERROR;
...@@ -155,42 +174,20 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) ...@@ -155,42 +174,20 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v)
static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db, static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db,
char *tab, PQRYRES qrp) char *tab, PQRYRES qrp)
{ {
size_t m, n;
JCATPARM *cap; JCATPARM *cap;
#if defined(_DEBUG) #if defined(_DEBUG)
assert(qrp); assert(qrp);
#endif #endif
// Save stack and allocation environment and prepare error return if ((cap = (JCATPARM *)PlgDBSubAlloc(g, NULL, sizeof(JCATPARM)))) {
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return NULL;
} // endif jump_level
if (setjmp(g->jumper[++g->jump_level]) != 0) {
printf("%s\n", g->Message);
cap = NULL;
goto fin;
} // endif rc
m = (size_t)qrp->Maxres;
n = (size_t)qrp->Nbcol;
cap = (JCATPARM *)PlugSubAlloc(g, NULL, sizeof(JCATPARM));
memset(cap, 0, sizeof(JCATPARM)); memset(cap, 0, sizeof(JCATPARM));
cap->Id = fid; cap->Id = fid;
cap->Qrp = qrp; cap->Qrp = qrp;
cap->DB = (PUCHAR)db; cap->DB = db;
cap->Tab = (PUCHAR)tab; cap->Tab = tab;
//cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *)); } // endif cap
//for (i = 0; i < n; i++)
// cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * sizeof(SQLLEN));
//cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD));
fin:
g->jump_level--;
return cap; return cap;
} // end of AllocCatInfo } // end of AllocCatInfo
...@@ -198,8 +195,8 @@ static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db, ...@@ -198,8 +195,8 @@ static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db,
/* JDBCColumns: constructs the result blocks containing all columns */ /* JDBCColumns: constructs the result blocks containing all columns */
/* of a JDBC table that will be retrieved by GetData commands. */ /* of a JDBC table that will be retrieved by GetData commands. */
/***********************************************************************/ /***********************************************************************/
PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat,
char *colpat, int maxres, bool info, PJPARM sjp) int maxres, bool info, PJPARM sjp)
{ {
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT,
...@@ -221,7 +218,7 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, ...@@ -221,7 +218,7 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table,
if (!info) { if (!info) {
jcp = new(g)JDBConn(g, NULL); jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(jpath, sjp) != RC_OK) // openReadOnly + noJDBCdialog if (jcp->Open(sjp) != RC_OK) // openReadOnly + noJDBCdialog
return NULL; return NULL;
if (table && !strchr(table, '%')) { if (table && !strchr(table, '%')) {
...@@ -272,7 +269,8 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, ...@@ -272,7 +269,8 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table,
if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp))) if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp)))
return NULL; return NULL;
cap->Pat = (PUCHAR)colpat; // Colpat cannot be null or empty for some drivers
cap->Pat = (colpat && *colpat) ? colpat : "%";
/************************************************************************/ /************************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
...@@ -300,22 +298,25 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, ...@@ -300,22 +298,25 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table,
/* JDBCSrcCols: constructs the result blocks containing the */ /* JDBCSrcCols: constructs the result blocks containing the */
/* description of all the columns of a Srcdef option. */ /* description of all the columns of a Srcdef option. */
/**************************************************************************/ /**************************************************************************/
PQRYRES JDBCSrcCols(PGLOBAL g, char *jpath, char *src, PJPARM sjp) PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp)
{ {
PQRYRES qrp;
JDBConn *jcp = new(g)JDBConn(g, NULL); JDBConn *jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(jpath, sjp)) if (jcp->Open(sjp))
return NULL; return NULL;
return jcp->GetMetaData(g, src); qrp = jcp->GetMetaData(g, src);
jcp->Close();
return qrp;
} // end of JDBCSrcCols } // end of JDBCSrcCols
/**************************************************************************/ /**************************************************************************/
/* JDBCTables: constructs the result blocks containing all tables in */ /* JDBCTables: constructs the result blocks containing all tables in */
/* an JDBC database that will be retrieved by GetData commands. */ /* an JDBC database that will be retrieved by GetData commands. */
/**************************************************************************/ /**************************************************************************/
PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp,
char *tabtyp, int maxres, bool info, PJPARM sjp) int maxres, bool info, PJPARM sjp)
{ {
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_STRING, TYPE_STRING}; TYPE_STRING, TYPE_STRING};
...@@ -337,7 +338,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, ...@@ -337,7 +338,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat,
/**********************************************************************/ /**********************************************************************/
jcp = new(g)JDBConn(g, NULL); jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(jpath, sjp) == RC_FX) if (jcp->Open(sjp) == RC_FX)
return NULL; return NULL;
if (!maxres) if (!maxres)
...@@ -345,14 +346,14 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, ...@@ -345,14 +346,14 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat,
n = jcp->GetMaxValue(2); // Max catalog name length n = jcp->GetMaxValue(2); // Max catalog name length
if (n < 0) // if (n < 0)
return NULL; // return NULL;
length[0] = (n) ? (n + 1) : 0; length[0] = (n > 0) ? (n + 1) : 0;
n = jcp->GetMaxValue(3); // Max schema name length n = jcp->GetMaxValue(3); // Max schema name length
length[1] = (n) ? (n + 1) : 0; length[1] = (n > 0) ? (n + 1) : 0;
n = jcp->GetMaxValue(4); // Max table name length n = jcp->GetMaxValue(4); // Max table name length
length[2] = (n) ? (n + 1) : 128; length[2] = (n > 0) ? (n + 1) : 128;
} else { } else {
maxres = 0; maxres = 0;
length[0] = 128; length[0] = 128;
...@@ -380,7 +381,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, ...@@ -380,7 +381,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat,
if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp))) if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp)))
return NULL; return NULL;
cap->Pat = (PUCHAR)tabtyp; cap->Pat = tabtyp;
if (trace) if (trace)
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol); htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
...@@ -414,7 +415,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, ...@@ -414,7 +415,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat,
/* drivers available on the local host. */ /* drivers available on the local host. */
/* Called with info=true to have result column names. */ /* Called with info=true to have result column names. */
/*************************************************************************/ /*************************************************************************/
PQRYRES JDBCDrivers(PGLOBAL g, char *jpath, int maxres, bool info) PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
{ {
int buftyp[] ={TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING}; int buftyp[] ={TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING};
XFLD fldtyp[] ={FLD_NAME, FLD_EXTRA, FLD_DEFAULT, FLD_REM }; XFLD fldtyp[] ={FLD_NAME, FLD_EXTRA, FLD_DEFAULT, FLD_REM };
...@@ -431,7 +432,7 @@ PQRYRES JDBCDrivers(PGLOBAL g, char *jpath, int maxres, bool info) ...@@ -431,7 +432,7 @@ PQRYRES JDBCDrivers(PGLOBAL g, char *jpath, int maxres, bool info)
if (!info) { if (!info) {
jcp = new(g) JDBConn(g, NULL); jcp = new(g) JDBConn(g, NULL);
if (jcp->Open(jpath, NULL) != RC_OK) if (jcp->Open(NULL) != RC_OK)
return NULL; return NULL;
if (!maxres) if (!maxres)
...@@ -613,90 +614,6 @@ PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table) ...@@ -613,90 +614,6 @@ PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table)
/************************************************************************/ /************************************************************************/
return qrp; return qrp;
} // end of JDBCPrimaryKeys } // end of JDBCPrimaryKeys
/**************************************************************************/
/* Statistics: constructs the result blocks containing statistics */
/* about one or several tables to be retrieved by GetData commands. */
/**************************************************************************/
PQRYRES JDBCStatistics(PGLOBAL g, JDBConn *op, char *dsn, char *pat,
int un, int acc)
{
static int buftyp[] ={ TYPE_STRING,
TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_STRING,
TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_STRING };
static unsigned int length[] ={ 0, 0, 0, 6, 0, 0, 6, 6, 0, 2, 10, 10, 128 };
int n, ncol = 13;
int maxres;
PQRYRES qrp;
JCATPARM *cap;
JDBConn *jcp = op;
if (!op) {
/**********************************************************************/
/* Open the connection with the JDBC data source. */
/**********************************************************************/
jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;
} // endif op
/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
n = 1 + jcp->GetMaxValue(SQL_MAX_COLUMNS_IN_INDEX);
maxres = (n) ? (int)n : 32;
n = jcp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
length[1] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
length[2] = length[5] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
length[0] = length[4] = (n) ? (n + 1) : length[2];
n = jcp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[7] = (n) ? (n + 1) : 128;
if (trace)
htrc("SemStatistics: max=%d pat=%s\n", maxres, SVP(pat));
/************************************************************************/
/* Allocate the structure used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT,
buftyp, NULL, length, false, true);
if (trace)
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
cap = AllocCatInfo(g, CAT_STAT, NULL, pat, qrp);
cap->Unique = (un < 0) ? SQL_INDEX_UNIQUE : (UWORD)un;
cap->Accuracy = (acc < 0) ? SQL_QUICK : (UWORD)acc;
/************************************************************************/
/* Now get the results into blocks. */
/************************************************************************/
if ((n = jcp->GetCatInfo(cap)) >= 0) {
qrp->Nblin = n;
// ResetNullValues(cap);
if (trace)
htrc("Statistics: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
qrp = NULL;
/************************************************************************/
/* Close any local connection. */
/************************************************************************/
if (!op)
jcp->Close();
/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
return qrp;
} // end of Statistics
#endif // 0 #endif // 0
/***********************************************************************/ /***********************************************************************/
...@@ -708,13 +625,15 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) ...@@ -708,13 +625,15 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
m_Tdb = tdbp; m_Tdb = tdbp;
jvm = nullptr; // Pointer to the JVM (Java Virtual Machine) jvm = nullptr; // Pointer to the JVM (Java Virtual Machine)
env= nullptr; // Pointer to native interface env= nullptr; // Pointer to native interface
jdi = nullptr; // Pointer to the JdbcInterface class jdi = nullptr; // Pointer to the java wrapper class
job = nullptr; // The JdbcInterface class object job = nullptr; // The java wrapper class object
xqid = xuid = xid = grs = readid = fetchid = typid = nullptr; xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr;
prepid = xpid = pcid = nullptr; prepid = xpid = pcid = nullptr;
chrfldid = intfldid = dblfldid = fltfldid = datfldid = bigfldid = nullptr;
//m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; //m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT;
//m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; //m_QueryTimeout = DEFAULT_QUERY_TIMEOUT;
//m_UpdateOptions = 0; //m_UpdateOptions = 0;
Msg = NULL;
m_Driver = NULL; m_Driver = NULL;
m_Url = NULL; m_Url = NULL;
m_User = NULL; m_User = NULL;
...@@ -741,32 +660,56 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) ...@@ -741,32 +660,56 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
// } // end of ~JDBConn // } // end of ~JDBConn
#if 0
/***********************************************************************/ /***********************************************************************/
/* Screen for errors. */ /* Screen for errors. */
/***********************************************************************/ /***********************************************************************/
bool JDBConn::Check(RETCODE rc) bool JDBConn::Check(jint rc)
{ {
switch (rc) { jstring s;
case SQL_SUCCESS_WITH_INFO:
if (trace) {
DJX x(rc);
if (x.BuildErrorMessage(this, m_hstmt)) if (env->ExceptionCheck()) {
htrc("JDBC Success With Info, hstmt=%p %s\n", jthrowable exc = env->ExceptionOccurred();
m_hstmt, x.GetErrorMessage(0)); jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"),
"toString", "()Ljava/lang/String;");
} // endif trace if (exc != nullptr && tid != nullptr) {
jstring s = (jstring)env->CallObjectMethod(exc, tid);
const char *utf = env->GetStringUTFChars(s, (jboolean)false);
env->DeleteLocalRef(s);
Msg = PlugDup(m_G, utf);
} else
Msg = "Exception occured";
env->ExceptionClear();
} else if (rc < 0) {
s = (jstring)env->CallObjectMethod(job, errid);
Msg = (char*)env->GetStringUTFChars(s, (jboolean)false);
} else
Msg = NULL;
return (Msg != NULL);
} // end of Check
/***********************************************************************/
/* Get MethodID if not exists yet. */
/***********************************************************************/
bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig)
{
if (mid == nullptr) {
mid = env->GetMethodID(jdi, name, sig);
// Fall through if (Check()) {
case SQL_SUCCESS: strcpy(g->Message, Msg);
case SQL_NO_DATA_FOUND:
return true; return true;
} // endswitch rc } else
return false;
} else
return false; return false;
} // end of Check
} // end of gmID
#if 0
/***********************************************************************/ /***********************************************************************/
/* Utility routine. */ /* Utility routine. */
/***********************************************************************/ /***********************************************************************/
...@@ -825,65 +768,209 @@ void JDBConn::OnSetOptions(HSTMT hstmt) ...@@ -825,65 +768,209 @@ void JDBConn::OnSetOptions(HSTMT hstmt)
/***********************************************************************/ /***********************************************************************/
int JDBConn::GetMaxValue(int n) int JDBConn::GetMaxValue(int n)
{ {
jmethodID maxid = env->GetMethodID(jdi, "GetMaxValue", "(I)I"); jint m;
jmethodID maxid = nullptr;
if (maxid == nullptr) { if (gmID(m_G, maxid, "GetMaxValue", "(I)I"))
strcpy(m_G->Message, "ERROR: method GetMaxValue not found !");
return -1; return -1;
} // endif maxid
// call method // call method
return (int)env->CallIntMethod(job, maxid, n); if (Check(m = env->CallIntMethod(job, maxid, n)))
htrc("GetMaxValue: %s", Msg);
return (int)m;
} // end of GetMaxValue } // end of GetMaxValue
/***********************************************************************/
/* Reset the JVM library. */
/***********************************************************************/
void JDBConn::ResetJVM(void)
{
if (LibJvm) {
#if defined(__WIN__)
FreeLibrary((HMODULE)LibJvm);
#else // !__WIN__
dlclose(LibJvm);
#endif // !__WIN__
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
} // endif LibJvm
} // end of ResetJVM
/***********************************************************************/
/* Dynamically link the JVM library. */
/* The purpose of this function is to allow using the CONNECT plugin */
/* for other table types when the Java JDK is not installed. */
/***********************************************************************/
bool JDBConn::GetJVM(PGLOBAL g)
{
if (!LibJvm) {
char soname[512];
#if defined(__WIN__)
if (JvmPath)
strcat(strcpy(soname, JvmPath), "\\jvm.dll");
else
strcpy(soname, "jvm.dll");
// Load the desired shared library
if (!(LibJvm = LoadLibrary(soname))) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
} else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_CreateJavaVM"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
} else if (!(GetCreatedJavaVMs = (GETJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_GetCreatedJavaVMs"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
#if defined(_DEBUG)
} else if (!(GetDefaultJavaVMInitArgs = (GETDEF)GetProcAddress((HINSTANCE)LibJvm,
"JNI_GetDefaultJavaVMInitArgs"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(),
"JNI_GetDefaultJavaVMInitArgs");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
#else // !__WIN__
const char *error = NULL;
if (JvmPath)
strcat(strcpy(soname, JvmPath), "/libjvm.so");
else
strcpy(soname, "libjvm.so");
// Load the desired shared library
if (!(LibJvm = dlopen(soname, RTLD_LAZY))) {
error = dlerror();
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
} else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
} else if (!(GetCreatedJavaVMs = (GETJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
#if defined(_DEBUG)
} else if (!(GetDefaultJavaVMInitArgs = (GETDEF)dlsym(LibJvm,
"JNI_GetDefaultJavaVMInitArgs"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetDefaultJavaVMInitArgs", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
#endif // !__WIN__
} // endif LibJvm
return LibJvm == NULL;
} // end of GetJVM
/***********************************************************************/ /***********************************************************************/
/* Open: connect to a data source. */ /* Open: connect to a data source. */
/***********************************************************************/ /***********************************************************************/
int JDBConn::Open(PSZ jpath, PJPARM sop) int JDBConn::Open(PJPARM sop)
{ {
bool err = false;
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
PSTRG jpop = new(g) STRING(g, 512, "-Djava.class.path=");
// Link or check whether jvm library was linked
if (GetJVM(g))
return RC_FX;
// Firstly check whether the jvm was already created
JavaVM* jvms[1];
jsize jsz;
jint rc = GetCreatedJavaVMs(jvms, 1, &jsz);
if (rc == JNI_OK && jsz == 1) {
// jvm already existing
jvm = jvms[0];
rc = jvm->AttachCurrentThread((void**)&env, nullptr);
if (rc != JNI_OK) {
strcpy(g->Message, "Cannot attach jvm to the current thread");
return RC_FX;
} // endif rc
} else {
/*******************************************************************/
/* Create a new jvm */
/*******************************************************************/
PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path=.");
char *cp = NULL;
char sep; char sep;
#if defined(__WIN__) #if defined(__WIN__)
sep = ';'; sep = ';';
#define N 1
//#define N 2
//#define N 3
#else #else
sep = ':'; sep = ':';
#define N 1
#endif #endif
if (sop) {
m_Driver = sop->Driver;
m_Url = sop->Url;
m_User = sop->User;
m_Pwd = sop->Pwd;
m_Scrollable = sop->Scrollable;
m_RowsetSize = sop->Fsize;
//m_LoginTimeout = sop->Cto;
//m_QueryTimeout = sop->Qto;
//m_UseCnc = sop->UseCnc;
} // endif sop
//================== prepare loading of Java VM ============================ //================== prepare loading of Java VM ============================
JavaVMInitArgs vm_args; // Initialization arguments JavaVMInitArgs vm_args; // Initialization arguments
JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options JavaVMOption* options = new JavaVMOption[N]; // JVM invocation options
// where to find java .class // where to find java .class
jpop->Append(getenv("CLASSPATH")); if (ClassPath && *ClassPath) {
jpop->Append(sep);
jpop->Append(ClassPath);
} // endif ClassPath
if (jpath) { if ((cp = getenv("CLASSPATH"))) {
jpop->Append(sep); jpop->Append(sep);
jpop->Append(jpath); jpop->Append(cp);
} // endif jpath } // endif cp
if (trace) {
htrc("ClassPath=%s\n", ClassPath);
htrc("CLASSPATH=%s\n", cp);
htrc("%s\n", jpop->GetStr());
} // endif trace
options[0].optionString = jpop->GetStr(); options[0].optionString = jpop->GetStr();
//options[1].optionString = "-verbose:jni"; #if N == 2
options[1].optionString = "-Xcheck:jni";
#endif
#if N == 3
options[1].optionString = "-Xms256M";
options[2].optionString = "-Xmx512M";
#endif
#if defined(_DEBUG)
vm_args.version = JNI_VERSION_1_2; // minimum Java version
rc = GetDefaultJavaVMInitArgs(&vm_args);
#else
vm_args.version = JNI_VERSION_1_6; // minimum Java version vm_args.version = JNI_VERSION_1_6; // minimum Java version
vm_args.nOptions = 1; // number of options #endif // _DEBUG
vm_args.nOptions = N; // number of options
vm_args.options = options; vm_args.options = options;
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
//=============== load and initialize Java VM and JNI interface ============= //=============== load and initialize Java VM and JNI interface =============
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !! rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
delete options; // we then no longer need the initialisation options. delete options; // we then no longer need the initialisation options.
switch (rc) { switch (rc) {
...@@ -904,28 +991,7 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) ...@@ -904,28 +991,7 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
return RC_FX; return RC_FX;
case JNI_EEXIST: case JNI_EEXIST:
strcpy(g->Message, "VM already created"); strcpy(g->Message, "VM already created");
{
JavaVM* jvms[1];
jsize jsz;
rc = JNI_GetCreatedJavaVMs(jvms, 1, &jsz);
if (rc == JNI_OK && jsz == 1) {
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6;
args.name = NULL;
args.group = NULL;
jvm = jvms[0];
rc = jvm->AttachCurrentThread((void**)&env, &args);
} // endif rc
} // end of block
if (rc == JNI_OK)
break;
else
return RC_FX; return RC_FX;
case JNI_EINVAL: case JNI_EINVAL:
strcpy(g->Message, "Invalid arguments"); strcpy(g->Message, "Invalid arguments");
return RC_FX; return RC_FX;
...@@ -934,23 +1000,65 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) ...@@ -934,23 +1000,65 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
return RC_FX; return RC_FX;
} // endswitch rc } // endswitch rc
} // endif rc
//=============== Display JVM version ======================================= //=============== Display JVM version =======================================
//jint ver = env->GetVersion(); #if defined(_DEBUG)
//cout << ((ver>>16)&0x0f) << "."<<(ver&0x0f) << endl; jint ver = env->GetVersion();
printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f));
#endif //_DEBUG
// try to find the JdbcInterface class // try to find the java wrapper class
jdi = env->FindClass("JdbcInterface"); jdi = env->FindClass(Wrapper);
if (jdi == nullptr) { if (jdi == nullptr) {
strcpy(g->Message, "ERROR: class JdbcInterface not found !"); sprintf(g->Message, "ERROR: class %s not found!", Wrapper);
return RC_FX; return RC_FX;
} // endif jdi } // endif jdi
#if 0 // Suppressed because it does not make any usable change
if (b && jpath && *jpath) {
// Try to add that path the the jvm class path
jmethodID alp = env->GetStaticMethodID(jdi, "addLibraryPath",
"(Ljava/lang/String;)I");
if (alp == nullptr) {
env->ExceptionDescribe();
env->ExceptionClear();
} else {
char *msg;
jstring path = env->NewStringUTF(jpath);
rc = env->CallStaticIntMethod(jdi, alp, path);
if ((msg = Check(rc))) {
strcpy(g->Message, msg);
env->DeleteLocalRef(path);
return RC_FX;
} else switch (rc) {
case JNI_OK:
printf("jpath added\n");
break;
case JNI_EEXIST:
printf("jpath already exist\n");
break;
case JNI_ERR:
default:
strcpy(g->Message, "Error adding jpath");
env->DeleteLocalRef(path);
return RC_FX;
} // endswitch rc
env->DeleteLocalRef(path);
} // endif alp
} // endif jpath
#endif // 0
// if class found, continue // if class found, continue
jmethodID ctor = env->GetMethodID(jdi, "<init>", "()V"); jmethodID ctor = env->GetMethodID(jdi, "<init>", "()V");
if (ctor == nullptr) { if (ctor == nullptr) {
strcpy(g->Message, "ERROR: JdbcInterface constructor not found !"); sprintf(g->Message, "ERROR: %s constructor not found!", Wrapper);
return RC_FX; return RC_FX;
} else } else
job = env->NewObject(jdi, ctor); job = env->NewObject(jdi, ctor);
...@@ -959,26 +1067,41 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) ...@@ -959,26 +1067,41 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
// we can then search for the method we want to call, // we can then search for the method we want to call,
// and invoke it for the object: // and invoke it for the object:
if (job == nullptr) { if (job == nullptr) {
strcpy(g->Message, "JdbcInterface class object not constructed !"); sprintf(g->Message, "%s class object not constructed!", Wrapper);
return RC_FX; return RC_FX;
} // endif job } // endif job
if (!sop) // DRIVER catalog table errid = env->GetMethodID(jdi, "GetErrmsg", "()Ljava/lang/String;");
return RC_OK;
jmethodID cid = env->GetMethodID(jdi, "JdbcConnect", "([Ljava/lang/String;IZ)I");
if (env->ExceptionCheck()) { if (env->ExceptionCheck()) {
strcpy(g->Message, "ERROR: method JdbcConnect() not found!"); strcpy(g->Message, "ERROR: method GetErrmsg() not found!");
env->ExceptionDescribe(); env->ExceptionDescribe();
env->ExceptionClear(); env->ExceptionClear();
return RC_FX; return RC_FX;
} // endif Check } // endif Check
if (!sop) // DRIVER catalog table
return RC_OK;
jmethodID cid = nullptr;
if (gmID(g, cid, "JdbcConnect", "([Ljava/lang/String;IZ)I"))
return RC_FX;
// Build the java string array // Build the java string array
jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4 jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4
env->FindClass("java/lang/String"), NULL); // Strings env->FindClass("java/lang/String"), NULL); // Strings
m_Driver = sop->Driver;
m_Url = sop->Url;
m_User = sop->User;
m_Pwd = sop->Pwd;
m_Scrollable = sop->Scrollable;
m_RowsetSize = sop->Fsize;
//m_LoginTimeout = sop->Cto;
//m_QueryTimeout = sop->Qto;
//m_UseCnc = sop->UseCnc;
// change some elements // change some elements
if (m_Driver) if (m_Driver)
env->SetObjectArrayElement(parms, 0, env->NewStringUTF(m_Driver)); env->SetObjectArrayElement(parms, 0, env->NewStringUTF(m_Driver));
...@@ -994,23 +1117,17 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) ...@@ -994,23 +1117,17 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
// call method // call method
rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable); rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable);
err = Check(rc);
env->DeleteLocalRef(parms); // Not used anymore
// Not used anymore if (err) {
env->DeleteLocalRef(parms); sprintf(g->Message, "Connecting: %s rc=%d", Msg, (int)rc);
if (rc != (jint)0) {
strcpy(g->Message, "Connection failed");
return RC_FX; return RC_FX;
} // endif rc } // endif Msg
typid = env->GetMethodID(jdi, "ColumnType", "(ILjava/lang/String;)I"); if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I"))
if (env->ExceptionCheck()) {
strcpy(g->Message, "ERROR: method ColumnType() not found!");
env->ExceptionDescribe();
env->ExceptionClear();
return RC_FX; return RC_FX;
} else else
m_Opened = true; m_Opened = true;
return RC_OK; return RC_OK;
...@@ -1021,43 +1138,37 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) ...@@ -1021,43 +1138,37 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
/***********************************************************************/ /***********************************************************************/
int JDBConn::ExecSQLcommand(char *sql) int JDBConn::ExecSQLcommand(char *sql)
{ {
int rc = RC_NF; int rc;
jint n; jint n;
jstring qry; jstring qry;
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
if (xid == nullptr) {
// Get the methods used to execute a query and get the result // Get the methods used to execute a query and get the result
xid = env->GetMethodID(jdi, "Execute", "(Ljava/lang/String;)I"); if (gmID(g, xid, "Execute", "(Ljava/lang/String;)I") ||
gmID(g, grs, "GetResult", "()I"))
if (xid == nullptr) {
strcpy(g->Message, "Cannot find method Execute");
return RC_FX;
} else
grs = env->GetMethodID(jdi, "GetResult", "()I");
if (grs == nullptr) {
strcpy(g->Message, "Cannot find method GetResult");
return RC_FX; return RC_FX;
} // endif grs
} // endif xid
qry = env->NewStringUTF(sql); qry = env->NewStringUTF(sql);
n = env->CallIntMethod(job, xid, qry); n = env->CallIntMethod(job, xid, qry);
env->DeleteLocalRef(qry); env->DeleteLocalRef(qry);
if (n < 0) { if (Check(n)) {
sprintf(g->Message, "Error executing %s", sql); sprintf(g->Message, "Execute: %s", Msg);
return RC_FX; return RC_FX;
} // endif n } // endif n
if ((m_Ncol = env->CallIntMethod(job, grs))) { m_Ncol = env->CallIntMethod(job, grs);
if (Check(m_Ncol)) {
sprintf(g->Message, "GetResult: %s", Msg);
rc = RC_FX;
} else if (m_Ncol) {
strcpy(g->Message, "Result set column number"); strcpy(g->Message, "Result set column number");
rc = RC_OK; // A result set was returned rc = RC_OK; // A result set was returned
} else { } else {
m_Aff = (int)n; // Affected rows m_Aff = (int)n; // Affected rows
strcpy(g->Message, "Affected rows"); strcpy(g->Message, "Affected rows");
rc = RC_NF;
} // endif ncol } // endif ncol
return rc; return rc;
...@@ -1068,44 +1179,29 @@ int JDBConn::ExecSQLcommand(char *sql) ...@@ -1068,44 +1179,29 @@ int JDBConn::ExecSQLcommand(char *sql)
/***********************************************************************/ /***********************************************************************/
int JDBConn::Fetch(int pos) int JDBConn::Fetch(int pos)
{ {
jint rc; jint rc = JNI_ERR;
PGLOBAL& g = m_G;
if (m_Full) // Result set has one row if (m_Full) // Result set has one row
return 1; return 1;
if (pos) { if (pos) {
if (!m_Scrollable) { if (!m_Scrollable) {
strcpy(m_G->Message, "Cannot fetch(pos) if FORWARD ONLY"); strcpy(g->Message, "Cannot fetch(pos) if FORWARD ONLY");
return -1; return rc;
} else if (fetchid == nullptr) { } else if (gmID(m_G, fetchid, "Fetch", "(I)Z"))
fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); return rc;
if (fetchid == nullptr) {
strcpy(m_G->Message, "Cannot find method Fetch");
return -1;
} // endif fetchid
} // endif's
if (env->CallBooleanMethod(job, fetchid, pos)) if (env->CallBooleanMethod(job, fetchid, pos))
rc = m_Rows; rc = m_Rows;
else
rc = -1;
} else { } else {
if (readid == nullptr) { if (gmID(g, readid, "ReadNext", "()I"))
readid = env->GetMethodID(jdi, "ReadNext", "()I"); return rc;
if (readid == nullptr) {
strcpy(m_G->Message, "Cannot find method ReadNext");
return -1;
} // endif readid
} // endif readid
rc = env->CallBooleanMethod(job, readid); rc = env->CallBooleanMethod(job, readid);
if (rc >= 0) { if (!Check(rc)) {
if (rc == 0) if (rc == 0)
m_Full = (m_Fetch == 1); m_Full = (m_Fetch == 1);
else else
...@@ -1113,7 +1209,7 @@ int JDBConn::Fetch(int pos) ...@@ -1113,7 +1209,7 @@ int JDBConn::Fetch(int pos)
m_Rows += (int)rc; m_Rows += (int)rc;
} else } else
strcpy(m_G->Message, "Error fetching next row"); sprintf(g->Message, "Fetch: %s", Msg);
} // endif pos } // endif pos
...@@ -1130,15 +1226,8 @@ int JDBConn::Rewind(char *sql) ...@@ -1130,15 +1226,8 @@ int JDBConn::Rewind(char *sql)
if (m_Full) if (m_Full)
rbuf = m_Rows; // No need to "rewind" rbuf = m_Rows; // No need to "rewind"
else if (m_Scrollable) { else if (m_Scrollable) {
if (fetchid == nullptr) { if (gmID(m_G, fetchid, "Fetch", "(I)Z"))
fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z");
if (fetchid == nullptr) {
strcpy(m_G->Message, "Cannot find method Fetch");
return -1; return -1;
} // endif readid
} // endif readid
jboolean b = env->CallBooleanMethod(job, fetchid, 0); jboolean b = env->CallBooleanMethod(job, fetchid, 0);
...@@ -1156,14 +1245,16 @@ void JDBConn::Close() ...@@ -1156,14 +1245,16 @@ void JDBConn::Close()
{ {
if (m_Opened) { if (m_Opened) {
jint rc; jint rc;
jmethodID did = env->GetMethodID(jdi, "JdbcDisconnect", "()I"); jmethodID did = nullptr;
if (did == nullptr) if (gmID(m_G, did, "JdbcDisconnect", "()I"))
printf("ERROR: method JdbcDisconnect() not found !"); printf("%s\n", Msg);
else else if (Check(env->CallIntMethod(job, did)))
rc = env->CallIntMethod(job, did); printf("jdbcDisconnect: %s\n", Msg);
if ((rc = jvm->DetachCurrentThread()) != JNI_OK)
printf("DetachCurrentThread: rc=%d\n", (int)rc);
rc = jvm->DetachCurrentThread();
//rc = jvm->DestroyJavaVM(); //rc = jvm->DestroyJavaVM();
m_Opened = false; m_Opened = false;
} // endif m_Opened } // endif m_Opened
...@@ -1180,8 +1271,6 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1180,8 +1271,6 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
jlong dtv; jlong dtv;
jstring cn, jn = nullptr; jstring cn, jn = nullptr;
jobject dob; jobject dob;
jthrowable exc;
jmethodID fldid = nullptr;
if (rank == 0) if (rank == 0)
if (!name || (jn = env->NewStringUTF(name)) == nullptr) { if (!name || (jn = env->NewStringUTF(name)) == nullptr) {
...@@ -1189,16 +1278,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1189,16 +1278,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif name } // endif name
// Returns 666 is case of error
ctyp = env->CallIntMethod(job, typid, rank, jn); ctyp = env->CallIntMethod(job, typid, rank, jn);
if ((exc = env->ExceptionOccurred()) != nullptr) { if (Check((ctyp == 666) ? -1 : 1)) {
jboolean isCopy = false; sprintf(g->Message, "Getting ctyp: %s", Msg);
jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
jstring s = (jstring)env->CallObjectMethod(exc, tid);
const char* utf = env->GetStringUTFChars(s, &isCopy);
sprintf(g->Message, "SetColumnValue: %s", utf);
env->DeleteLocalRef(s);
env->ExceptionClear();
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif Check } // endif Check
...@@ -1206,11 +1290,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1206,11 +1290,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
case 12: // VARCHAR case 12: // VARCHAR
case -1: // LONGVARCHAR case -1: // LONGVARCHAR
case 1: // CHAR case 1: // CHAR
fldid = env->GetMethodID(jdi, "StringField", if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;")) {
"(ILjava/lang/String;)Ljava/lang/String;"); cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn);
if (fldid != nullptr) {
cn = (jstring)env->CallObjectMethod(job, fldid, (jint)rank, jn);
if (cn) { if (cn) {
const char *field = env->GetStringUTFChars(cn, (jboolean)false); const char *field = env->GetStringUTFChars(cn, (jboolean)false);
...@@ -1227,30 +1308,26 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1227,30 +1308,26 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
case 4: // INTEGER case 4: // INTEGER
case 5: // SMALLINT case 5: // SMALLINT
case -6: // TINYINT case -6: // TINYINT
fldid = env->GetMethodID(jdi, "IntField", "(ILjava/lang/String;)I"); case -7: // BIT
if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I"))
if (fldid != nullptr) val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn));
val->SetValue((int)env->CallIntMethod(job, fldid, rank, jn));
else else
val->Reset(); val->Reset();
break; break;
case 8: // DOUBLE case 8: // DOUBLE
case 2: // NUMERIC
case 3: // DECIMAL case 3: // DECIMAL
fldid = env->GetMethodID(jdi, "DoubleField", "(ILjava/lang/String;)D"); if (!gmID(g, dblfldid, "DoubleField", "(ILjava/lang/String;)D"))
val->SetValue((double)env->CallDoubleMethod(job, dblfldid, rank, jn));
if (fldid != nullptr)
val->SetValue((double)env->CallDoubleMethod(job, fldid, rank, jn));
else else
val->Reset(); val->Reset();
break; break;
case 7: // REAL case 7: // REAL
case 6: // FLOAT case 6: // FLOAT
fldid = env->GetMethodID(jdi, "FloatField", "(ILjava/lang/String;)F"); if (!gmID(g, fltfldid, "FloatField", "(ILjava/lang/String;)F"))
val->SetValue((float)env->CallFloatMethod(job, fltfldid, rank, jn));
if (fldid != nullptr)
val->SetValue((float)env->CallFloatMethod(job, fldid, rank, jn));
else else
val->Reset(); val->Reset();
...@@ -1258,11 +1335,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1258,11 +1335,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
case 91: // DATE case 91: // DATE
case 92: // TIME case 92: // TIME
case 93: // TIMESTAMP case 93: // TIMESTAMP
fldid = env->GetMethodID(jdi, "TimestampField", if (!gmID(g, datfldid, "TimestampField",
"(ILjava/lang/String;)Ljava/sql/Timestamp;"); "(ILjava/lang/String;)Ljava/sql/Timestamp;")) {
dob = env->CallObjectMethod(job, datfldid, (jint)rank, jn);
if (fldid != nullptr) {
dob = env->CallObjectMethod(job, fldid, (jint)rank, jn);
if (dob) { if (dob) {
jclass jts = env->FindClass("java/sql/Timestamp"); jclass jts = env->FindClass("java/sql/Timestamp");
...@@ -1288,10 +1363,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1288,10 +1363,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
break; break;
case -5: // BIGINT case -5: // BIGINT
fldid = env->GetMethodID(jdi, "BigintField", "(ILjava/lang/String;)J"); if (!gmID(g, bigfldid, "BigintField", "(ILjava/lang/String;)J"))
val->SetValue((long long)env->CallLongMethod(job, bigfldid, (jint)rank, jn));
if (fldid != nullptr)
val->SetValue((long long)env->CallLongMethod(job, fldid, (jint)rank, jn));
else else
val->Reset(); val->Reset();
...@@ -1301,10 +1374,21 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1301,10 +1374,21 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
break; break;
case java.sql.Types.BOOLEAN: case java.sql.Types.BOOLEAN:
System.out.print(jdi.BooleanField(i)); */ System.out.print(jdi.BooleanField(i)); */
case 0: // NULL
val->SetNull(true);
// passthru
default: default:
val->Reset(); val->Reset();
} // endswitch Type } // endswitch Type
if (Check()) {
if (rank == 0)
env->DeleteLocalRef(jn);
sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", Msg, rank, (int)ctyp);
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif Check
if (rank == 0) if (rank == 0)
env->DeleteLocalRef(jn); env->DeleteLocalRef(jn);
...@@ -1315,21 +1399,22 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1315,21 +1399,22 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
/***********************************************************************/ /***********************************************************************/
bool JDBConn::PrepareSQL(char *sql) bool JDBConn::PrepareSQL(char *sql)
{ {
if (prepid == nullptr) { bool b = true;
prepid = env->GetMethodID(jdi, "CreatePrepStmt", "(Ljava/lang/String;)Z"); PGLOBAL& g = m_G;
if (prepid == nullptr) {
strcpy(m_G->Message, "Cannot find method CreatePrepStmt");
return true;
} // endif prepid
} // endif prepid
if (!gmID(g, prepid, "CreatePrepStmt", "(Ljava/lang/String;)I")) {
// Create the prepared statement // Create the prepared statement
jstring qry = env->NewStringUTF(sql); jstring qry = env->NewStringUTF(sql);
jboolean b = env->CallBooleanMethod(job, prepid, qry);
if (Check(env->CallBooleanMethod(job, prepid, qry)))
sprintf(g->Message, "CreatePrepStmt: %s", Msg);
else
b = false;
env->DeleteLocalRef(qry); env->DeleteLocalRef(qry);
return (bool)b; } // endif prepid
return b;
} // end of PrepareSQL } // end of PrepareSQL
/***********************************************************************/ /***********************************************************************/
...@@ -1337,34 +1422,27 @@ bool JDBConn::PrepareSQL(char *sql) ...@@ -1337,34 +1422,27 @@ bool JDBConn::PrepareSQL(char *sql)
/***********************************************************************/ /***********************************************************************/
int JDBConn::ExecuteQuery(char *sql) int JDBConn::ExecuteQuery(char *sql)
{ {
int rc = RC_FX;
jint ncol; jint ncol;
jstring qry; jstring qry;
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
if (xqid == nullptr) {
// Get the methods used to execute a query and get the result // Get the methods used to execute a query and get the result
xqid = env->GetMethodID(jdi, "ExecuteQuery", "(Ljava/lang/String;)I"); if (!gmID(g, xqid, "ExecuteQuery", "(Ljava/lang/String;)I")) {
if (xqid == nullptr) {
strcpy(g->Message, "Cannot find method ExecuteQuery");
return RC_FX;
} // endif !xqid
} // endif xqid
qry = env->NewStringUTF(sql); qry = env->NewStringUTF(sql);
ncol = env->CallIntMethod(job, xqid, qry); ncol = env->CallIntMethod(job, xqid, qry);
env->DeleteLocalRef(qry);
if (ncol < 0) { if (!Check(ncol)) {
sprintf(g->Message, "Error executing %s: ncol = %d", sql, ncol);
return RC_FX;
} else {
m_Ncol = (int)ncol; m_Ncol = (int)ncol;
m_Aff = 0; // Affected rows m_Aff = 0; // Affected rows
} // endif ncol rc = RC_OK;
} else
sprintf(g->Message, "ExecuteQuery: %s", Msg);
return RC_OK; env->DeleteLocalRef(qry);
} // endif xqid
return rc;
} // end of ExecuteQuery } // end of ExecuteQuery
/***********************************************************************/ /***********************************************************************/
...@@ -1372,34 +1450,27 @@ int JDBConn::ExecuteQuery(char *sql) ...@@ -1372,34 +1450,27 @@ int JDBConn::ExecuteQuery(char *sql)
/***********************************************************************/ /***********************************************************************/
int JDBConn::ExecuteUpdate(char *sql) int JDBConn::ExecuteUpdate(char *sql)
{ {
int rc = RC_FX;
jint n; jint n;
jstring qry; jstring qry;
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
if (xuid == nullptr) {
// Get the methods used to execute a query and get the affected rows // Get the methods used to execute a query and get the affected rows
xuid = env->GetMethodID(jdi, "ExecuteUpdate", "(Ljava/lang/String;)I"); if (!gmID(g, xuid, "ExecuteUpdate", "(Ljava/lang/String;)I")) {
if (xuid == nullptr) {
strcpy(g->Message, "Cannot find method ExecuteUpdate");
return RC_FX;
} // endif !xuid
} // endif xuid
qry = env->NewStringUTF(sql); qry = env->NewStringUTF(sql);
n = env->CallIntMethod(job, xuid, qry); n = env->CallIntMethod(job, xuid, qry);
env->DeleteLocalRef(qry);
if (n < 0) { if (!Check(n)) {
sprintf(g->Message, "Error executing %s: n = %d", sql, n);
return RC_FX;
} else {
m_Ncol = 0; m_Ncol = 0;
m_Aff = (int)n; // Affected rows m_Aff = (int)n; // Affected rows
} // endif n rc = RC_OK;
} else
sprintf(g->Message, "ExecuteUpdate: %s n=%d", Msg, n);
return RC_OK; env->DeleteLocalRef(qry);
} // endif xuid
return rc;
} // end of ExecuteUpdate } // end of ExecuteUpdate
/***********************************************************************/ /***********************************************************************/
...@@ -1432,32 +1503,21 @@ int JDBConn::ExecuteSQL(void) ...@@ -1432,32 +1503,21 @@ int JDBConn::ExecuteSQL(void)
int rc = RC_FX; int rc = RC_FX;
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
if (xpid == nullptr) {
// Get the methods used to execute a prepared statement // Get the methods used to execute a prepared statement
xpid = env->GetMethodID(jdi, "ExecutePrep", "()I"); if (!gmID(g, xpid, "ExecutePrep", "()I")) {
if (xpid == nullptr) {
strcpy(g->Message, "Cannot find method ExecutePrep");
return rc;
} // endif xpid
} // endif xpid
jint n = env->CallIntMethod(job, xpid); jint n = env->CallIntMethod(job, xpid);
switch ((int)n) { if (n == -3)
case -1:
case -2:
strcpy(g->Message, "Exception error thrown while executing SQL");
break;
case -3:
strcpy(g->Message, "SQL statement is not prepared"); strcpy(g->Message, "SQL statement is not prepared");
break; else if (Check(n))
default: sprintf(g->Message, "ExecutePrep: %s", Msg);
else {
m_Aff = (int)n; m_Aff = (int)n;
rc = RC_OK; rc = RC_OK;
} // endswitch n } // endswitch n
} // endif xpid
return rc; return rc;
} // end of ExecuteSQL } // end of ExecuteSQL
...@@ -1467,7 +1527,7 @@ int JDBConn::ExecuteSQL(void) ...@@ -1467,7 +1527,7 @@ int JDBConn::ExecuteSQL(void)
bool JDBConn::SetParam(JDBCCOL *colp) bool JDBConn::SetParam(JDBCCOL *colp)
{ {
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
int rc = false; bool rc = false;
PVAL val = colp->GetValue(); PVAL val = colp->GetValue();
jint n, i = (jint)colp->GetRank(); jint n, i = (jint)colp->GetRank();
jshort s; jshort s;
...@@ -1477,63 +1537,42 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1477,63 +1537,42 @@ bool JDBConn::SetParam(JDBCCOL *colp)
jclass dat; jclass dat;
jobject datobj; jobject datobj;
jstring jst = nullptr; jstring jst = nullptr;
jthrowable exc;
jmethodID dtc, setid = nullptr; jmethodID dtc, setid = nullptr;
switch (val->GetType()) { switch (val->GetType()) {
case TYPE_STRING: case TYPE_STRING:
setid = env->GetMethodID(jdi, "SetStringParm", "(ILjava/lang/String;)V"); if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V"))
if (setid == nullptr) {
strcpy(g->Message, "Cannot fing method SetStringParm");
return true; return true;
} // endif setid
jst = env->NewStringUTF(val->GetCharValue()); jst = env->NewStringUTF(val->GetCharValue());
env->CallVoidMethod(job, setid, i, jst); env->CallVoidMethod(job, setid, i, jst);
break; break;
case TYPE_INT: case TYPE_INT:
setid = env->GetMethodID(jdi, "SetIntParm", "(II)V"); if (gmID(g, setid, "SetIntParm", "(II)V"))
if (setid == nullptr) {
strcpy(g->Message, "Cannot fing method SetIntParm");
return true; return true;
} // endif setid
n = (jint)val->GetIntValue(); n = (jint)val->GetIntValue();
env->CallVoidMethod(job, setid, i, n); env->CallVoidMethod(job, setid, i, n);
break; break;
case TYPE_TINY: case TYPE_TINY:
case TYPE_SHORT: case TYPE_SHORT:
setid = env->GetMethodID(jdi, "SetShortParm", "(IS)V"); if (gmID(g, setid, "SetShortParm", "(IS)V"))
if (setid == nullptr) {
strcpy(g->Message, "Cannot fing method SetShortParm");
return true; return true;
} // endif setid
s = (jshort)val->GetShortValue(); s = (jshort)val->GetShortValue();
env->CallVoidMethod(job, setid, i, s); env->CallVoidMethod(job, setid, i, s);
break; break;
case TYPE_BIGINT: case TYPE_BIGINT:
setid = env->GetMethodID(jdi, "SetBigintParm", "(IJ)V"); if (gmID(g, setid, "SetBigintParm", "(IJ)V"))
if (setid == nullptr) {
strcpy(g->Message, "Cannot fing method SetBigintParm");
return true; return true;
} // endif setid
lg = (jlong)val->GetBigintValue(); lg = (jlong)val->GetBigintValue();
env->CallVoidMethod(job, setid, i, lg); env->CallVoidMethod(job, setid, i, lg);
break; break;
case TYPE_DOUBLE: case TYPE_DOUBLE:
case TYPE_DECIM: case TYPE_DECIM:
setid = env->GetMethodID(jdi, "SetDoubleParm", "(ID)V"); if (gmID(g, setid, "SetDoubleParm", "(ID)V"))
if (setid == nullptr) {
strcpy(g->Message, "Cannot fing method SetDoubleParm");
return true; return true;
} // endif setid
d = (jdouble)val->GetFloatValue(); d = (jdouble)val->GetFloatValue();
env->CallVoidMethod(job, setid, i, d); env->CallVoidMethod(job, setid, i, d);
...@@ -1552,11 +1591,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1552,11 +1591,8 @@ bool JDBConn::SetParam(JDBCCOL *colp)
if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) { if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) {
strcpy(g->Message, "Cannot make Timestamp object"); strcpy(g->Message, "Cannot make Timestamp object");
return true; return true;
} else if ((setid = env->GetMethodID(jdi, "SetTimestampParm", } else if (gmID(g, setid, "SetTimestampParm", "(ILjava/sql/Timestamp;)V"))
"(ILjava/sql/Timestamp;)V")) == nullptr) {
strcpy(g->Message, "Cannot find method SetTimestampParm");
return true; return true;
} // endif setid
env->CallVoidMethod(job, setid, i, datobj); env->CallVoidMethod(job, setid, i, datobj);
break; break;
...@@ -1565,16 +1601,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1565,16 +1601,10 @@ bool JDBConn::SetParam(JDBCCOL *colp)
return true; return true;
} // endswitch Type } // endswitch Type
if ((exc = env->ExceptionOccurred()) != nullptr) { if (Check()) {
jboolean isCopy = false; sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), Msg);
jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
jstring s = (jstring)env->CallObjectMethod(exc, tid);
const char* utf = env->GetStringUTFChars(s, &isCopy);
sprintf(g->Message, "SetParam: %s", utf);
env->DeleteLocalRef(s);
env->ExceptionClear();
rc = true; rc = true;
} // endif exc } // endif msg
if (jst) if (jst)
env->DeleteLocalRef(jst); env->DeleteLocalRef(jst);
...@@ -1638,14 +1668,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1638,14 +1668,10 @@ bool JDBConn::SetParam(JDBCCOL *colp)
int i, n, size; int i, n, size;
PCOLRES crp; PCOLRES crp;
jstring js; jstring js;
jmethodID gdid = env->GetMethodID(jdi, "GetDrivers", "([Ljava/lang/String;I)I"); jmethodID gdid = nullptr;
if (env->ExceptionCheck()) { if (gmID(m_G, gdid, "GetDrivers", "([Ljava/lang/String;I)I"))
strcpy(m_G->Message, "ERROR: method GetDrivers() not found!");
env->ExceptionDescribe();
env->ExceptionClear();
return true; return true;
} // endif Check
// Build the java string array // Build the java string array
jobjectArray s = env->NewObjectArray(4 * qrp->Maxres, jobjectArray s = env->NewObjectArray(4 * qrp->Maxres,
...@@ -1694,10 +1720,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1694,10 +1720,10 @@ bool JDBConn::SetParam(JDBCCOL *colp)
int len, qcol = 5; int len, qcol = 5;
PQRYRES qrp = NULL; PQRYRES qrp = NULL;
PCOLRES crp; PCOLRES crp;
USHORT i; ushort i;
jint *n; jint *n = nullptr;
jstring label; jstring label;
jmethodID colid; jmethodID colid = nullptr;
int rc = ExecSQLcommand(src); int rc = ExecSQLcommand(src);
if (rc == RC_NF) { if (rc == RC_NF) {
...@@ -1710,20 +1736,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1710,20 +1736,8 @@ bool JDBConn::SetParam(JDBCCOL *colp)
return NULL; return NULL;
} // endif's } // endif's
colid = env->GetMethodID(jdi, "ColumnDesc", "(I[I)Ljava/lang/String;"); if (gmID(g, colid, "ColumnDesc", "(I[I)Ljava/lang/String;"))
if (colid == nullptr) {
strcpy(m_G->Message, "ERROR: method ColumnDesc() not found!");
return NULL; return NULL;
} // endif colid
// Build the java string array
jintArray val = env->NewIntArray(4);
if (val == nullptr) {
strcpy(m_G->Message, "Cannot allocate jint array");
return NULL;
} // endif colid
// Get max column name length // Get max column name length
len = GetMaxValue(5); len = GetMaxValue(5);
...@@ -1744,11 +1758,28 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1744,11 +1758,28 @@ bool JDBConn::SetParam(JDBCCOL *colp)
case 5: crp->Name = "Nullable"; break; case 5: crp->Name = "Nullable"; break;
} // endswitch i } // endswitch i
// Build the java string array
jintArray val = env->NewIntArray(4);
if (val == nullptr) {
strcpy(m_G->Message, "Cannot allocate jint array");
return NULL;
} // endif colid
/************************************************************************/ /************************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/************************************************************************/ /************************************************************************/
for (i = 0; i < m_Ncol; i++) { for (i = 0; i < m_Ncol; i++) {
label = (jstring)env->CallObjectMethod(job, colid, i + 1, val); if (!(label = (jstring)env->CallObjectMethod(job, colid, i + 1, val))) {
if (Check())
sprintf(g->Message, "ColumnDesc: %s", Msg);
else
strcpy(g->Message, "No result metadata");
env->ReleaseIntArrayElements(val, n, 0);
return NULL;
} // endif label
name = env->GetStringUTFChars(label, (jboolean)false); name = env->GetStringUTFChars(label, (jboolean)false);
crp = qrp->Colresp; // Column_Name crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue((char*)name, i); crp->Kdata->SetValue((char*)name, i);
...@@ -1766,7 +1797,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1766,7 +1797,6 @@ bool JDBConn::SetParam(JDBCCOL *colp)
/* Cleanup */ /* Cleanup */
env->ReleaseIntArrayElements(val, n, 0); env->ReleaseIntArrayElements(val, n, 0);
Close();
/************************************************************************/ /************************************************************************/
/* Return the result pointer for use by GetData routines. */ /* Return the result pointer for use by GetData routines. */
...@@ -1879,10 +1909,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1879,10 +1909,10 @@ bool JDBConn::SetParam(JDBCCOL *colp)
int JDBConn::GetCatInfo(JCATPARM *cap) int JDBConn::GetCatInfo(JCATPARM *cap)
{ {
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
void *buffer; // void *buffer;
int i; int i, ncol;
PSZ fnc = "Unknown"; PSZ fnc = "Unknown";
uint n, ncol; uint n;
short len, tp; short len, tp;
int crow = 0; int crow = 0;
PQRYRES qrp = cap->Qrp; PQRYRES qrp = cap->Qrp;
...@@ -1893,7 +1923,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1893,7 +1923,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
PVAL *pval = NULL; PVAL *pval = NULL;
char* *pbuf = NULL; char* *pbuf = NULL;
jobjectArray parms; jobjectArray parms;
jmethodID catid; jmethodID catid = nullptr;
if (qrp->Maxres <= 0) if (qrp->Maxres <= 0)
return 0; // 0-sized result" return 0; // 0-sized result"
...@@ -1905,8 +1935,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1905,8 +1935,6 @@ bool JDBConn::SetParam(JDBCCOL *colp)
env->SetObjectArrayElement(parms, 0, env->NewStringUTF(name.ptr(2))); env->SetObjectArrayElement(parms, 0, env->NewStringUTF(name.ptr(2)));
env->SetObjectArrayElement(parms, 1, env->NewStringUTF(name.ptr(1))); env->SetObjectArrayElement(parms, 1, env->NewStringUTF(name.ptr(1)));
env->SetObjectArrayElement(parms, 2, env->NewStringUTF(name.ptr(0))); env->SetObjectArrayElement(parms, 2, env->NewStringUTF(name.ptr(0)));
if (cap->Pat)
env->SetObjectArrayElement(parms, 3, env->NewStringUTF((const char*)cap->Pat)); env->SetObjectArrayElement(parms, 3, env->NewStringUTF((const char*)cap->Pat));
// Now do call the proper JDBC API // Now do call the proper JDBC API
...@@ -1939,21 +1967,26 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1939,21 +1967,26 @@ bool JDBConn::SetParam(JDBCCOL *colp)
return -1; return -1;
} // endswitch infotype } // endswitch infotype
catid = env->GetMethodID(jdi, fnc, "([Ljava/lang/String;)I"); if (gmID(g, catid, fnc, "([Ljava/lang/String;)I"))
if (catid == nullptr) {
sprintf(g->Message, "ERROR: method %s not found !", fnc);
return -1; return -1;
} // endif maxid
// call method // call method
ncol = env->CallIntMethod(job, catid, parms); ncol = env->CallIntMethod(job, catid, parms);
if (Check(ncol)) {
sprintf(g->Message, "%s: %s", fnc, Msg);
env->DeleteLocalRef(parms);
return -1;
} // endif Check
// Not used anymore // Not used anymore
env->DeleteLocalRef(parms); env->DeleteLocalRef(parms);
if (trace)
htrc("Method %s returned %d columns\n", fnc, ncol);
// n because we no more ignore the first column // n because we no more ignore the first column
if ((n = qrp->Nbcol) > (int)ncol) { if ((n = qrp->Nbcol) > (uint)ncol) {
strcpy(g->Message, MSG(COL_NUM_MISM)); strcpy(g->Message, MSG(COL_NUM_MISM));
return -1; return -1;
} // endif n } // endif n
...@@ -1979,20 +2012,25 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1979,20 +2012,25 @@ bool JDBConn::SetParam(JDBCCOL *colp)
if (crp->Type == TYPE_STRING) { if (crp->Type == TYPE_STRING) {
pbuf[n] = (char*)PlugSubAlloc(g, NULL, len); pbuf[n] = (char*)PlugSubAlloc(g, NULL, len);
buffer = pbuf[n]; // buffer = pbuf[n];
} else } // endif Type
buffer = pval[n]->GetTo_Val(); // } else
// buffer = pval[n]->GetTo_Val();
n++; n++;
} // endfor n } // endfor n
// Now fetch the result // Now fetch the result
// Extended fetch cannot be used because of STRBLK's
for (i = 0; i < qrp->Maxres; i++) { for (i = 0; i < qrp->Maxres; i++) {
if ((rc = Fetch(0)) == 0) if (Check(rc = Fetch(0))) {
break; sprintf(g->Message, "Fetch: %s", Msg);
else if (rc < 0)
return -1; return -1;
} if (rc == 0) {
if (trace)
htrc("End of fetches i=%d\n", i);
break;
} // endif rc
for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) { for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) {
SetColumnValue(n + 1, nullptr, pval[n]); SetColumnValue(n + 1, nullptr, pval[n]);
...@@ -2001,7 +2039,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -2001,7 +2039,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
} // endfor i } // endfor i
if (rc == RC_OK) if (rc > 0)
qrp->Truncated = true; qrp->Truncated = true;
return i; return i;
...@@ -2020,7 +2058,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -2020,7 +2058,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
if (!m_Rows) { if (!m_Rows) {
strcpy(g->Message, "Void result"); strcpy(g->Message, "Void result");
return NULL; return NULL;
} // endif m_Res } // endif m_Rows
/*********************************************************************/ /*********************************************************************/
/* Allocate the result storage for future retrieval. */ /* Allocate the result storage for future retrieval. */
......
...@@ -32,15 +32,6 @@ ...@@ -32,15 +32,6 @@
typedef unsigned char *PUCHAR; typedef unsigned char *PUCHAR;
#endif // !__WIN__ #endif // !__WIN__
// Field Flags, used to indicate status of fields
//efine SQL_FIELD_FLAG_DIRTY 0x1
//efine SQL_FIELD_FLAG_NULL 0x2
// Update options flags
//efine SQL_SETPOSUPDATES 0x0001
//efine SQL_POSITIONEDSQL 0x0002
//efine SQL_GDBOUND 0x0004
enum JCATINFO { enum JCATINFO {
CAT_TAB = 1, // JDBC Tables CAT_TAB = 1, // JDBC Tables
CAT_COL = 2, // JDBC Columns CAT_COL = 2, // JDBC Columns
...@@ -55,11 +46,17 @@ enum JCATINFO { ...@@ -55,11 +46,17 @@ enum JCATINFO {
typedef struct tagJCATPARM { typedef struct tagJCATPARM {
JCATINFO Id; // Id to indicate function JCATINFO Id; // Id to indicate function
PQRYRES Qrp; // Result set pointer PQRYRES Qrp; // Result set pointer
PUCHAR DB; // Database (Schema) char *DB; // Database (Schema)
PUCHAR Tab; // Table name or pattern char *Tab; // Table name or pattern
PUCHAR Pat; // Table type or column pattern char *Pat; // Table type or column pattern
} JCATPARM; } JCATPARM;
typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *);
typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *);
#if defined(_DEBUG)
typedef jint(JNICALL *GETDEF) (void *);
#endif // _DEBUG
// JDBC connection to a data source // JDBC connection to a data source
class TDBJDBC; class TDBJDBC;
class JDBCCOL; class JDBCCOL;
...@@ -79,7 +76,7 @@ class JDBConn : public BLOCK { ...@@ -79,7 +76,7 @@ class JDBConn : public BLOCK {
public: public:
JDBConn(PGLOBAL g, TDBJDBC *tdbp); JDBConn(PGLOBAL g, TDBJDBC *tdbp);
int Open(PSZ jpath, PJPARM sop); int Open(PJPARM sop);
int Rewind(char *sql); int Rewind(char *sql);
void Close(void); void Close(void);
PQRYRES AllocateResult(PGLOBAL g); PQRYRES AllocateResult(PGLOBAL g);
...@@ -114,8 +111,18 @@ class JDBConn : public BLOCK { ...@@ -114,8 +111,18 @@ class JDBConn : public BLOCK {
PQRYRES GetMetaData(PGLOBAL g, char *src); PQRYRES GetMetaData(PGLOBAL g, char *src);
public: public:
// Set special options // Set static variables
//void OnSetOptions(HSTMT hstmt); static void SetJVM(void) {
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
} // end of SetJVM
static void ResetJVM(void);
static bool GetJVM(PGLOBAL g);
// Implementation // Implementation
public: public:
...@@ -123,24 +130,30 @@ class JDBConn : public BLOCK { ...@@ -123,24 +130,30 @@ class JDBConn : public BLOCK {
// JDBC operations // JDBC operations
protected: protected:
//bool Check(RETCODE rc); bool gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig);
bool Check(jint rc = 0);
//void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/); //void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/);
//void ThrowDJX(PSZ msg); //void ThrowDJX(PSZ msg);
//void AllocConnect(DWORD dwOptions);
//void Connect(void);
//bool DriverConnect(DWORD Options);
//void VerifyConnect(void);
//void GetConnectInfo(void);
//void Free(void); //void Free(void);
protected: protected:
// Members // Members
#if defined(__WIN__)
static HANDLE LibJvm; // Handle to the jvm DLL
#else // !__WIN__
static void *LibJvm; // Handle for the jvm shared library
#endif // !__WIN__
static CRTJVM CreateJavaVM;
static GETJVM GetCreatedJavaVMs;
#if defined(_DEBUG)
static GETDEF GetDefaultJavaVMInitArgs;
#endif // _DEBUG
PGLOBAL m_G; PGLOBAL m_G;
TDBJDBC *m_Tdb; TDBJDBC *m_Tdb;
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env; // Pointer to native interface JNIEnv *env; // Pointer to native interface
jclass jdi; // Pointer to the JdbcInterface class jclass jdi; // Pointer to the java wrapper class
jobject job; // The JdbcInterface class object jobject job; // The java wrapper class object
jmethodID xqid; // The ExecuteQuery method ID jmethodID xqid; // The ExecuteQuery method ID
jmethodID xuid; // The ExecuteUpdate method ID jmethodID xuid; // The ExecuteUpdate method ID
jmethodID xid; // The Execute method ID jmethodID xid; // The Execute method ID
...@@ -151,9 +164,17 @@ class JDBConn : public BLOCK { ...@@ -151,9 +164,17 @@ class JDBConn : public BLOCK {
jmethodID prepid; // The CreatePrepStmt method ID jmethodID prepid; // The CreatePrepStmt method ID
jmethodID xpid; // The ExecutePrep method ID jmethodID xpid; // The ExecutePrep method ID
jmethodID pcid; // The ClosePrepStmt method ID jmethodID pcid; // The ClosePrepStmt method ID
jmethodID errid; // The GetErrmsg method ID
jmethodID chrfldid; // The StringField method ID
jmethodID intfldid; // The IntField method ID
jmethodID dblfldid; // The DoubleField method ID
jmethodID fltfldid; // The FloatField method ID
jmethodID datfldid; // The TimestampField method ID
jmethodID bigfldid; // The BigintField method ID
//DWORD m_LoginTimeout; //DWORD m_LoginTimeout;
//DWORD m_QueryTimeout; //DWORD m_QueryTimeout;
//DWORD m_UpdateOptions; //DWORD m_UpdateOptions;
char *Msg;
char m_IDQuoteChar[2]; char m_IDQuoteChar[2];
PSZ m_Driver; PSZ m_Driver;
PSZ m_Url; PSZ m_Url;
......
...@@ -21,5 +21,5 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table, ...@@ -21,5 +21,5 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
char *colpat, int maxres, bool info, POPARM sop); char *colpat, int maxres, bool info, POPARM sop);
PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src, POPARM sop); PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src, POPARM sop);
PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat, PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
int maxres, bool info, POPARM sop); char *tabtyp, int maxres, bool info, POPARM sop);
PQRYRES ODBCDrivers(PGLOBAL g, int maxres, bool info); PQRYRES ODBCDrivers(PGLOBAL g, int maxres, bool info);
...@@ -606,7 +606,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info) ...@@ -606,7 +606,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info)
/* an ODBC database that will be retrieved by GetData commands. */ /* an ODBC database that will be retrieved by GetData commands. */
/**************************************************************************/ /**************************************************************************/
PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat, PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
int maxres, bool info, POPARM sop) char *tabtyp, int maxres, bool info, POPARM sop)
{ {
int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_STRING, TYPE_STRING}; TYPE_STRING, TYPE_STRING};
...@@ -668,7 +668,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat, ...@@ -668,7 +668,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp))) if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp)))
return NULL; return NULL;
//cap->Pat = (PUCHAR)tabtyp; cap->Pat = (PUCHAR)tabtyp;
if (trace) if (trace)
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol); htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
......
/************* TabJDBC C++ Program Source Code File (.CPP) *************/ /************* TabJDBC C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABJDBC */ /* PROGRAM NAME: TABJDBC */
/* ------------- */ /* ------------- */
/* Version 1.0 */ /* Version 1.1 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
...@@ -34,8 +34,10 @@ ...@@ -34,8 +34,10 @@
/***********************************************************************/ /***********************************************************************/
/* Include relevant MariaDB header file. */ /* Include relevant MariaDB header file. */
/***********************************************************************/ /***********************************************************************/
#define MYSQL_SERVER 1
#include "my_global.h" #include "my_global.h"
#include "sql_class.h" #include "sql_class.h"
#include "sql_servers.h"
#if defined(__WIN__) #if defined(__WIN__)
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -67,7 +69,6 @@ ...@@ -67,7 +69,6 @@
#include "plgdbsem.h" #include "plgdbsem.h"
#include "mycat.h" #include "mycat.h"
#include "xtable.h" #include "xtable.h"
#include "jdbccat.h"
#include "tabjdbc.h" #include "tabjdbc.h"
#include "tabmul.h" #include "tabmul.h"
#include "reldef.h" #include "reldef.h"
...@@ -95,48 +96,160 @@ bool ExactInfo(void); ...@@ -95,48 +96,160 @@ bool ExactInfo(void);
/***********************************************************************/ /***********************************************************************/
JDBCDEF::JDBCDEF(void) JDBCDEF::JDBCDEF(void)
{ {
Jpath = Driver = Url = Tabname = Tabschema = Username = NULL; Driver = Url = Tabname = Tabschema = Username = Colpat = NULL;
Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL; Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL;
Options = Quoted = Maxerr = Maxres = Memory = 0; Options = Quoted = Maxerr = Maxres = Memory = 0;
Scrollable = Xsrc = false; Scrollable = Xsrc = false;
} // end of JDBCDEF constructor } // end of JDBCDEF constructor
/***********************************************************************/
/* Called on table construction. */
/***********************************************************************/
bool JDBCDEF::SetParms(PJPARM sjp)
{
sjp->Url= Url;
sjp->User= Username;
sjp->Pwd= Password;
return true;
} // end of SetParms
/***********************************************************************/
/* Parse connection string */
/* */
/* SYNOPSIS */
/* ParseURL() */
/* Url The connection string to parse */
/* */
/* DESCRIPTION */
/* This is used to set the Url in case a wrapper server as been */
/* specified. This is rather experimental yet. */
/* */
/* RETURN VALUE */
/* RC_OK Url was a true URL */
/* RC_NF Url was a server name/table */
/* RC_FX Error */
/* */
/***********************************************************************/
int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
{
if (strncmp(url, "jdbc:", 5)) {
// No "jdbc:" in connection string. Must be a straight
// "server" or "server/table"
// ok, so we do a little parsing, but not completely!
if ((Tabname= strchr(url, '/'))) {
// If there is a single '/' in the connection string,
// this means the user is specifying a table name
*Tabname++= '\0';
// there better not be any more '/'s !
if (strchr(Tabname, '/'))
return RC_FX;
} else if (b) {
// Otherwise, straight server name,
Tabname = GetStringCatInfo(g, "Name", NULL);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
} // endelse
if (trace)
htrc("server: %s Tabname: %s", url, Tabname);
// Now make the required URL
FOREIGN_SERVER *server, server_buffer;
// get_server_by_name() clones the server if exists
if (!(server= get_server_by_name(current_thd->mem_root, url, &server_buffer))) {
sprintf(g->Message, "Server %s does not exist!", url);
return RC_FX;
} // endif server
if (strncmp(server->host, "jdbc:", 5)) {
// Now make the required URL
Url = (PSZ)PlugSubAlloc(g, NULL, 0);
strcat(strcpy(Url, "jdbc:"), server->scheme);
strcat(strcat(Url, "://"), server->host);
if (server->port) {
char buf[16];
sprintf(buf, "%ld", server->port);
strcat(strcat(Url, ":"), buf);
} // endif port
if (server->db)
strcat(strcat(Url, "/"), server->db);
PlugSubAlloc(g, NULL, strlen(Url) + 1);
} else // host is a URL
Url = PlugDup(g, server->host);
if (server->username)
Username = PlugDup(g, server->username);
if (server->password)
Password = PlugDup(g, server->password);
return RC_NF;
} // endif
// Url was a JDBC URL, nothing to do
return RC_OK;
} // end of ParseURL
/***********************************************************************/ /***********************************************************************/
/* DefineAM: define specific AM block values from JDBC file. */ /* DefineAM: define specific AM block values from JDBC file. */
/***********************************************************************/ /***********************************************************************/
bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{ {
Jpath = GetStringCatInfo(g, "Jpath", ""); int rc = RC_OK;
Driver = GetStringCatInfo(g, "Driver", NULL); Driver = GetStringCatInfo(g, "Driver", NULL);
Desc = Url = GetStringCatInfo(g, "Url", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL);
if (!Url && !Catfunc) { if (!Url && !Catfunc) {
// Look in the option list (deprecated)
Url = GetStringCatInfo(g, "Url", NULL);
if (!Url) {
sprintf(g->Message, "Missing URL for JDBC table %s", Name); sprintf(g->Message, "Missing URL for JDBC table %s", Name);
return true; return true;
} // endif Url
} // endif Connect } // endif Connect
if (Url)
rc = ParseURL(g, Url);
if (rc == RC_FX) // Error
return true;
else if (rc == RC_OK) { // Url was not a server name
Tabname = GetStringCatInfo(g, "Name", Tabname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Tabname = GetStringCatInfo(g, "Tabname", Tabname); Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Tabtype = GetStringCatInfo(g, "Tabtype", NULL);
Username = GetStringCatInfo(g, "User", NULL); Username = GetStringCatInfo(g, "User", NULL);
Password = GetStringCatInfo(g, "Password", NULL); Password = GetStringCatInfo(g, "Password", NULL);
} // endif rc
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
Read_Only = true; Read_Only = true;
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
if (Catfunc == FNC_COL)
Colpat = GetStringCatInfo(g, "Colpat", NULL);
if (Catfunc == FNC_TABLE)
Tabtype = GetStringCatInfo(g, "Tabtype", NULL);
Qrystr = GetStringCatInfo(g, "Query_String", "?"); Qrystr = GetStringCatInfo(g, "Query_String", "?");
Sep = GetStringCatInfo(g, "Separator", NULL); Sep = GetStringCatInfo(g, "Separator", NULL);
Xsrc = GetBoolCatInfo("Execsrc", FALSE); Xsrc = GetBoolCatInfo("Execsrc", FALSE);
Maxerr = GetIntCatInfo("Maxerr", 0); Maxerr = GetIntCatInfo("Maxerr", 0);
Maxres = GetIntCatInfo("Maxres", 0); Maxres = GetIntCatInfo("Maxres", 0);
Quoted = GetIntCatInfo("Quoted", 0); Quoted = GetIntCatInfo("Quoted", 0);
//Options = JDBConn::noJDBCDialog;
//Options = JDBConn::noJDBCDialog | JDBConn::useCursorLib;
//Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); //Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
//Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); //Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
Scrollable = GetBoolCatInfo("Scrollable", false); Scrollable = GetBoolCatInfo("Scrollable", false);
...@@ -216,7 +329,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) ...@@ -216,7 +329,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
Cnp = NULL; Cnp = NULL;
if (tdp) { if (tdp) {
Jpath = tdp->Jpath;
Ops.Driver = tdp->Driver; Ops.Driver = tdp->Driver;
Ops.Url = tdp->Url; Ops.Url = tdp->Url;
TableName = tdp->Tabname; TableName = tdp->Tabname;
...@@ -235,7 +347,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) ...@@ -235,7 +347,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
Memory = tdp->Memory; Memory = tdp->Memory;
Ops.Scrollable = tdp->Scrollable; Ops.Scrollable = tdp->Scrollable;
} else { } else {
Jpath = NULL;
TableName = NULL; TableName = NULL;
Schema = NULL; Schema = NULL;
Ops.Driver = NULL; Ops.Driver = NULL;
...@@ -271,6 +382,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) ...@@ -271,6 +382,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
Ncol = 0; Ncol = 0;
Nparm = 0; Nparm = 0;
Placed = false; Placed = false;
Prepared = false;
Werr = false; Werr = false;
Rerr = false; Rerr = false;
Ops.Fsize = Ops.CheckSize(Rows); Ops.Fsize = Ops.CheckSize(Rows);
...@@ -280,7 +392,6 @@ TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp) ...@@ -280,7 +392,6 @@ TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp)
{ {
Jcp = tdbp->Jcp; // is that right ? Jcp = tdbp->Jcp; // is that right ?
Cnp = tdbp->Cnp; Cnp = tdbp->Cnp;
Jpath = tdbp->Jpath;
TableName = tdbp->TableName; TableName = tdbp->TableName;
Schema = tdbp->Schema; Schema = tdbp->Schema;
Ops = tdbp->Ops; Ops = tdbp->Ops;
...@@ -678,7 +789,7 @@ int TDBJDBC::Cardinality(PGLOBAL g) ...@@ -678,7 +789,7 @@ int TDBJDBC::Cardinality(PGLOBAL g)
char qry[96], tbn[64]; char qry[96], tbn[64];
JDBConn *jcp = new(g)JDBConn(g, this); JDBConn *jcp = new(g)JDBConn(g, this);
if (jcp->Open(Jpath, &Ops) == RC_FX) if (jcp->Open(&Ops) == RC_FX)
return -1; return -1;
// Table name can be encoded in UTF-8 // Table name can be encoded in UTF-8
...@@ -789,7 +900,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g) ...@@ -789,7 +900,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
else if (Jcp->IsOpen()) else if (Jcp->IsOpen())
Jcp->Close(); Jcp->Close();
if (Jcp->Open(Jpath, &Ops) == RC_FX) if (Jcp->Open(&Ops) == RC_FX)
return true; return true;
else if (Quoted) else if (Quoted)
Quote = Jcp->GetQuoteChar(); Quote = Jcp->GetQuoteChar();
...@@ -1539,7 +1650,7 @@ bool TDBXJDC::OpenDB(PGLOBAL g) ...@@ -1539,7 +1650,7 @@ bool TDBXJDC::OpenDB(PGLOBAL g)
} else if (Jcp->IsOpen()) } else if (Jcp->IsOpen())
Jcp->Close(); Jcp->Close();
if (Jcp->Open(Jpath, &Ops) == RC_FX) if (Jcp->Open(&Ops) == RC_FX)
return true; return true;
Use = USE_OPEN; // Do it now in case we are recursively called Use = USE_OPEN; // Do it now in case we are recursively called
...@@ -1651,7 +1762,7 @@ void JSRCCOL::WriteColumn(PGLOBAL g) ...@@ -1651,7 +1762,7 @@ void JSRCCOL::WriteColumn(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBJDRV::GetResult(PGLOBAL g) PQRYRES TDBJDRV::GetResult(PGLOBAL g)
{ {
return JDBCDrivers(g, Jpath, Maxres, false); return JDBCDrivers(g, Maxres, false);
} // end of GetResult } // end of GetResult
/* ---------------------------TDBJTB class --------------------------- */ /* ---------------------------TDBJTB class --------------------------- */
...@@ -1661,7 +1772,6 @@ PQRYRES TDBJDRV::GetResult(PGLOBAL g) ...@@ -1661,7 +1772,6 @@ PQRYRES TDBJDRV::GetResult(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp)
{ {
Jpath = tdp->Jpath;
Schema = tdp->Tabschema; Schema = tdp->Tabschema;
Tab = tdp->Tabname; Tab = tdp->Tabname;
Tabtype = tdp->Tabtype; Tabtype = tdp->Tabtype;
...@@ -1669,6 +1779,8 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) ...@@ -1669,6 +1779,8 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp)
Ops.Url = tdp->Url; Ops.Url = tdp->Url;
Ops.User = tdp->Username; Ops.User = tdp->Username;
Ops.Pwd = tdp->Password; Ops.Pwd = tdp->Password;
Ops.Fsize = 0;
Ops.Scrollable = false;
} // end of TDBJTB constructor } // end of TDBJTB constructor
/***********************************************************************/ /***********************************************************************/
...@@ -1676,17 +1788,25 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) ...@@ -1676,17 +1788,25 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBJTB::GetResult(PGLOBAL g) PQRYRES TDBJTB::GetResult(PGLOBAL g)
{ {
return JDBCTables(g, Jpath, Schema, Tab, Tabtype, Maxres, false, &Ops); return JDBCTables(g, Schema, Tab, Tabtype, Maxres, false, &Ops);
} // end of GetResult } // end of GetResult
/* --------------------------TDBJDBCL class -------------------------- */ /* --------------------------TDBJDBCL class -------------------------- */
/***********************************************************************/
/* TDBJDBCL class constructor. */
/***********************************************************************/
TDBJDBCL::TDBJDBCL(PJDBCDEF tdp) : TDBJTB(tdp)
{
Colpat = tdp->Colpat;
} // end of TDBJDBCL constructor
/***********************************************************************/ /***********************************************************************/
/* GetResult: Get the list of JDBC table columns. */ /* GetResult: Get the list of JDBC table columns. */
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBJDBCL::GetResult(PGLOBAL g) PQRYRES TDBJDBCL::GetResult(PGLOBAL g)
{ {
return JDBCColumns(g, Jpath, Schema, Tab, NULL, Maxres, false, &Ops); return JDBCColumns(g, Schema, Tab, Colpat, Maxres, false, &Ops);
} // end of GetResult } // end of GetResult
#if 0 #if 0
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
/***********************************************************************/ /***********************************************************************/
#include "colblk.h" #include "colblk.h"
#include "resource.h" #include "resource.h"
#include "jdbccat.h"
typedef class JDBCDEF *PJDBCDEF; typedef class JDBCDEF *PJDBCDEF;
typedef class TDBJDBC *PTDBJDBC; typedef class TDBJDBC *PTDBJDBC;
...@@ -25,13 +26,13 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ ...@@ -25,13 +26,13 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */
friend class TDBXJDC; friend class TDBXJDC;
friend class TDBJDRV; friend class TDBJDRV;
friend class TDBJTB; friend class TDBJTB;
friend class TDBJDBCL;
public: public:
// Constructor // Constructor
JDBCDEF(void); JDBCDEF(void);
// Implementation // Implementation
virtual const char *GetType(void) { return "JDBC"; } virtual const char *GetType(void) { return "JDBC"; }
PSZ GetJpath(void) { return Jpath; }
PSZ GetTabname(void) { return Tabname; } PSZ GetTabname(void) { return Tabname; }
PSZ GetTabschema(void) { return Tabschema; } PSZ GetTabschema(void) { return Tabschema; }
PSZ GetTabcat(void) { return Tabcat; } PSZ GetTabcat(void) { return Tabcat; }
...@@ -45,10 +46,11 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ ...@@ -45,10 +46,11 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */
virtual int Indexable(void) { return 2; } virtual int Indexable(void) { return 2; }
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m); virtual PTDB GetTable(PGLOBAL g, MODE m);
int ParseURL(PGLOBAL g, char *url, bool b = true);
bool SetParms(PJPARM sjp);
protected: protected:
// Members // Members
PSZ Jpath; /* Java class path */
PSZ Driver; /* JDBC driver */ PSZ Driver; /* JDBC driver */
PSZ Url; /* JDBC driver URL */ PSZ Url; /* JDBC driver URL */
PSZ Tabname; /* External table name */ PSZ Tabname; /* External table name */
...@@ -57,6 +59,7 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ ...@@ -57,6 +59,7 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */
PSZ Password; /* Password connect info */ PSZ Password; /* Password connect info */
PSZ Tabcat; /* External table catalog */ PSZ Tabcat; /* External table catalog */
PSZ Tabtype; /* External table type */ PSZ Tabtype; /* External table type */
PSZ Colpat; /* Catalog column pattern */
PSZ Srcdef; /* The source table SQL definition */ PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */ PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */ PSZ Qrystr; /* The original query */
...@@ -73,7 +76,7 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ ...@@ -73,7 +76,7 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */
}; // end of JDBCDEF }; // end of JDBCDEF
#if !defined(NJDBC) #if !defined(NJDBC)
#include "JDBConn.h" #include "jdbconn.h"
/***********************************************************************/ /***********************************************************************/
/* This is the JDBC Access Method class declaration for files from */ /* This is the JDBC Access Method class declaration for files from */
...@@ -130,7 +133,6 @@ class TDBJDBC : public TDBASE { ...@@ -130,7 +133,6 @@ class TDBJDBC : public TDBASE {
JDBCCOL *Cnp; // Points to count(*) column JDBCCOL *Cnp; // Points to count(*) column
JDBCPARM Ops; // Additional parameters JDBCPARM Ops; // Additional parameters
PSTRG Query; // Constructed SQL query PSTRG Query; // Constructed SQL query
char *Jpath; // Java class path
char *TableName; // Points to JDBC table name char *TableName; // Points to JDBC table name
char *Schema; // Points to JDBC table Schema char *Schema; // Points to JDBC table Schema
char *User; // User connect info char *User; // User connect info
...@@ -282,7 +284,7 @@ class JSRCCOL : public JDBCCOL { ...@@ -282,7 +284,7 @@ class JSRCCOL : public JDBCCOL {
class TDBJDRV : public TDBCAT { class TDBJDRV : public TDBCAT {
public: public:
// Constructor // Constructor
TDBJDRV(PJDBCDEF tdp) : TDBCAT(tdp) {Maxres = tdp->Maxres; Jpath = tdp->Jpath;} TDBJDRV(PJDBCDEF tdp) : TDBCAT(tdp) {Maxres = tdp->Maxres;}
protected: protected:
// Specific routines // Specific routines
...@@ -290,7 +292,6 @@ class TDBJDRV : public TDBCAT { ...@@ -290,7 +292,6 @@ class TDBJDRV : public TDBCAT {
// Members // Members
int Maxres; // Returned lines limit int Maxres; // Returned lines limit
char *Jpath; // Java class path
}; // end of class TDBJDRV }; // end of class TDBJDRV
/***********************************************************************/ /***********************************************************************/
...@@ -306,7 +307,6 @@ class TDBJTB : public TDBJDRV { ...@@ -306,7 +307,6 @@ class TDBJTB : public TDBJDRV {
virtual PQRYRES GetResult(PGLOBAL g); virtual PQRYRES GetResult(PGLOBAL g);
// Members // Members
char *Jpath; // Points to Java classpath
char *Schema; // Points to schema name or NULL char *Schema; // Points to schema name or NULL
char *Tab; // Points to JDBC table name or pattern char *Tab; // Points to JDBC table name or pattern
char *Tabtype; // Points to JDBC table type char *Tabtype; // Points to JDBC table type
...@@ -319,14 +319,15 @@ class TDBJTB : public TDBJDRV { ...@@ -319,14 +319,15 @@ class TDBJTB : public TDBJDRV {
class TDBJDBCL : public TDBJTB { class TDBJDBCL : public TDBJTB {
public: public:
// Constructor // Constructor
TDBJDBCL(PJDBCDEF tdp) : TDBJTB(tdp) {} TDBJDBCL(PJDBCDEF tdp);
protected: protected:
// Specific routines // Specific routines
virtual PQRYRES GetResult(PGLOBAL g); virtual PQRYRES GetResult(PGLOBAL g);
// No additional Members // Members
}; // end of class TDBJCL char *Colpat; // Points to catalog column pattern
}; // end of class TDBJDBCL
#if 0 #if 0
/***********************************************************************/ /***********************************************************************/
......
/************* Tabodbc C++ Program Source Code File (.CPP) *************/ /************* Tabodbc C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABODBC */ /* PROGRAM NAME: TABODBC */
/* ------------- */ /* ------------- */
/* Version 3.0 */ /* Version 3.1 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
...@@ -96,7 +96,7 @@ bool ExactInfo(void); ...@@ -96,7 +96,7 @@ bool ExactInfo(void);
ODBCDEF::ODBCDEF(void) ODBCDEF::ODBCDEF(void)
{ {
Connect = Tabname = Tabschema = Username = Password = NULL; Connect = Tabname = Tabschema = Username = Password = NULL;
Tabcat = Srcdef = Qchar = Qrystr = Sep = NULL; Tabcat = Colpat = Srcdef = Qchar = Qrystr = Sep = NULL;
Catver = Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0; Catver = Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0;
Scrollable = Xsrc = UseCnc = false; Scrollable = Xsrc = UseCnc = false;
} // end of ODBCDEF constructor } // end of ODBCDEF constructor
...@@ -141,6 +141,12 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -141,6 +141,12 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt) if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt)
Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch
if (Catfunc == FNC_COL)
Colpat = GetStringCatInfo(g, "Colpat", NULL);
if (Catfunc == FNC_TABLE)
Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
UseCnc = GetBoolCatInfo("UseDSN", false); UseCnc = GetBoolCatInfo("UseDSN", false);
// Memory was Boolean, it is now integer // Memory was Boolean, it is now integer
...@@ -1768,6 +1774,7 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) ...@@ -1768,6 +1774,7 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
Dsn = tdp->GetConnect(); Dsn = tdp->GetConnect();
Schema = tdp->GetTabschema(); Schema = tdp->GetTabschema();
Tab = tdp->GetTabname(); Tab = tdp->GetTabname();
Tabtyp = tdp->Tabtyp;
Ops.User = tdp->Username; Ops.User = tdp->Username;
Ops.Pwd = tdp->Password; Ops.Pwd = tdp->Password;
Ops.Cto = tdp->Cto; Ops.Cto = tdp->Cto;
...@@ -1780,17 +1787,25 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) ...@@ -1780,17 +1787,25 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBOTB::GetResult(PGLOBAL g) PQRYRES TDBOTB::GetResult(PGLOBAL g)
{ {
return ODBCTables(g, Dsn, Schema, Tab, Maxres, false, &Ops); return ODBCTables(g, Dsn, Schema, Tab, Tabtyp, Maxres, false, &Ops);
} // end of GetResult } // end of GetResult
/* ---------------------------TDBOCL class --------------------------- */ /* ---------------------------TDBOCL class --------------------------- */
/***********************************************************************/
/* TDBOCL class constructor. */
/***********************************************************************/
TDBOCL::TDBOCL(PODEF tdp) : TDBOTB(tdp)
{
Colpat = tdp->Colpat;
} // end of TDBOTB constructor
/***********************************************************************/ /***********************************************************************/
/* GetResult: Get the list of ODBC table columns. */ /* GetResult: Get the list of ODBC table columns. */
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBOCL::GetResult(PGLOBAL g) PQRYRES TDBOCL::GetResult(PGLOBAL g)
{ {
return ODBCColumns(g, Dsn, Schema, Tab, NULL, Maxres, false, &Ops); return ODBCColumns(g, Dsn, Schema, Tab, Colpat, Maxres, false, &Ops);
} // end of GetResult } // end of GetResult
/* ------------------------ End of Tabodbc --------------------------- */ /* ------------------------ End of Tabodbc --------------------------- */
...@@ -25,7 +25,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -25,7 +25,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
friend class TDBXDBC; friend class TDBXDBC;
friend class TDBDRV; friend class TDBDRV;
friend class TDBOTB; friend class TDBOTB;
public: friend class TDBOCL;
public:
// Constructor // Constructor
ODBCDEF(void); ODBCDEF(void);
...@@ -54,6 +55,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -54,6 +55,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Username; /* User connect name */ PSZ Username; /* User connect name */
PSZ Password; /* Password connect info */ PSZ Password; /* Password connect info */
PSZ Tabcat; /* External table catalog */ PSZ Tabcat; /* External table catalog */
PSZ Tabtyp; /* Catalog table type */
PSZ Colpat; /* Catalog column pattern */
PSZ Srcdef; /* The source table SQL definition */ PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */ PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */ PSZ Qrystr; /* The original query */
...@@ -326,6 +329,7 @@ class TDBOTB : public TDBDRV { ...@@ -326,6 +329,7 @@ class TDBOTB : public TDBDRV {
char *Dsn; // Points to connection string char *Dsn; // Points to connection string
char *Schema; // Points to schema name or NULL char *Schema; // Points to schema name or NULL
char *Tab; // Points to ODBC table name or pattern char *Tab; // Points to ODBC table name or pattern
char *Tabtyp; // Points to ODBC table type
ODBCPARM Ops; // Additional parameters ODBCPARM Ops; // Additional parameters
}; // end of class TDBOTB }; // end of class TDBOTB
...@@ -335,13 +339,14 @@ class TDBOTB : public TDBDRV { ...@@ -335,13 +339,14 @@ class TDBOTB : public TDBDRV {
class TDBOCL : public TDBOTB { class TDBOCL : public TDBOTB {
public: public:
// Constructor // Constructor
TDBOCL(PODEF tdp) : TDBOTB(tdp) {} TDBOCL(PODEF tdp);
protected: protected:
// Specific routines // Specific routines
virtual PQRYRES GetResult(PGLOBAL g); virtual PQRYRES GetResult(PGLOBAL g);
// No additional Members // Members
char *Colpat; // Points to column pattern
}; // end of class TDBOCL }; // end of class TDBOCL
#endif // !NODBC #endif // !NODBC
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment