summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/ha_connect.cc34
-rw-r--r--storage/connect/jdbconn.cpp222
-rw-r--r--storage/connect/jdbconn.h22
-rw-r--r--storage/connect/reldef.cpp5
4 files changed, 171 insertions, 112 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index caa07c8cf88..7571392ff3a 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -129,6 +129,7 @@
#endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT)
#include "jdbccat.h"
+#include "jdbconn.h"
#endif // JDBC_SUPPORT
#include "xtable.h"
#include "tabmysql.h"
@@ -169,7 +170,7 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.04.0006 March 12, 2016";
+ char version[]= "Version 1.04.0006 May 08, 2016";
#if defined(__WIN__)
char compver[]= "Version 1.04.0006 " __DATE__ " " __TIME__;
char slash= '\\';
@@ -190,6 +191,10 @@ extern "C" {
} // extern "C"
#endif // XMSG
+#if defined(JDBC_SUPPORT)
+ char *JvmPath;
+#endif // JDBC_SUPPORT
+
#if defined(__WIN__)
CRITICAL_SECTION parsec; // Used calling the Flex parser
#else // !__WIN__
@@ -667,6 +672,9 @@ static int connect_init_func(void *p)
DTVAL::SetTimeShift(); // Initialize time zone shift once for all
BINCOL::SetEndian(); // Initialize host endian setting
+#if defined(JDBC_SUPPORT)
+ JDBConn::SetJVM();
+#endif // JDBC_SUPPORT
DBUG_RETURN(0);
} // end of connect_init_func
@@ -683,13 +691,17 @@ static int connect_done_func(void *)
#ifdef LIBXML2_SUPPORT
XmlCleanupParserLib();
-#endif // LIBXML2_SUPPORT
+#endif // LIBXML2_SUPPORT
-#if defined(__WIN__)
+#ifdef JDBC_SUPPORT
+ JDBConn::ResetJVM();
+#endif // JDBC_SUPPORT
+
+#if defined(__WIN__)
DeleteCriticalSection((LPCRITICAL_SECTION)&parsec);
-#else // !__WIN__
+#else // !__WIN__
PROFILE_End();
-#endif // !__WIN__
+#endif // !__WIN__
for (pc= user_connect::to_users; pc; pc= pn) {
if (pc->g)
@@ -6835,6 +6847,15 @@ static MYSQL_SYSVAR_STR(errmsg_dir_path, msg_path,
"../../../../storage/connect/"); // for testing
#endif // XMSG
+#if defined(JDBC_SUPPORT)
+static MYSQL_SYSVAR_STR(jvm_path, JvmPath,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "Path to the directory where is the JVM lib",
+ // check_jvm_path, update_jvm_path,
+ NULL, NULL, NULL);
+#endif // JDBC_SUPPORT
+
+
static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(xtrace),
MYSQL_SYSVAR(conv_size),
@@ -6852,7 +6873,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG
MYSQL_SYSVAR(json_grp_size),
- NULL
+ MYSQL_SYSVAR(jvm_path),
+ NULL
};
maria_declare_plugin(connect)
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index 093c746b59d..da1eb4eeb1d 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -17,17 +17,19 @@
#include <direct.h> // for getcwd
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
-#endif
+#endif // __BORLANDC__
//#include <windows.h>
-#else
+#else // !__WIN__
#if defined(UNIX)
#include <errno.h>
-#else
+#else // !UNIX
//nclude <io.h>
-#endif
+#endif // !UNIX
+#include <stdio.h>
+#include <stdlib.h> // for getenv
//nclude <fcntl.h>
#define NODW
-#endif
+#endif // !__WIN__
/***********************************************************************/
/* Required objects includes. */
@@ -52,6 +54,14 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !__WIN__
int GetConvSize();
+extern char *JvmPath; // The connect_jvm_path global variable value
+
+/***********************************************************************/
+/* Static JDBConn objects. */
+/***********************************************************************/
+void *JDBConn::LibJvm = NULL;
+CRTJVM JDBConn::CreateJavaVM = NULL;
+GETJVM JDBConn::GetCreatedJavaVMs = NULL;
/***********************************************************************/
/* Some macro's (should be defined elsewhere to be more accessible) */
@@ -618,90 +628,6 @@ PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table)
/************************************************************************/
return qrp;
} // 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
/***********************************************************************/
@@ -843,12 +769,97 @@ int JDBConn::GetMaxValue(int n)
} // 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;
+ } // 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 (JvmPath)
+ strcat(strcpy(soname, JvmPath), "\\jvm.dll");
+ else
+ strcpy(soname, "jvm.dll");
+
+#if defined(__WIN__)
+ // 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;
+ } // endif LibJvm
+#else // !__WIN__
+ const char *error = NULL;
+
+ // 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 = (CRTJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error));
+ dlclose(LibJvm);
+ LibJvm = NULL;
+ } // endif LibJvm
+#endif // !__WIN__
+
+ } // endif LibJvm
+
+ return LibJvm == NULL;
+} // end of GetJVM
+
+/***********************************************************************/
/* Open: connect to a data source. */
/***********************************************************************/
int JDBConn::Open(PSZ jpath, PJPARM sop)
{
PGLOBAL& g = m_G;
+
+ if (GetJVM(g))
+ return true;
+
PSTRG jpop = new(g) STRING(g, 512, "-Djava.class.path=");
+ char *cp = NULL;
char sep;
#if defined(__WIN__)
@@ -872,15 +883,26 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
//================== prepare loading of Java VM ============================
JavaVMInitArgs vm_args; // Initialization arguments
JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options
-
+
// where to find java .class
- jpop->Append(getenv("CLASSPATH"));
+ if ((cp = PlugDup(m_G, getenv("CLASSPATH"))))
+ jpop->Append(cp);
+
+ if (trace) {
+ htrc("CLASSPATH=%s\n", cp);
+ htrc("jpath=%s\n", jpath);
+ } // endif trace
+
+ if (jpath && *jpath) {
+ if (cp)
+ jpop->Append(sep);
- if (jpath) {
- jpop->Append(sep);
jpop->Append(jpath);
} // endif jpath
+ if (trace)
+ htrc("%s\n", jpop->GetStr());
+
options[0].optionString = jpop->GetStr();
//options[1].optionString = "-verbose:jni";
vm_args.version = JNI_VERSION_1_6; // minimum Java version
@@ -889,7 +911,7 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
//=============== load and initialize Java VM and JNI interface =============
- jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
+ jint rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
delete options; // we then no longer need the initialisation options.
switch (rc) {
@@ -914,7 +936,7 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
JavaVM* jvms[1];
jsize jsz;
- rc = JNI_GetCreatedJavaVMs(jvms, 1, &jsz);
+ rc = GetCreatedJavaVMs(jvms, 1, &jsz);
if (rc == JNI_OK && jsz == 1) {
jvm = jvms[0];
@@ -1952,6 +1974,9 @@ bool JDBConn::SetParam(JDBCCOL *colp)
// Not used anymore
env->DeleteLocalRef(parms);
+ if (trace)
+ htrc("Method %s returned %d columns\n", fnc, ncol);
+
// n because we no more ignore the first column
if ((n = qrp->Nbcol) > (uint)ncol) {
strcpy(g->Message, MSG(COL_NUM_MISM));
@@ -1989,9 +2014,12 @@ bool JDBConn::SetParam(JDBCCOL *colp)
// Now fetch the result
for (i = 0; i < qrp->Maxres; i++) {
- if ((rc = Fetch(0)) == 0)
+ if ((rc = Fetch(0)) == 0) {
+ if (trace)
+ htrc("End of fetches i=%d\n", i);
+
break;
- else if (rc < 0)
+ } else if (rc < 0)
return -1;
for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) {
diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h
index 99720bf55d5..b226d5d08d6 100644
--- a/storage/connect/jdbconn.h
+++ b/storage/connect/jdbconn.h
@@ -60,6 +60,9 @@ typedef struct tagJCATPARM {
PUCHAR Pat; // Table type or column pattern
} JCATPARM;
+typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *);
+typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *);
+
// JDBC connection to a data source
class TDBJDBC;
class JDBCCOL;
@@ -114,8 +117,11 @@ public:
PQRYRES GetMetaData(PGLOBAL g, char *src);
public:
- // Set special options
-//void OnSetOptions(HSTMT hstmt);
+ // Set static variables
+ static void SetJVM(void)
+ { LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; }
+ static void ResetJVM(void);
+ static bool GetJVM(PGLOBAL g);
// Implementation
public:
@@ -126,15 +132,17 @@ protected:
char *Check(void);
//void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/);
//void ThrowDJX(PSZ msg);
-//void AllocConnect(DWORD dwOptions);
-//void Connect(void);
-//bool DriverConnect(DWORD Options);
-//void VerifyConnect(void);
-//void GetConnectInfo(void);
//void Free(void);
protected:
// 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;
PGLOBAL m_G;
TDBJDBC *m_Tdb;
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 4b9d99bd8c9..2c8ada52e6f 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -514,10 +514,11 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
} // endif getdef
#else // !__WIN__
const char *error = NULL;
- Dl_info dl_info;
#if 0 // Don't know what all this stuff does
- // The OEM lib must retrieve exported CONNECT variables
+ Dl_info dl_info;
+
+ // The OEM lib must retrieve exported CONNECT variables
if (dladdr(&connect_hton, &dl_info)) {
if (dlopen(dl_info.dli_fname, RTLD_NOLOAD | RTLD_NOW | RTLD_GLOBAL) == 0) {
error = dlerror();