Commit 2f2797e5 authored by Olivier Bertrand's avatar Olivier Bertrand

- JDBC tables can be connected via foreign server wrapper

  Redesign the handling of errors and exceptions
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/jdbconn.cpp
  modified:   storage/connect/jdbconn.h
  modified:   storage/connect/tabjdbc.cpp
  modified:   storage/connect/tabjdbc.h
parent 7972a45b
...@@ -119,6 +119,7 @@ ...@@ -119,6 +119,7 @@
#undef OFFSET #undef OFFSET
#define NOPARSE #define NOPARSE
#define NJDBC
#if defined(UNIX) #if defined(UNIX)
#include "osutil.h" #include "osutil.h"
#endif // UNIX #endif // UNIX
...@@ -128,7 +129,7 @@ ...@@ -128,7 +129,7 @@
#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" #include "jdbconn.h"
#endif // JDBC_SUPPORT #endif // JDBC_SUPPORT
#include "xtable.h" #include "xtable.h"
...@@ -5224,7 +5225,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5224,7 +5225,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif #endif
#if defined(JDBC_SUPPORT) #if defined(JDBC_SUPPORT)
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"));
...@@ -5325,18 +5326,31 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5325,18 +5326,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 && !(url= strz(g, create_info->connect_string))) { } 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->Url= url;
sjp->User= (char*)user;
sjp->Pwd= (char*)pwd;
sjp->Fsize= 0; sjp->Fsize= 0;
sjp->Scrollable= false; sjp->Scrollable= false;
ok= true;
if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) {
sjp->Url= url;
sjp->User= (char*)user;
sjp->Pwd= (char*)pwd;
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);
...@@ -5775,12 +5789,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5775,12 +5789,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
......
...@@ -38,7 +38,6 @@ ...@@ -38,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
...@@ -118,6 +117,7 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) ...@@ -118,6 +117,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
...@@ -155,7 +155,6 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) ...@@ -155,7 +155,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;
...@@ -318,12 +317,15 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, ...@@ -318,12 +317,15 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat,
/**************************************************************************/ /**************************************************************************/
PQRYRES JDBCSrcCols(PGLOBAL g, 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(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
/**************************************************************************/ /**************************************************************************/
...@@ -361,14 +363,14 @@ PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, ...@@ -361,14 +363,14 @@ PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp,
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;
...@@ -642,11 +644,12 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) ...@@ -642,11 +644,12 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
env= nullptr; // Pointer to native interface env= nullptr; // Pointer to native interface
jdi = nullptr; // Pointer to the JdbcInterface class jdi = nullptr; // Pointer to the JdbcInterface class
job = nullptr; // The JdbcInterface class object job = nullptr; // The JdbcInterface 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;
//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;
...@@ -676,10 +679,11 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) ...@@ -676,10 +679,11 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
/***********************************************************************/ /***********************************************************************/
/* Screen for errors. */ /* Screen for errors. */
/***********************************************************************/ /***********************************************************************/
char *JDBConn::Check(void) bool JDBConn::Check(jint rc)
{ {
jstring s;
if (env->ExceptionCheck()) { if (env->ExceptionCheck()) {
char *msg;
jthrowable exc = env->ExceptionOccurred(); jthrowable exc = env->ExceptionOccurred();
jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"),
"toString", "()Ljava/lang/String;"); "toString", "()Ljava/lang/String;");
...@@ -688,17 +692,39 @@ char *JDBConn::Check(void) ...@@ -688,17 +692,39 @@ char *JDBConn::Check(void)
jstring s = (jstring)env->CallObjectMethod(exc, tid); jstring s = (jstring)env->CallObjectMethod(exc, tid);
const char *utf = env->GetStringUTFChars(s, (jboolean)false); const char *utf = env->GetStringUTFChars(s, (jboolean)false);
env->DeleteLocalRef(s); env->DeleteLocalRef(s);
msg = PlugDup(m_G, utf); Msg = PlugDup(m_G, utf);
} else } else
msg = "Exception occured"; Msg = "Exception occured";
env->ExceptionClear(); env->ExceptionClear();
return msg; } else if (rc < 0) {
} // endif Check s = (jstring)env->CallObjectMethod(job, errid);
Msg = (char*)env->GetStringUTFChars(s, (jboolean)false);
} else
Msg = NULL;
return NULL; return (Msg != NULL);
} // end of Check } // 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);
if (Check()) {
strcpy(g->Message, Msg);
return true;
} else
return false;
} else
return false;
} // end of gmID
#if 0 #if 0
/***********************************************************************/ /***********************************************************************/
/* Utility routine. */ /* Utility routine. */
...@@ -758,15 +784,17 @@ void JDBConn::OnSetOptions(HSTMT hstmt) ...@@ -758,15 +784,17 @@ 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
/***********************************************************************/ /***********************************************************************/
...@@ -859,6 +887,7 @@ bool JDBConn::GetJVM(PGLOBAL g) ...@@ -859,6 +887,7 @@ bool JDBConn::GetJVM(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int JDBConn::Open(PJPARM sop) int JDBConn::Open(PJPARM sop)
{ {
bool err = false;
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
// Link or check whether jvm library was linked // Link or check whether jvm library was linked
...@@ -881,8 +910,10 @@ int JDBConn::Open(PJPARM sop) ...@@ -881,8 +910,10 @@ int JDBConn::Open(PJPARM sop)
} // endif rc } // endif rc
} else { } else {
// Create a new jvm /*******************************************************************/
PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path="); /* Create a new jvm */
/*******************************************************************/
PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path=.");
char *cp = NULL; char *cp = NULL;
char sep; char sep;
...@@ -897,23 +928,21 @@ int JDBConn::Open(PJPARM sop) ...@@ -897,23 +928,21 @@ int JDBConn::Open(PJPARM sop)
JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options
// where to find java .class // where to find java .class
if ((cp = PlugDup(m_G, getenv("CLASSPATH"))))
jpop->Append(cp);
if (trace) {
htrc("CLASSPATH=%s\n", getenv("CLASSPATH"));
htrc("ClassPath=%s\n", ClassPath);
} // endif trace
if (ClassPath && *ClassPath) { if (ClassPath && *ClassPath) {
if (cp) jpop->Append(sep);
jpop->Append(sep);
jpop->Append(ClassPath); jpop->Append(ClassPath);
} // endif ClassPath } // endif ClassPath
if (trace) if ((cp = getenv("CLASSPATH"))) {
jpop->Append(sep);
jpop->Append(cp);
} // endif cp
if (trace) {
htrc("ClassPath=%s\n", ClassPath);
htrc("CLASSPATH=%s\n", cp);
htrc("%s\n", jpop->GetStr()); htrc("%s\n", jpop->GetStr());
} // endif trace
options[0].optionString = jpop->GetStr(); options[0].optionString = jpop->GetStr();
//options[1].optionString = "-verbose:jni"; //options[1].optionString = "-verbose:jni";
...@@ -981,7 +1010,7 @@ int JDBConn::Open(PJPARM sop) ...@@ -981,7 +1010,7 @@ int JDBConn::Open(PJPARM sop)
jstring path = env->NewStringUTF(jpath); jstring path = env->NewStringUTF(jpath);
rc = env->CallStaticIntMethod(jdi, alp, path); rc = env->CallStaticIntMethod(jdi, alp, path);
if ((msg = Check())) { if ((msg = Check(rc))) {
strcpy(g->Message, msg); strcpy(g->Message, msg);
env->DeleteLocalRef(path); env->DeleteLocalRef(path);
return RC_FX; return RC_FX;
...@@ -1022,33 +1051,36 @@ int JDBConn::Open(PJPARM sop) ...@@ -1022,33 +1051,36 @@ int JDBConn::Open(PJPARM sop)
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
if (sop) { m_Driver = sop->Driver;
m_Driver = sop->Driver; m_Url = sop->Url;
m_Url = sop->Url; m_User = sop->User;
m_User = sop->User; m_Pwd = sop->Pwd;
m_Pwd = sop->Pwd; m_Scrollable = sop->Scrollable;
m_Scrollable = sop->Scrollable; m_RowsetSize = sop->Fsize;
m_RowsetSize = sop->Fsize; //m_LoginTimeout = sop->Cto;
//m_LoginTimeout = sop->Cto; //m_QueryTimeout = sop->Qto;
//m_QueryTimeout = sop->Qto; //m_UseCnc = sop->UseCnc;
//m_UseCnc = sop->UseCnc;
} // endif sop
// change some elements // change some elements
if (m_Driver) if (m_Driver)
...@@ -1065,23 +1097,17 @@ int JDBConn::Open(PJPARM sop) ...@@ -1065,23 +1097,17 @@ int JDBConn::Open(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;
...@@ -1092,43 +1118,37 @@ int JDBConn::Open(PJPARM sop) ...@@ -1092,43 +1118,37 @@ int JDBConn::Open(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 if (gmID(g, xid, "Execute", "(Ljava/lang/String;)I") ||
xid = env->GetMethodID(jdi, "Execute", "(Ljava/lang/String;)I"); gmID(g, grs, "GetResult", "()I"))
return RC_FX;
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;
} // 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;
...@@ -1139,44 +1159,29 @@ int JDBConn::ExecSQLcommand(char *sql) ...@@ -1139,44 +1159,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
...@@ -1184,7 +1189,7 @@ int JDBConn::Fetch(int pos) ...@@ -1184,7 +1189,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
...@@ -1201,15 +1206,8 @@ int JDBConn::Rewind(char *sql) ...@@ -1201,15 +1206,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"); return -1;
if (fetchid == nullptr) {
strcpy(m_G->Message, "Cannot find method Fetch");
return -1;
} // endif readid
} // endif readid
jboolean b = env->CallBooleanMethod(job, fetchid, 0); jboolean b = env->CallBooleanMethod(job, fetchid, 0);
...@@ -1227,15 +1225,15 @@ void JDBConn::Close() ...@@ -1227,15 +1225,15 @@ 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 if ((rc = env->CallIntMethod(job, did))) else if (Check(env->CallIntMethod(job, did)))
printf("jdbcDisconnect: rc=%d", (int)rc); printf("jdbcDisconnect: %s\n", Msg);
if ((rc = jvm->DetachCurrentThread())) if ((rc = jvm->DetachCurrentThread()) != JNI_OK)
printf("DetachCurrentThread: rc = %d", (int)rc); printf("DetachCurrentThread: rc=%d\n", (int)rc);
//rc = jvm->DestroyJavaVM(); //rc = jvm->DestroyJavaVM();
m_Opened = false; m_Opened = false;
...@@ -1249,7 +1247,6 @@ void JDBConn::Close() ...@@ -1249,7 +1247,6 @@ void JDBConn::Close()
void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
{ {
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
char *msg;
jint ctyp; jint ctyp;
jlong dtv; jlong dtv;
jstring cn, jn = nullptr; jstring cn, jn = nullptr;
...@@ -1262,10 +1259,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1262,10 +1259,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 ((msg = Check())) { if (Check((ctyp == 666) ? -1 : 1)) {
sprintf(g->Message, "Getting ctyp: %s", msg); sprintf(g->Message, "Getting ctyp: %s", Msg);
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif Check } // endif Check
...@@ -1303,6 +1301,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1303,6 +1301,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
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"); fldid = env->GetMethodID(jdi, "DoubleField", "(ILjava/lang/String;)D");
...@@ -1372,11 +1371,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1372,11 +1371,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
val->Reset(); val->Reset();
} // endswitch Type } // endswitch Type
if ((msg = Check())) { if (Check()) {
if (rank == 0) if (rank == 0)
env->DeleteLocalRef(jn); env->DeleteLocalRef(jn);
sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", msg, rank, (int)ctyp); sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", Msg, rank, (int)ctyp);
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif Check } // endif Check
...@@ -1390,21 +1389,22 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1390,21 +1389,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) { if (!gmID(g, prepid, "CreatePrepStmt", "(Ljava/lang/String;)I")) {
strcpy(m_G->Message, "Cannot find method CreatePrepStmt"); // Create the prepared statement
return true; jstring qry = env->NewStringUTF(sql);
} // endif prepid
if (Check(env->CallBooleanMethod(job, prepid, qry)))
sprintf(g->Message, "CreatePrepStmt: %s", Msg);
else
b = false;
env->DeleteLocalRef(qry);
} // endif prepid } // endif prepid
// Create the prepared statement return b;
jstring qry = env->NewStringUTF(sql);
jboolean b = env->CallBooleanMethod(job, prepid, qry);
env->DeleteLocalRef(qry);
return (bool)b;
} // end of PrepareSQL } // end of PrepareSQL
/***********************************************************************/ /***********************************************************************/
...@@ -1412,32 +1412,25 @@ bool JDBConn::PrepareSQL(char *sql) ...@@ -1412,32 +1412,25 @@ 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 if (!gmID(g, xqid, "ExecuteQuery", "(Ljava/lang/String;)I")) {
xqid = env->GetMethodID(jdi, "ExecuteQuery", "(Ljava/lang/String;)I"); qry = env->NewStringUTF(sql);
ncol = env->CallIntMethod(job, xqid, qry);
if (xqid == nullptr) { if (!Check(ncol)) {
strcpy(g->Message, "Cannot find method ExecuteQuery"); m_Ncol = (int)ncol;
return RC_FX; m_Aff = 0; // Affected rows
} // endif !xqid rc = RC_OK;
} else
} // endif xqid sprintf(g->Message, "ExecuteQuery: %s", Msg);
qry = env->NewStringUTF(sql);
ncol = env->CallIntMethod(job, xqid, qry);
env->DeleteLocalRef(qry);
if (ncol < 0) { env->DeleteLocalRef(qry);
sprintf(g->Message, "Error executing %s: ncol = %d", sql, ncol); } // endif xqid
return RC_FX;
} else {
m_Ncol = (int)ncol;
m_Aff = 0; // Affected rows
} // endif ncol
return RC_OK; return RC_OK;
} // end of ExecuteQuery } // end of ExecuteQuery
...@@ -1447,34 +1440,27 @@ int JDBConn::ExecuteQuery(char *sql) ...@@ -1447,34 +1440,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 if (!gmID(g, xuid, "ExecuteUpdate", "(Ljava/lang/String;)I")) {
xuid = env->GetMethodID(jdi, "ExecuteUpdate", "(Ljava/lang/String;)I"); qry = env->NewStringUTF(sql);
n = env->CallIntMethod(job, xuid, qry);
if (xuid == nullptr) { if (!Check(n)) {
strcpy(g->Message, "Cannot find method ExecuteUpdate"); m_Ncol = 0;
return RC_FX; m_Aff = (int)n; // Affected rows
} // endif !xuid rc = RC_OK;
} else
} // endif xuid sprintf(g->Message, "ExecuteUpdate: %s n=%d", Msg, n);
qry = env->NewStringUTF(sql); env->DeleteLocalRef(qry);
n = env->CallIntMethod(job, xuid, qry); } // endif xuid
env->DeleteLocalRef(qry);
if (n < 0) { return rc;
sprintf(g->Message, "Error executing %s: n = %d", sql, n);
return RC_FX;
} else {
m_Ncol = 0;
m_Aff = (int)n; // Affected rows
} // endif n
return RC_OK;
} // end of ExecuteUpdate } // end of ExecuteUpdate
/***********************************************************************/ /***********************************************************************/
...@@ -1507,32 +1493,21 @@ int JDBConn::ExecuteSQL(void) ...@@ -1507,32 +1493,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 if (!gmID(g, xpid, "ExecutePrep", "()I")) {
xpid = env->GetMethodID(jdi, "ExecutePrep", "()I"); jint n = env->CallIntMethod(job, xpid);
if (xpid == nullptr) { if (n == -3)
strcpy(g->Message, "Cannot find method ExecutePrep"); strcpy(g->Message, "SQL statement is not prepared");
return rc; else if (Check(n))
} // endif xpid sprintf(g->Message, "ExecutePrep: %s", Msg);
else {
m_Aff = (int)n;
rc = RC_OK;
} // endswitch n
} // endif xpid } // endif xpid
jint n = env->CallIntMethod(job, xpid);
switch ((int)n) {
case -1:
case -2:
strcpy(g->Message, "Exception error thrown while executing SQL");
break;
case -3:
strcpy(g->Message, "SQL statement is not prepared");
break;
default:
m_Aff = (int)n;
rc = RC_OK;
} // endswitch n
return rc; return rc;
} // end of ExecuteSQL } // end of ExecuteSQL
...@@ -1542,8 +1517,7 @@ int JDBConn::ExecuteSQL(void) ...@@ -1542,8 +1517,7 @@ int JDBConn::ExecuteSQL(void)
bool JDBConn::SetParam(JDBCCOL *colp) bool JDBConn::SetParam(JDBCCOL *colp)
{ {
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
char *msg; bool rc = false;
int 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;
...@@ -1557,58 +1531,38 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1557,58 +1531,38 @@ bool JDBConn::SetParam(JDBCCOL *colp)
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 find 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);
...@@ -1627,11 +1581,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1627,11 +1581,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;
...@@ -1640,8 +1591,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1640,8 +1591,8 @@ bool JDBConn::SetParam(JDBCCOL *colp)
return true; return true;
} // endswitch Type } // endswitch Type
if ((msg = Check())) { if (Check()) {
sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), msg); sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), Msg);
rc = true; rc = true;
} // endif msg } // endif msg
...@@ -1707,14 +1658,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1707,14 +1658,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,
...@@ -1766,7 +1713,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1766,7 +1713,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
ushort i; ushort i;
jint *n = nullptr; 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) {
...@@ -1779,20 +1726,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1779,20 +1726,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);
...@@ -1813,11 +1748,28 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1813,11 +1748,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);
...@@ -1835,7 +1787,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1835,7 +1787,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. */
...@@ -1962,7 +1913,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -1962,7 +1913,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"
...@@ -2008,16 +1959,18 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -2008,16 +1959,18 @@ 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);
...@@ -2061,13 +2014,15 @@ bool JDBConn::SetParam(JDBCCOL *colp) ...@@ -2061,13 +2014,15 @@ bool JDBConn::SetParam(JDBCCOL *colp)
// Now fetch the result // Now fetch the result
for (i = 0; i < qrp->Maxres; i++) { for (i = 0; i < qrp->Maxres; i++) {
if ((rc = Fetch(0)) == 0) { if (Check(rc = Fetch(0))) {
sprintf(g->Message, "Fetch: %s", Msg);
return -1;
} if (rc == 0) {
if (trace) if (trace)
htrc("End of fetches i=%d\n", i); htrc("End of fetches i=%d\n", i);
break; break;
} else if (rc < 0) } // endif rc
return -1;
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]);
......
...@@ -120,7 +120,8 @@ class JDBConn : public BLOCK { ...@@ -120,7 +120,8 @@ class JDBConn : public BLOCK {
// JDBC operations // JDBC operations
protected: protected:
char *Check(void); 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 Free(void); //void Free(void);
...@@ -150,9 +151,11 @@ class JDBConn : public BLOCK { ...@@ -150,9 +151,11 @@ 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
//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;
......
/************* 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"
...@@ -101,11 +102,107 @@ JDBCDEF::JDBCDEF(void) ...@@ -101,11 +102,107 @@ JDBCDEF::JDBCDEF(void)
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, "%d", 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)
{ {
int rc = RC_OK;
Driver = GetStringCatInfo(g, "Driver", NULL); Driver = GetStringCatInfo(g, "Driver", NULL);
Desc = Url = GetStringCatInfo(g, "Connect", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL);
...@@ -120,28 +217,33 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -120,28 +217,33 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endif Connect } // endif Connect
Tabname = GetStringCatInfo(g, "Name", if (Url)
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); rc = ParseURL(g, Url);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Tabschema = GetStringCatInfo(g, "Dbname", NULL); if (rc == RC_FX) // Error
Tabschema = GetStringCatInfo(g, "Schema", Tabschema); return true;
Tabcat = GetStringCatInfo(g, "Qualifier", NULL); else if (rc == RC_OK) { // Url was not a server name
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); Tabname = GetStringCatInfo(g, "Name",
Tabtype = GetStringCatInfo(g, "Tabtype", NULL); (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Username = GetStringCatInfo(g, "User", NULL); Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Password = GetStringCatInfo(g, "Password", NULL); Username = GetStringCatInfo(g, "User", 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);
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);
...@@ -274,6 +376,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) ...@@ -274,6 +376,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);
......
...@@ -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;
...@@ -44,6 +45,8 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ ...@@ -44,6 +45,8 @@ 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
......
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