From 7b7414c0ef6a9f009c96483e60ebf1e5a6a6eb14 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 27 Apr 2016 12:36:55 +0200 Subject: - Add the JDBC table type compilation for CMAKE. modified: storage/connect/CMakeLists.txt - Fix MDEV-9993 modified: storage/connect/jsonudf.cpp --- storage/connect/CMakeLists.txt | 13 +++-- storage/connect/jsonudf.cpp | 128 +++++++++++++++++++++++++---------------- 2 files changed, 86 insertions(+), 55 deletions(-) diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index fe8940eb493..80a5b3bdc60 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -265,14 +265,17 @@ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) IF(CONNECT_WITH_JDBC) # TODO: detect Java SDK and the presence of JDBC connectors + # TODO: Find how to compile and install the JdbcInterface.java class # Find required libraries and include directories - # Find how to compile and install the JdbcInterface.java class - IF(JDBC_OK) - INCLUDE_DIRECTORIES(${JDBC_INCLUDE_DIR}) + FIND_PACKAGE(JAVA) + FIND_PACKAGE(JNI) + IF (JAVA_FOUND AND JNI_FOUND) + INCLUDE_DIRECTORIES(${JNI_INCLUDE_DIR}) + SET(JNI_LIBRARY ${JNI_LIBRARIES}) + SET(CONNECT_SOURCES ${CONNECT_SOURCES} JdbcInterface.java + jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) add_definitions(-DJDBC_SUPPORT) - SET(CONNECT_SOURCES ${CONNECT_SOURCES} - JdbcInterface.java tabjdbc.cpp jdbconn.cpp jdbccat.h jdbconn.h tabjdbc.h) ELSE() SET(JDBC_LIBRARY "") ENDIF() diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index eae872b81cc..0b5688c58ab 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -3538,37 +3538,9 @@ void jsoncontains_path_deinit(UDF_INIT* initid) } // end of jsoncontains_path_deinit /*********************************************************************************/ -/* Set Json items of a Json document according to path. */ +/* This function is used by the json_set/insert/update_item functions. */ /*********************************************************************************/ -my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) -{ - unsigned long reslen, memlen; - int n = IsJson(args, 0); - - if (!(args->arg_count % 2)) { - strcpy(message, "This function must have an odd number of arguments"); - return true; - } else if (!n && args->arg_type[0] != STRING_RESULT) { - strcpy(message, "First argument must be a json item"); - return true; - } else - CalcLen(args, false, reslen, memlen); - - if (n == 2 && args->args[0]) { - char fn[_MAX_PATH]; - long fl; - - memcpy(fn, args->args[0], args->lengths[0]); - fn[args->lengths[0]] = 0; - fl = GetFileLength(fn); - memlen += fl * 3; - } else if (n != 3) - memlen += args->lengths[0] * 3; - - return JsonInit(initid, args, message, true, reslen, memlen); -} // end of json_set_item_init - -char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, +char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) { char *p, *path, *str = NULL; @@ -3586,12 +3558,16 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - if (!strcmp(result, "$insert")) + if (!strcmp(result, "$set")) + w = 0; + else if (!strcmp(result, "$insert")) w = 1; else if (!strcmp(result, "$update")) w = 2; - else - w = 0; + else { + PUSH_WARNING("Logical error, please contact CONNECT developer"); + goto err; + } // endelse // Save stack and allocation environment and prepare error return if (g->jump_level == MAX_JUMP) { @@ -3660,10 +3636,10 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, // Keep result of constant function g->Activityp = (PACTIVITY)str; - err: +err: g->jump_level--; - fin: +fin: if (!str) { *is_null = 1; *res_length = 0; @@ -3671,6 +3647,44 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, *res_length = strlen(str); return str; +} // end of handle_item + +/*********************************************************************************/ +/* Set Json items of a Json document according to path. */ +/*********************************************************************************/ +my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + unsigned long reslen, memlen; + int n = IsJson(args, 0); + + if (!(args->arg_count % 2)) { + strcpy(message, "This function must have an odd number of arguments"); + return true; + } else if (!n && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + if (n == 2 && args->args[0]) { + char fn[_MAX_PATH]; + long fl; + + memcpy(fn, args->args[0], args->lengths[0]); + fn[args->lengths[0]] = 0; + fl = GetFileLength(fn); + memlen += fl * 3; + } else if (n != 3) + memlen += args->lengths[0] * 3; + + return JsonInit(initid, args, message, true, reslen, memlen); +} // end of json_set_item_init + +char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *p) +{ + strcpy(result, "$set"); + return handle_item(initid, args, result, res_length, is_null, p); } // end of json_set_item void json_set_item_deinit(UDF_INIT* initid) @@ -3690,7 +3704,7 @@ char *json_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$insert"); - return json_set_item(initid, args, result, res_length, is_null, p); + return handle_item(initid, args, result, res_length, is_null, p); } // end of json_insert_item void json_insert_item_deinit(UDF_INIT* initid) @@ -3710,7 +3724,7 @@ char *json_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$update"); - return json_set_item(initid, args, result, res_length, is_null, p); + return handle_item(initid, args, result, res_length, is_null, p); } // end of json_update_item void json_update_item_deinit(UDF_INIT* initid) @@ -4706,14 +4720,9 @@ void jbin_item_merge_deinit(UDF_INIT* initid) } // end of jbin_item_merge_deinit /*********************************************************************************/ -/* Set Json items of a Json document according to path. */ +/* This function is used by the jbin_set/insert/update functions. */ /*********************************************************************************/ -my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) -{ - return json_set_item_init(initid, args, message); -} // end of jbin_set_item_init - -char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, +char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) { char *p, *path; @@ -4732,12 +4741,16 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - if (!strcmp(result, "$insert")) + if (!strcmp(result, "$set")) + w = 0; + else if (!strcmp(result, "$insert")) w = 1; else if (!strcmp(result, "$update")) w = 2; - else - w = 0; + else { + PUSH_WARNING("Logical error, please contact CONNECT developer"); + goto fin; + } // endelse if (!g->Xchk) { if (CheckMemory(g, initid, args, 1, true, false, true)) { @@ -4791,7 +4804,7 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, // Keep result of constant function g->Activityp = (PACTIVITY)bsp; - fin: +fin: if (!bsp) { *is_null = 1; *res_length = 0; @@ -4799,6 +4812,21 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, *res_length = sizeof(BSON); return (char*)bsp; +} // end of bin_handle_item + +/*********************************************************************************/ +/* Set Json items of a Json document according to path. */ +/*********************************************************************************/ +my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + return json_set_item_init(initid, args, message); +} // end of jbin_set_item_init + +char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *p) +{ + strcpy(result, "$set"); + return bin_handle_item(initid, args, result, res_length, is_null, p); } // end of jbin_set_item void jbin_set_item_deinit(UDF_INIT* initid) @@ -4818,7 +4846,7 @@ char *jbin_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$insert"); - return jbin_set_item(initid, args, result, res_length, is_null, p); + return bin_handle_item(initid, args, result, res_length, is_null, p); } // end of jbin_insert_item void jbin_insert_item_deinit(UDF_INIT* initid) @@ -4838,7 +4866,7 @@ char *jbin_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$update"); - return jbin_set_item(initid, args, result, res_length, is_null, p); + return bin_handle_item(initid, args, result, res_length, is_null, p); } // end of jbin_update_item void jbin_update_item_deinit(UDF_INIT* initid) -- cgit v1.2.1 From bbdeb911b85ad10ae4a13308492e541384ec9889 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 27 Apr 2016 12:57:27 +0200 Subject: - Add the JdbcInterface.java to the project added: storage/connect/JdbcInterface.java - Add *.java to be handled modified: .gitattributes --- .gitattributes | 2 + storage/connect/JdbcInterface.java | 639 +++++++++++++++++++++++++++++++++++++ 2 files changed, 641 insertions(+) create mode 100644 storage/connect/JdbcInterface.java diff --git a/.gitattributes b/.gitattributes index 8aedbaa83d7..d11f2120249 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ *.cpp text *.h text *.test text +*.java text # Declare files that will always have LF line endings on checkout. *.result text eol=lf @@ -29,3 +30,4 @@ storage/connect/mysql-test/connect/std_data/*.dat binary *.cc diff=cpp *.ic diff=cpp *.cpp diff=cpp +*.java diff=cpp diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java new file mode 100644 index 00000000000..97f86b55a2c --- /dev/null +++ b/storage/connect/JdbcInterface.java @@ -0,0 +1,639 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.List; + +public class JdbcInterface { + boolean DEBUG = false; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + + // === Constructors/finalize ========================================= + public JdbcInterface() { + this(true); + } // end of default constructor + + public JdbcInterface(boolean b) { + DEBUG = b; + } // end of constructor + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + + if (DEBUG) + System.out.println("In JdbcInterface: driver=" + parms[0]); + + try { + if (DEBUG) + System.out.println("In try block"); + + if (parms[0] != null && !parms[0].isEmpty()) { + System.out.println("b is true!"); + Class.forName(parms[0]); //loads the driver + } // endif driver + + if (DEBUG) + System.out.println("URL=" + parms[1]); + + if (parms[2] != null && !parms[2].isEmpty()) { + if (DEBUG) + System.out.println("user=" + parms[2] + " pwd=" + parms[3]); + + conn = DriverManager.getConnection(parms[1], parms[2], parms[3]); + } else + conn = DriverManager.getConnection(parms[1]); + + if (DEBUG) + System.out.println("Connection " + conn.toString() + " established"); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch(ClassNotFoundException e) { + System.err.println("ClassNotFoundException: " + e.getMessage()); + rc = 1; + } catch (SQLException se) { + System.out.println("SQL Exception:"); + + // Loop through the SQL Exceptions + while (se != null) { + System.out.println("State : " + se.getSQLState()); + System.out.println("Message: " + se.getMessage()); + System.out.println("Error : " + se.getErrorCode()); + + se = se.getNextException(); + } // end while se + + rc = 2; + } catch( Exception e ) { + System.out.println(e); + rc = 3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public boolean CreatePrepStmt(String sql) { + boolean b = false; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + System.out.println(se); + b = true; + } catch (Exception e) { + System.out.println(e); + b = true; + } // end try/catch + + return b; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + System.out.println(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + System.out.println(se); + n = -1; + } catch (Exception e) { + System.out.println(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + System.out.println(se); + b = true; + } catch (Exception e) { + System.out.println(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + System.out.println(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + System.out.println("Closing result set"); + rs.close(); + } catch(SQLException se) { + System.out.println(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + System.out.println("Closing statement"); + stmt.close(); + } catch(SQLException se) { + System.out.println(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + System.out.println("Closing connection"); + conn.close(); + } catch (SQLException se) { + System.out.println(se); + rc += 8; + } //end try/catch + + System.out.println("All closed"); + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + System.out.println(e); + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + System.out.println(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + System.out.println(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + System.out.println(se); + n = -1; + } catch (Exception e) { + System.out.println(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + System.out.println(se); + ncol = -1; + } catch (Exception e) { + System.out.println(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + System.out.println(se); + ncol = -1; + } catch (Exception e) { + System.out.println(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + System.out.println(se); + n = -1; + } catch (Exception e) { + System.out.println(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteQuery + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + System.out.println(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + System.out.println(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + System.out.println("ColumnType: " + se); + } //end try/catch + + return 0; + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of ColumnType + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : null; + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of TimestampField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + +} // end of class JdbcInterface -- cgit v1.2.1 From 80a204f27e91629a97a5d41e06bc8e4128a4ae86 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 5 May 2016 01:03:26 +0200 Subject: - Try to fix MDEV-9950 (not tested yet) modified: storage/connect/ha_connect.cc modified: storage/connect/plgdbutl.cpp - Fix Mdev-9997 (Sergey Vojtovitch) modified: storage/connect/inihandl.c - Try to have the JDBC type compiled by CMake modified: storage/connect/CMakeLists.txt - Fixing some bugs in the JDBC table type Use the CONNECTION option for the URL modified: storage/connect/ha_connect.cc modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h modified: storage/connect/tabjdbc.cpp - Add the JdbcInterface.class to the project new file: storage/connect/JdbcInterface.class --- storage/connect/CMakeLists.txt | 12 +++--- storage/connect/JdbcInterface.class | Bin 0 -> 15117 bytes storage/connect/JdbcInterface.java | 2 +- storage/connect/ha_connect.cc | 19 +++++--- storage/connect/inihandl.c | 7 ++- storage/connect/jdbconn.cpp | 84 ++++++++++++++++-------------------- storage/connect/jdbconn.h | 2 +- storage/connect/plgdbutl.cpp | 29 ++++++------- storage/connect/tabjdbc.cpp | 16 +++++-- 9 files changed, 90 insertions(+), 81 deletions(-) create mode 100644 storage/connect/JdbcInterface.class diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index 80a5b3bdc60..f4bcbfa9ade 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -268,12 +268,14 @@ IF(CONNECT_WITH_JDBC) # TODO: Find how to compile and install the JdbcInterface.java class # Find required libraries and include directories - FIND_PACKAGE(JAVA) - FIND_PACKAGE(JNI) + FIND_PACKAGE(Java REQUIRED) + FIND_PACKAGE(JNI REQUIRED) IF (JAVA_FOUND AND JNI_FOUND) - INCLUDE_DIRECTORIES(${JNI_INCLUDE_DIR}) - SET(JNI_LIBRARY ${JNI_LIBRARIES}) - SET(CONNECT_SOURCES ${CONNECT_SOURCES} JdbcInterface.java + INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH}) + INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH2}) + SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) + SET(CONNECT_SOURCES ${CONNECT_SOURCES} + JdbcInterface.java JdbcInterface.class jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) add_definitions(-DJDBC_SUPPORT) ELSE() diff --git a/storage/connect/JdbcInterface.class b/storage/connect/JdbcInterface.class new file mode 100644 index 00000000000..816f575212b Binary files /dev/null and b/storage/connect/JdbcInterface.class differ diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java index 97f86b55a2c..5e01516d0cb 100644 --- a/storage/connect/JdbcInterface.java +++ b/storage/connect/JdbcInterface.java @@ -536,7 +536,7 @@ public class JdbcInterface { System.out.println("No result set"); } else try { BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); - return bigDecimal != null ? bigDecimal.longValue() : null; + return bigDecimal != null ? bigDecimal.longValue() : 0; } catch (SQLException se) { System.out.println(se); } //end try/catch diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 9f75d3bf54b..caa07c8cf88 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -190,6 +190,12 @@ extern "C" { } // extern "C" #endif // XMSG +#if defined(__WIN__) +CRITICAL_SECTION parsec; // Used calling the Flex parser +#else // !__WIN__ +pthread_mutex_t parmut; +#endif // !__WIN__ + /***********************************************************************/ /* Utility functions. */ /***********************************************************************/ @@ -634,6 +640,7 @@ static int connect_init_func(void *p) #if defined(__WIN__) sql_print_information("CONNECT: %s", compver); + InitializeCriticalSection((LPCRITICAL_SECTION)&parsec); #else // !__WIN__ sql_print_information("CONNECT: %s", version); #endif // !__WIN__ @@ -678,8 +685,10 @@ static int connect_done_func(void *) XmlCleanupParserLib(); #endif // LIBXML2_SUPPORT -#if !defined(__WIN__) -//PROFILE_End(); Causes signal 11 +#if defined(__WIN__) + DeleteCriticalSection((LPCRITICAL_SECTION)&parsec); +#else // !__WIN__ + PROFILE_End(); #endif // !__WIN__ for (pc= user_connect::to_users; pc; pc= pn) { @@ -5172,7 +5181,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, spc= (!sep) ? ',' : *sep; qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0; hdr= (int)topt->header; - tbl= topt->tablist; + tbl= topt->tablist; col= topt->colist; if (topt->oplist) { @@ -5305,8 +5314,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd, case TAB_JDBC: if (fnc & FNC_DRIVER) { ok= true; - } else if (!url) { - strcpy(g->Message, "Missing URL"); + } else if (!url && !(url= strz(g, create_info->connect_string))) { + strcpy(g->Message, "Missing URL"); } else { // Store ODBC additional parameters sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM)); diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.c index 542b807f899..46102557b20 100644 --- a/storage/connect/inihandl.c +++ b/storage/connect/inihandl.c @@ -622,13 +622,16 @@ void PROFILE_End(void) if (trace) htrc("PROFILE_End: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES); + if (!CurProfile) // Sergey Vojtovich + return; + /* Close all opened files and free the cache structure */ for (i = 0; i < N_CACHED_PROFILES; i++) { if (trace) htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i); - CurProfile = MRUProfile[i]; - PROFILE_ReleaseFile(); +// CurProfile = MRUProfile[i]; Sergey Vojtovich +// PROFILE_ReleaseFile(); see MDEV-9997 free(MRUProfile[i]); } // endfor i diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index cf744971c9e..4ad491951a7 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -741,32 +741,33 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) // } // end of ~JDBConn -#if 0 /***********************************************************************/ /* Screen for errors. */ /***********************************************************************/ -bool JDBConn::Check(RETCODE rc) +char *JDBConn::Check(void) { - switch (rc) { - case SQL_SUCCESS_WITH_INFO: - if (trace) { - DJX x(rc); - - if (x.BuildErrorMessage(this, m_hstmt)) - htrc("JDBC Success With Info, hstmt=%p %s\n", - m_hstmt, x.GetErrorMessage(0)); - - } // endif trace + if (env->ExceptionCheck()) { + char *msg; + jthrowable exc = env->ExceptionOccurred(); + jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), + "toString", "()Ljava/lang/String;"); + + 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"; - // Fall through - case SQL_SUCCESS: - case SQL_NO_DATA_FOUND: - return true; - } // endswitch rc + env->ExceptionClear(); + return msg; + } // endif Check - return false; + return NULL; } // end of Check +#if 0 /***********************************************************************/ /* Utility routine. */ /***********************************************************************/ @@ -911,14 +912,10 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) 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); + rc = jvm->AttachCurrentThread((void**)&env, nullptr); } // endif rc + } // end of block if (rc == JNI_OK) @@ -1176,11 +1173,11 @@ void JDBConn::Close() void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) { PGLOBAL& g = m_G; + char *msg; jint ctyp; jlong dtv; jstring cn, jn = nullptr; jobject dob; - jthrowable exc; jmethodID fldid = nullptr; if (rank == 0) @@ -1191,14 +1188,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ctyp = env->CallIntMethod(job, typid, rank, jn); - if ((exc = env->ExceptionOccurred()) != nullptr) { - jboolean isCopy = false; - 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(); + if ((msg = Check())) { + sprintf(g->Message, "Getting ctyp: %s", msg); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); } // endif Check @@ -1305,6 +1296,14 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) val->Reset(); } // endswitch Type + if ((msg = 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) env->DeleteLocalRef(jn); @@ -1467,6 +1466,7 @@ int JDBConn::ExecuteSQL(void) bool JDBConn::SetParam(JDBCCOL *colp) { PGLOBAL& g = m_G; + char *msg; int rc = false; PVAL val = colp->GetValue(); jint n, i = (jint)colp->GetRank(); @@ -1477,7 +1477,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) jclass dat; jobject datobj; jstring jst = nullptr; - jthrowable exc; jmethodID dtc, setid = nullptr; switch (val->GetType()) { @@ -1531,7 +1530,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) setid = env->GetMethodID(jdi, "SetDoubleParm", "(ID)V"); if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetDoubleParm"); + strcpy(g->Message, "Cannot find method SetDoubleParm"); return true; } // endif setid @@ -1565,16 +1564,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) return true; } // endswitch Type - if ((exc = env->ExceptionOccurred()) != nullptr) { - jboolean isCopy = false; - 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(); + if ((msg = Check())) { + sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), msg); rc = true; - } // endif exc + } // endif msg if (jst) env->DeleteLocalRef(jst); @@ -1987,7 +1980,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) } // endfor n // Now fetch the result - // Extended fetch cannot be used because of STRBLK's for (i = 0; i < qrp->Maxres; i++) { if ((rc = Fetch(0)) == 0) break; @@ -2001,7 +1993,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) } // endfor i - if (rc == RC_OK) + if (rc > 0) qrp->Truncated = true; return i; diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index 0646fee845b..99720bf55d5 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -123,7 +123,7 @@ public: // JDBC operations protected: -//bool Check(RETCODE rc); + char *Check(void); //void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/); //void ThrowDJX(PSZ msg); //void AllocConnect(DWORD dwOptions); diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index d70eeb32a04..799df7cfc51 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -46,9 +46,9 @@ #else // !__WIN__ #include #include -#if defined(THREAD) +//#if defined(THREAD) #include -#endif // THREAD +//#endif // THREAD #include #define BIGMEM 2147483647 // Max int value #endif // !__WIN__ @@ -69,17 +69,6 @@ #include "valblk.h" #include "rcmsg.h" -/***********************************************************************/ -/* Macro or external routine definition */ -/***********************************************************************/ -#if defined(THREAD) -#if defined(__WIN__) -extern CRITICAL_SECTION parsec; // Used calling the Flex parser -#else // !__WIN__ -extern pthread_mutex_t parmut; -#endif // !__WIN__ -#endif // THREAD - /***********************************************************************/ /* DB static variables. */ /***********************************************************************/ @@ -90,6 +79,12 @@ extern "C" { extern char version[]; } // extern "C" +#if defined(__WIN__) +extern CRITICAL_SECTION parsec; // Used calling the Flex parser +#else // !__WIN__ +extern pthread_mutex_t parmut; +#endif // !__WIN__ + // The debug trace used by the main thread FILE *pfile = NULL; @@ -702,21 +697,21 @@ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag) /* Call the FLEX generated parser. In multi-threading mode the next */ /* instruction is included in an Enter/LeaveCriticalSection bracket. */ /*********************************************************************/ -#if defined(THREAD) + //#if defined(THREAD) #if defined(__WIN__) EnterCriticalSection((LPCRITICAL_SECTION)&parsec); #else // !__WIN__ pthread_mutex_lock(&parmut); #endif // !__WIN__ -#endif // THREAD +//#endif // THREAD rc = fmdflex(pdp); -#if defined(THREAD) +//#if defined(THREAD) #if defined(__WIN__) LeaveCriticalSection((LPCRITICAL_SECTION)&parsec); #else // !__WIN__ pthread_mutex_unlock(&parmut); #endif // !__WIN__ -#endif // THREAD +//#endif // THREAD if (trace) htrc("Done: in=%s out=%s rc=%d\n", SVP(pdp->InFmt), SVP(pdp->OutFmt), rc); diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index 97168646ba0..ce73349d9f7 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -108,11 +108,17 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Jpath = GetStringCatInfo(g, "Jpath", ""); Driver = GetStringCatInfo(g, "Driver", NULL); - Desc = Url = GetStringCatInfo(g, "Url", NULL); + Desc = Url = GetStringCatInfo(g, "Connect", NULL); if (!Url && !Catfunc) { - sprintf(g->Message, "Missing URL for JDBC table %s", Name); - return true; + // Look in the option list (deprecated) + Url = GetStringCatInfo(g, "Url", NULL); + + if (!Url) { + sprintf(g->Message, "Missing URL for JDBC table %s", Name); + return true; + } // endif Url + } // endif Connect Tabname = GetStringCatInfo(g, "Name", @@ -198,7 +204,7 @@ int JDBCPARM::CheckSize(int rows) if (Url && rows == 1) { // Are we connected to a MySQL JDBC connector? bool b = (!strncmp(Url, "jdbc:mysql:", 11) || - !strncmp(Url, "jdbc:mariadb:", 13)); + !strncmp(Url, "jdbc:mariadb:", 13)); return b ? INT_MIN32 : rows; } else return rows; @@ -1669,6 +1675,8 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) Ops.Url = tdp->Url; Ops.User = tdp->Username; Ops.Pwd = tdp->Password; + Ops.Fsize = 0; + Ops.Scrollable = false; } // end of TDBJTB constructor /***********************************************************************/ -- cgit v1.2.1 From 025decfc38c00e8e04b433f13b22e2f32122abff Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 6 May 2016 01:07:14 +0200 Subject: - Remove gcc compiling errors and warnings modified: storage/connect/jdbconn.cpp modified: storage/connect/tabjdbc.h --- storage/connect/jdbconn.cpp | 36 ++++++++++++++++++++++-------------- storage/connect/tabjdbc.h | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 4ad491951a7..093c746b59d 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -47,7 +47,9 @@ #if defined(__WIN__) extern "C" HINSTANCE s_hModule; // Saved module handle -#endif // __WIN__ +#else // !__WIN__ +#define nullptr 0 +#endif // !__WIN__ int GetConvSize(); @@ -62,6 +64,9 @@ int GetConvSize(); #define DEBUG_ONLY(f) ((void)0) #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. */ /***********************************************************************/ @@ -155,7 +160,7 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db, char *tab, PQRYRES qrp) { - size_t m, n; +//size_t m, n; JCATPARM *cap; #if defined(_DEBUG) @@ -174,8 +179,8 @@ static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db, goto fin; } // endif rc - m = (size_t)qrp->Maxres; - n = (size_t)qrp->Nbcol; +//m = (size_t)qrp->Maxres; +//n = (size_t)qrp->Nbcol; cap = (JCATPARM *)PlugSubAlloc(g, NULL, sizeof(JCATPARM)); memset(cap, 0, sizeof(JCATPARM)); cap->Id = fid; @@ -1157,10 +1162,12 @@ void JDBConn::Close() if (did == nullptr) printf("ERROR: method JdbcDisconnect() not found !"); - else - rc = env->CallIntMethod(job, did); + else if ((rc = env->CallIntMethod(job, did))) + printf("jdbcDisconnect: rc=%d", (int)rc); + + if ((rc = jvm->DetachCurrentThread())) + printf("DetachCurrentThread: rc = %d", (int)rc); - rc = jvm->DetachCurrentThread(); //rc = jvm->DestroyJavaVM(); m_Opened = false; } // endif m_Opened @@ -1687,8 +1694,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) int len, qcol = 5; PQRYRES qrp = NULL; PCOLRES crp; - USHORT i; - jint *n; + ushort i; + jint *n = nullptr; jstring label; jmethodID colid; int rc = ExecSQLcommand(src); @@ -1872,7 +1879,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) int JDBConn::GetCatInfo(JCATPARM *cap) { PGLOBAL& g = m_G; - void *buffer; +// void *buffer; int i; PSZ fnc = "Unknown"; uint n, ncol; @@ -1946,7 +1953,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) env->DeleteLocalRef(parms); // 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)); return -1; } // endif n @@ -1972,9 +1979,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) if (crp->Type == TYPE_STRING) { pbuf[n] = (char*)PlugSubAlloc(g, NULL, len); - buffer = pbuf[n]; - } else - buffer = pval[n]->GetTo_Val(); +// buffer = pbuf[n]; + } // endif Type +// } else +// buffer = pval[n]->GetTo_Val(); n++; } // endfor n diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h index b6cf91e28b8..d3ac3784d2f 100644 --- a/storage/connect/tabjdbc.h +++ b/storage/connect/tabjdbc.h @@ -73,7 +73,7 @@ protected: }; // end of JDBCDEF #if !defined(NJDBC) -#include "JDBConn.h" +#include "jdbconn.h" /***********************************************************************/ /* This is the JDBC Access Method class declaration for files from */ -- cgit v1.2.1 From 2323cf003387af35b126988eb6e57f1dff7dd996 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 9 May 2016 17:26:50 +0200 Subject: - Make the JVM lib dynamically loaded This makes the CONNECT storage engine usable when Java JDK is not installed. modified: storage/connect/ha_connect.cc modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h - Typo modified: storage/connect/reldef.cpp --- storage/connect/ha_connect.cc | 34 +++++-- storage/connect/jdbconn.cpp | 222 ++++++++++++++++++++++++------------------ storage/connect/jdbconn.h | 22 +++-- storage/connect/reldef.cpp | 5 +- 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 // for getcwd #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro -#endif +#endif // __BORLANDC__ //#include -#else +#else // !__WIN__ #if defined(UNIX) #include -#else +#else // !UNIX //nclude -#endif +#endif // !UNIX +#include +#include // for getenv //nclude #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 /***********************************************************************/ @@ -842,13 +768,98 @@ int JDBConn::GetMaxValue(int n) return (int)env->CallIntMethod(job, maxid, 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(); -- cgit v1.2.1 From 6aa163bce8279ed6e67cfa825004ba025ebe12d8 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 12 May 2016 12:20:52 +0200 Subject: - Continue working on the JDBC table type Suppress the jpath option add the connect_jvm_path and connect_class_path global variables modified: storage/connect/ha_connect.cc modified: storage/connect/jdbccat.h modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h modified: storage/connect/tabjdbc.cpp modified: storage/connect/tabjdbc.h - Add the envar UDF modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h - Fix MDEV-9950 modified: storage/connect/ha_connect.cc modified: storage/connect/plgdbutl.cpp --- storage/connect/ha_connect.cc | 23 ++-- storage/connect/jdbccat.h | 8 +- storage/connect/jdbconn.cpp | 247 +++++++++++++++++++++++++----------------- storage/connect/jdbconn.h | 11 +- storage/connect/jsonudf.cpp | 27 +++++ storage/connect/jsonudf.h | 4 + storage/connect/plgdbutl.cpp | 2 +- storage/connect/tabjdbc.cpp | 19 ++-- storage/connect/tabjdbc.h | 7 +- 9 files changed, 207 insertions(+), 141 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 7571392ff3a..58a761f442d 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -193,12 +193,13 @@ extern "C" { #if defined(JDBC_SUPPORT) char *JvmPath; + char *ClassPath; #endif // JDBC_SUPPORT #if defined(__WIN__) CRITICAL_SECTION parsec; // Used calling the Flex parser #else // !__WIN__ -pthread_mutex_t parmut; +pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER; #endif // !__WIN__ /***********************************************************************/ @@ -5156,7 +5157,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd, #endif // ODBC_SUPPORT #if defined(JDBC_SUPPORT) PJPARM sjp= NULL; - char *jpath= NULL; char *driver= NULL; char *url= NULL; char *tabtyp = NULL; @@ -5223,7 +5223,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd, cnc= (!*ucnc || *ucnc == 'y' || *ucnc == 'Y' || atoi(ucnc) != 0); #endif #if defined(JDBC_SUPPORT) - jpath= GetListOption(g, "Jpath", topt->oplist, NULL); driver= GetListOption(g, "Driver", topt->oplist, NULL); url= GetListOption(g, "URL", topt->oplist, NULL); tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL); @@ -5510,15 +5509,14 @@ static int connect_assisted_discovery(handlerton *, THD* thd, case FNC_NO: case FNC_COL: if (src) { - qrp= JDBCSrcCols(g, jpath, (char*)src, sjp); + qrp= JDBCSrcCols(g, (char*)src, sjp); src= NULL; // for next tests } else - qrp= JDBCColumns(g, jpath, shm, tab, NULL, - mxr, fnc == FNC_COL, sjp); + qrp= JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp); break; case FNC_TABLE: - qrp= JDBCTables(g, dsn, shm, tab, tabtyp, mxr, true, sjp); + qrp= JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp); break; #if 0 case FNC_DSN: @@ -5526,7 +5524,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, break; #endif // 0 case FNC_DRIVER: - qrp= JDBCDrivers(g, jpath, mxr, true); + qrp= JDBCDrivers(g, mxr, true); break; default: sprintf(g->Message, "invalid catfunc %s", fncn); @@ -6853,6 +6851,12 @@ static MYSQL_SYSVAR_STR(jvm_path, JvmPath, "Path to the directory where is the JVM lib", // check_jvm_path, update_jvm_path, NULL, NULL, NULL); + +static MYSQL_SYSVAR_STR(class_path, ClassPath, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Java class path", + // check_class_path, update_class_path, + NULL, NULL, NULL); #endif // JDBC_SUPPORT @@ -6873,7 +6877,10 @@ static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(errmsg_dir_path), #endif // XMSG MYSQL_SYSVAR(json_grp_size), +#if defined(JDBC_SUPPORT) MYSQL_SYSVAR(jvm_path), + MYSQL_SYSVAR(class_path), +#endif // JDBC_SUPPORT NULL }; diff --git a/storage/connect/jdbccat.h b/storage/connect/jdbccat.h index 150197804d5..37f33d7063d 100644 --- a/storage/connect/jdbccat.h +++ b/storage/connect/jdbccat.h @@ -21,9 +21,9 @@ typedef struct jdbc_parms { char *JDBCCheckConnection(PGLOBAL g, char *dsn, int cop); #endif // PROMPT_OK //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); -PQRYRES JDBCSrcCols(PGLOBAL g, char *jpath, char *src, PJPARM sop); -PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, +PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sop); +PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, 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); diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index da1eb4eeb1d..fe93ba9a62f 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -54,7 +54,8 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #endif // !__WIN__ int GetConvSize(); -extern char *JvmPath; // The connect_jvm_path global variable value +extern char *JvmPath; // The connect_jvm_path global variable value +extern char *ClassPath; // The connect_class_path global variable value /***********************************************************************/ /* Static JDBConn objects. */ @@ -213,8 +214,8 @@ fin: /* JDBCColumns: constructs the result blocks containing all columns */ /* of a JDBC table that will be retrieved by GetData commands. */ /***********************************************************************/ -PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, - char *colpat, int maxres, bool info, PJPARM sjp) +PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, + int maxres, bool info, PJPARM sjp) { int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, @@ -236,7 +237,7 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, if (!info) { 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; if (table && !strchr(table, '%')) { @@ -315,11 +316,11 @@ PQRYRES JDBCColumns(PGLOBAL g, char *jpath, char *db, char *table, /* JDBCSrcCols: constructs the result blocks containing the */ /* 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) { JDBConn *jcp = new(g)JDBConn(g, NULL); - if (jcp->Open(jpath, sjp)) + if (jcp->Open(sjp)) return NULL; return jcp->GetMetaData(g, src); @@ -329,8 +330,8 @@ PQRYRES JDBCSrcCols(PGLOBAL g, char *jpath, char *src, PJPARM sjp) /* JDBCTables: constructs the result blocks containing all tables in */ /* an JDBC database that will be retrieved by GetData commands. */ /**************************************************************************/ -PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, - char *tabtyp, int maxres, bool info, PJPARM sjp) +PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, + int maxres, bool info, PJPARM sjp) { int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING}; @@ -352,7 +353,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, /**********************************************************************/ jcp = new(g)JDBConn(g, NULL); - if (jcp->Open(jpath, sjp) == RC_FX) + if (jcp->Open(sjp) == RC_FX) return NULL; if (!maxres) @@ -429,7 +430,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *jpath, char *db, char *tabpat, /* drivers available on the local host. */ /* 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}; XFLD fldtyp[] ={FLD_NAME, FLD_EXTRA, FLD_DEFAULT, FLD_REM }; @@ -446,7 +447,7 @@ PQRYRES JDBCDrivers(PGLOBAL g, char *jpath, int maxres, bool info) if (!info) { jcp = new(g) JDBConn(g, NULL); - if (jcp->Open(jpath, NULL) != RC_OK) + if (jcp->Open(NULL) != RC_OK) return NULL; if (!maxres) @@ -796,12 +797,12 @@ 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"); -#if defined(__WIN__) // Load the desired shared library if (!(LibJvm = LoadLibrary(soname))) { char buf[256]; @@ -826,6 +827,11 @@ bool JDBConn::GetJVM(PGLOBAL g) #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(); @@ -835,7 +841,7 @@ bool JDBConn::GetJVM(PGLOBAL g) sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error)); dlclose(LibJvm); LibJvm = NULL; - } else if (!(GetCreatedJavaVMs = (CRTJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) { + } else if (!(GetCreatedJavaVMs = (GETJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) { error = dlerror(); sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error)); dlclose(LibJvm); @@ -851,112 +857,103 @@ bool JDBConn::GetJVM(PGLOBAL g) /***********************************************************************/ /* Open: connect to a data source. */ /***********************************************************************/ -int JDBConn::Open(PSZ jpath, PJPARM sop) +int JDBConn::Open(PJPARM sop) { PGLOBAL& g = m_G; + // Link or check whether jvm library was linked if (GetJVM(g)) return true; - PSTRG jpop = new(g) STRING(g, 512, "-Djava.class.path="); - char *cp = NULL; - char sep; - -#if defined(__WIN__) - sep = ';'; -#else - sep = ':'; -#endif + // Firstly check whether the jvm was already created + JavaVM* jvms[1]; + jsize jsz; + jint rc = GetCreatedJavaVMs(jvms, 1, &jsz); - 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 + if (rc == JNI_OK && jsz == 1) { + // jvm already existing + jvm = jvms[0]; + rc = jvm->AttachCurrentThread((void**)&env, nullptr); - //================== prepare loading of Java VM ============================ - JavaVMInitArgs vm_args; // Initialization arguments - JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options - - // where to find java .class - 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); - - jpop->Append(jpath); - } // endif jpath + if (rc != JNI_OK) { + strcpy(g->Message, "Cannot attach jvm to the current thread"); + return RC_FX; + } // endif rc - if (trace) - htrc("%s\n", jpop->GetStr()); + } else { + // Create a new jvm + PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path="); + char *cp = NULL; + char sep; - options[0].optionString = jpop->GetStr(); -//options[1].optionString = "-verbose:jni"; - vm_args.version = JNI_VERSION_1_6; // minimum Java version - vm_args.nOptions = 1; // number of options - vm_args.options = options; - vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail +#if defined(__WIN__) + sep = ';'; +#else + sep = ':'; +#endif - //=============== load and initialize Java VM and JNI interface ============= - jint rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !! - delete options; // we then no longer need the initialisation options. + //================== prepare loading of Java VM ============================ + JavaVMInitArgs vm_args; // Initialization arguments + JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options - switch (rc) { - case JNI_OK: - strcpy(g->Message, "VM successfully created"); - break; - case JNI_ERR: - strcpy(g->Message, "Initialising JVM failed: unknown error"); - return RC_FX; - case JNI_EDETACHED: - strcpy(g->Message, "Thread detached from the VM"); - return RC_FX; - case JNI_EVERSION: - strcpy(g->Message, "JNI version error"); - return RC_FX; - case JNI_ENOMEM: - strcpy(g->Message, "Not enough memory"); - return RC_FX; - case JNI_EEXIST: - strcpy(g->Message, "VM already created"); - { - JavaVM* jvms[1]; - jsize jsz; + // where to find java .class + if ((cp = PlugDup(m_G, getenv("CLASSPATH")))) + jpop->Append(cp); - rc = GetCreatedJavaVMs(jvms, 1, &jsz); + if (trace) { + htrc("CLASSPATH=%s\n", getenv("CLASSPATH")); + htrc("ClassPath=%s\n", ClassPath); + } // endif trace - if (rc == JNI_OK && jsz == 1) { - jvm = jvms[0]; - rc = jvm->AttachCurrentThread((void**)&env, nullptr); - } // endif rc + if (ClassPath && *ClassPath) { + if (cp) + jpop->Append(sep); - } // end of block + jpop->Append(ClassPath); + } // endif ClassPath - if (rc == JNI_OK) + 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 + vm_args.nOptions = 1; // number of options + vm_args.options = options; + vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail + + //=============== load and initialize Java VM and JNI interface ============= + rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !! + delete options; // we then no longer need the initialisation options. + + switch (rc) { + case JNI_OK: + strcpy(g->Message, "VM successfully created"); break; - else + case JNI_ERR: + strcpy(g->Message, "Initialising JVM failed: unknown error"); return RC_FX; + case JNI_EDETACHED: + strcpy(g->Message, "Thread detached from the VM"); + return RC_FX; + case JNI_EVERSION: + strcpy(g->Message, "JNI version error"); + return RC_FX; + case JNI_ENOMEM: + strcpy(g->Message, "Not enough memory"); + return RC_FX; + case JNI_EEXIST: + strcpy(g->Message, "VM already created"); + return RC_FX; + case JNI_EINVAL: + strcpy(g->Message, "Invalid arguments"); + return RC_FX; + default: + sprintf(g->Message, "Unknown return code %d", rc); + return RC_FX; + } // endswitch rc - case JNI_EINVAL: - strcpy(g->Message, "Invalid arguments"); - return RC_FX; - default: - sprintf(g->Message, "Unknown return code %d", rc); - return RC_FX; - } // endswitch rc + } // endif rc //=============== Display JVM version ======================================= //jint ver = env->GetVersion(); @@ -970,6 +967,44 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) return RC_FX; } // 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())) { + 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 jmethodID ctor = env->GetMethodID(jdi, "", "()V"); @@ -1003,6 +1038,18 @@ int JDBConn::Open(PSZ jpath, PJPARM sop) jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4 env->FindClass("java/lang/String"), NULL); // Strings + 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 + // change some elements if (m_Driver) env->SetObjectArrayElement(parms, 0, env->NewStringUTF(m_Driver)); diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index b226d5d08d6..4014a52cdcc 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -32,15 +32,6 @@ typedef unsigned char *PUCHAR; #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 { CAT_TAB = 1, // JDBC Tables CAT_COL = 2, // JDBC Columns @@ -82,7 +73,7 @@ private: public: JDBConn(PGLOBAL g, TDBJDBC *tdbp); - int Open(PSZ jpath, PJPARM sop); + int Open(PJPARM sop); int Rewind(char *sql); void Close(void); PQRYRES AllocateResult(PGLOBAL g); diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 0b5688c58ab..d377b7d4b63 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -5027,3 +5027,30 @@ void json_serialize_deinit(UDF_INIT* initid) { JsonFreeMem((PGLOBAL)initid->ptr); } // end of json_serialize_deinit + +/*********************************************************************************/ +/* Utility function returning an environment variable value. */ +/*********************************************************************************/ +my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + if (args->arg_count != 1) { + strcpy(message, "Unique argument must be an environment variable name"); + return true; + } else + return false; + +} // end of envar_init + +char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *, char *) +{ + char *str, name[256]; + int n = MY_MIN(args->lengths[0], sizeof(name) - 1); + + memcpy(name, args->args[0], n); + name[n] = 0; + str = getenv(name); + *res_length = (str) ? strlen(str) : 0; + return str; +} // end of envar + diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h index b7e9b8ecabb..1406d9f2f2e 100644 --- a/storage/connect/jsonudf.h +++ b/storage/connect/jsonudf.h @@ -218,8 +218,12 @@ extern "C" { DllExport my_bool json_serialize_init(UDF_INIT*, UDF_ARGS*, char*); DllExport char *json_serialize(UDF_EXEC_ARGS); DllExport void json_serialize_deinit(UDF_INIT*); + + DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*); + DllExport char *envar(UDF_EXEC_ARGS); } // extern "C" + /*********************************************************************************/ /* Structure JPN. Used to make the locate path. */ /*********************************************************************************/ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 799df7cfc51..13c0dfd1e18 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index ce73349d9f7..37850ce6358 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -95,7 +95,7 @@ bool ExactInfo(void); /***********************************************************************/ JDBCDEF::JDBCDEF(void) { - Jpath = Driver = Url = Tabname = Tabschema = Username = NULL; + Driver = Url = Tabname = Tabschema = Username = NULL; Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL; Options = Quoted = Maxerr = Maxres = Memory = 0; Scrollable = Xsrc = false; @@ -106,7 +106,6 @@ JDBCDEF::JDBCDEF(void) /***********************************************************************/ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { - Jpath = GetStringCatInfo(g, "Jpath", ""); Driver = GetStringCatInfo(g, "Driver", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL); @@ -222,7 +221,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) Cnp = NULL; if (tdp) { - Jpath = tdp->Jpath; Ops.Driver = tdp->Driver; Ops.Url = tdp->Url; TableName = tdp->Tabname; @@ -241,7 +239,6 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) Memory = tdp->Memory; Ops.Scrollable = tdp->Scrollable; } else { - Jpath = NULL; TableName = NULL; Schema = NULL; Ops.Driver = NULL; @@ -286,7 +283,6 @@ TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp) { Jcp = tdbp->Jcp; // is that right ? Cnp = tdbp->Cnp; - Jpath = tdbp->Jpath; TableName = tdbp->TableName; Schema = tdbp->Schema; Ops = tdbp->Ops; @@ -684,7 +680,7 @@ int TDBJDBC::Cardinality(PGLOBAL g) char qry[96], tbn[64]; JDBConn *jcp = new(g)JDBConn(g, this); - if (jcp->Open(Jpath, &Ops) == RC_FX) + if (jcp->Open(&Ops) == RC_FX) return -1; // Table name can be encoded in UTF-8 @@ -795,7 +791,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g) else if (Jcp->IsOpen()) Jcp->Close(); - if (Jcp->Open(Jpath, &Ops) == RC_FX) + if (Jcp->Open(&Ops) == RC_FX) return true; else if (Quoted) Quote = Jcp->GetQuoteChar(); @@ -1545,7 +1541,7 @@ bool TDBXJDC::OpenDB(PGLOBAL g) } else if (Jcp->IsOpen()) Jcp->Close(); - if (Jcp->Open(Jpath, &Ops) == RC_FX) + if (Jcp->Open(&Ops) == RC_FX) return true; Use = USE_OPEN; // Do it now in case we are recursively called @@ -1657,7 +1653,7 @@ void JSRCCOL::WriteColumn(PGLOBAL g) /***********************************************************************/ PQRYRES TDBJDRV::GetResult(PGLOBAL g) { - return JDBCDrivers(g, Jpath, Maxres, false); + return JDBCDrivers(g, Maxres, false); } // end of GetResult /* ---------------------------TDBJTB class --------------------------- */ @@ -1667,7 +1663,6 @@ PQRYRES TDBJDRV::GetResult(PGLOBAL g) /***********************************************************************/ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) { - Jpath = tdp->Jpath; Schema = tdp->Tabschema; Tab = tdp->Tabname; Tabtype = tdp->Tabtype; @@ -1684,7 +1679,7 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) /***********************************************************************/ 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 /* --------------------------TDBJDBCL class -------------------------- */ @@ -1694,7 +1689,7 @@ PQRYRES TDBJTB::GetResult(PGLOBAL g) /***********************************************************************/ PQRYRES TDBJDBCL::GetResult(PGLOBAL g) { - return JDBCColumns(g, Jpath, Schema, Tab, NULL, Maxres, false, &Ops); + return JDBCColumns(g, Schema, Tab, NULL, Maxres, false, &Ops); } // end of GetResult #if 0 diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h index d3ac3784d2f..1624b903610 100644 --- a/storage/connect/tabjdbc.h +++ b/storage/connect/tabjdbc.h @@ -31,7 +31,6 @@ public: // Implementation virtual const char *GetType(void) { return "JDBC"; } - PSZ GetJpath(void) { return Jpath; } PSZ GetTabname(void) { return Tabname; } PSZ GetTabschema(void) { return Tabschema; } PSZ GetTabcat(void) { return Tabcat; } @@ -48,7 +47,6 @@ public: protected: // Members - PSZ Jpath; /* Java class path */ PSZ Driver; /* JDBC driver */ PSZ Url; /* JDBC driver URL */ PSZ Tabname; /* External table name */ @@ -130,7 +128,6 @@ protected: JDBCCOL *Cnp; // Points to count(*) column JDBCPARM Ops; // Additional parameters PSTRG Query; // Constructed SQL query - char *Jpath; // Java class path char *TableName; // Points to JDBC table name char *Schema; // Points to JDBC table Schema char *User; // User connect info @@ -282,7 +279,7 @@ protected: class TDBJDRV : public TDBCAT { public: // Constructor - TDBJDRV(PJDBCDEF tdp) : TDBCAT(tdp) {Maxres = tdp->Maxres; Jpath = tdp->Jpath;} + TDBJDRV(PJDBCDEF tdp) : TDBCAT(tdp) {Maxres = tdp->Maxres;} protected: // Specific routines @@ -290,7 +287,6 @@ protected: // Members int Maxres; // Returned lines limit - char *Jpath; // Java class path }; // end of class TDBJDRV /***********************************************************************/ @@ -306,7 +302,6 @@ protected: virtual PQRYRES GetResult(PGLOBAL g); // Members - char *Jpath; // Points to Java classpath char *Schema; // Points to schema name or NULL char *Tab; // Points to JDBC table name or pattern char *Tabtype; // Points to JDBC table type -- cgit v1.2.1 From 0f5ced1dd5f8b21b57effbcd2c4b699d214f7d79 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 12 May 2016 15:41:21 +0200 Subject: - Fix some typo ... causing crash! modified: storage/connect/jdbconn.cpp --- storage/connect/jdbconn.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index fe93ba9a62f..88557fdd420 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -774,7 +774,7 @@ int JDBConn::GetMaxValue(int n) /***********************************************************************/ void JDBConn::ResetJVM(void) { - if (!LibJvm) { + if (LibJvm) { #if defined(__WIN__) FreeLibrary((HMODULE)LibJvm); #else // !__WIN__ @@ -863,7 +863,7 @@ int JDBConn::Open(PJPARM sop) // Link or check whether jvm library was linked if (GetJVM(g)) - return true; + return RC_FX; // Firstly check whether the jvm was already created JavaVM* jvms[1]; -- cgit v1.2.1 From 7972a45b4343cf620f4dc6d508ff9e0c1ca000e3 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 12 May 2016 17:22:45 +0200 Subject: - Remove REQUIRED option that caused compilation to fail Remove JVM_LIBRARY (is now dynamically loaded at run time) modified: storage/connect/CMakeLists.txt --- storage/connect/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index f4bcbfa9ade..fa2fb7b4ddd 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -268,12 +268,12 @@ IF(CONNECT_WITH_JDBC) # TODO: Find how to compile and install the JdbcInterface.java class # Find required libraries and include directories - FIND_PACKAGE(Java REQUIRED) - FIND_PACKAGE(JNI REQUIRED) + FIND_PACKAGE(Java) + FIND_PACKAGE(JNI) IF (JAVA_FOUND AND JNI_FOUND) INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH}) INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH2}) - SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) + # SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) SET(CONNECT_SOURCES ${CONNECT_SOURCES} JdbcInterface.java JdbcInterface.class jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) -- cgit v1.2.1 From 2f2797e52f235e6edae8627ac0700f8e43809859 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 20 May 2016 00:18:29 +0200 Subject: - 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 --- storage/connect/ha_connect.cc | 34 ++- storage/connect/jdbconn.cpp | 497 +++++++++++++++++++----------------------- storage/connect/jdbconn.h | 5 +- storage/connect/tabjdbc.cpp | 131 +++++++++-- storage/connect/tabjdbc.h | 3 + 5 files changed, 373 insertions(+), 297 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 58a761f442d..0534884e684 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -119,6 +119,7 @@ #undef OFFSET #define NOPARSE +#define NJDBC #if defined(UNIX) #include "osutil.h" #endif // UNIX @@ -128,7 +129,7 @@ #include "odbccat.h" #endif // ODBC_SUPPORT #if defined(JDBC_SUPPORT) -#include "jdbccat.h" +#include "tabjdbc.h" #include "jdbconn.h" #endif // JDBC_SUPPORT #include "xtable.h" @@ -5224,7 +5225,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, #endif #if defined(JDBC_SUPPORT) 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); #endif // JDBC_SUPPORT mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0")); @@ -5325,18 +5326,31 @@ static int connect_assisted_discovery(handlerton *, THD* thd, case TAB_JDBC: if (fnc & FNC_DRIVER) { 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"); } 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->Driver= driver; - sjp->Url= url; - sjp->User= (char*)user; - sjp->Pwd= (char*)pwd; sjp->Fsize= 0; 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 supfnc |= (FNC_DRIVER | FNC_TABLE); @@ -5775,12 +5789,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, switch (typ) { case TYPE_DOUBLE: + case TYPE_DECIM: // Some data sources do not count dec in length (prec) prec += (dec + 2); // To be safe break; - case TYPE_DECIM: - prec= len; - break; default: dec= 0; } // endswitch typ diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 88557fdd420..1d2242060e1 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -38,7 +38,6 @@ #include "plgdbsem.h" #include "xobject.h" #include "xtable.h" -#include "jdbccat.h" #include "tabjdbc.h" //#include "jdbconn.h" //#include "plgcnx.h" // For DB types @@ -118,6 +117,7 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) break; case 2: // NUMERIC case 3: // DECIMAL + case -3: // VARBINARY type = TYPE_DECIM; break; case 4: // INTEGER @@ -155,7 +155,6 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) break; case 0: // NULL case -2: // BINARY - case -3: // VARBINARY case -4: // LONGVARBINARY default: type = TYPE_ERROR; @@ -318,12 +317,15 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, /**************************************************************************/ PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp) { + PQRYRES qrp; JDBConn *jcp = new(g)JDBConn(g, NULL); if (jcp->Open(sjp)) return NULL; - return jcp->GetMetaData(g, src); + qrp = jcp->GetMetaData(g, src); + jcp->Close(); + return qrp; } // end of JDBCSrcCols /**************************************************************************/ @@ -361,14 +363,14 @@ PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, n = jcp->GetMaxValue(2); // Max catalog name length - if (n < 0) - return NULL; +// if (n < 0) +// return NULL; - length[0] = (n) ? (n + 1) : 0; + length[0] = (n > 0) ? (n + 1) : 0; 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 - length[2] = (n) ? (n + 1) : 128; + length[2] = (n > 0) ? (n + 1) : 128; } else { maxres = 0; length[0] = 128; @@ -642,11 +644,12 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) env= nullptr; // Pointer to native interface jdi = nullptr; // Pointer to the JdbcInterface class 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; //m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; //m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; //m_UpdateOptions = 0; + Msg = NULL; m_Driver = NULL; m_Url = NULL; m_User = NULL; @@ -676,10 +679,11 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) /***********************************************************************/ /* Screen for errors. */ /***********************************************************************/ -char *JDBConn::Check(void) +bool JDBConn::Check(jint rc) { + jstring s; + if (env->ExceptionCheck()) { - char *msg; jthrowable exc = env->ExceptionOccurred(); jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;"); @@ -688,17 +692,39 @@ char *JDBConn::Check(void) jstring s = (jstring)env->CallObjectMethod(exc, tid); const char *utf = env->GetStringUTFChars(s, (jboolean)false); env->DeleteLocalRef(s); - msg = PlugDup(m_G, utf); + Msg = PlugDup(m_G, utf); } else - msg = "Exception occured"; + Msg = "Exception occured"; env->ExceptionClear(); - return msg; - } // endif Check + } else if (rc < 0) { + s = (jstring)env->CallObjectMethod(job, errid); + Msg = (char*)env->GetStringUTFChars(s, (jboolean)false); + } else + Msg = NULL; - return 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); + + if (Check()) { + strcpy(g->Message, Msg); + return true; + } else + return false; + + } else + return false; + +} // end of gmID + #if 0 /***********************************************************************/ /* Utility routine. */ @@ -758,15 +784,17 @@ void JDBConn::OnSetOptions(HSTMT hstmt) /***********************************************************************/ int JDBConn::GetMaxValue(int n) { - jmethodID maxid = env->GetMethodID(jdi, "GetMaxValue", "(I)I"); + jint m; + jmethodID maxid = nullptr; - if (maxid == nullptr) { - strcpy(m_G->Message, "ERROR: method GetMaxValue not found !"); + if (gmID(m_G, maxid, "GetMaxValue", "(I)I")) return -1; - } // endif maxid // 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 /***********************************************************************/ @@ -859,6 +887,7 @@ bool JDBConn::GetJVM(PGLOBAL g) /***********************************************************************/ int JDBConn::Open(PJPARM sop) { + bool err = false; PGLOBAL& g = m_G; // Link or check whether jvm library was linked @@ -881,8 +910,10 @@ int JDBConn::Open(PJPARM sop) } // endif rc } 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 sep; @@ -897,23 +928,21 @@ int JDBConn::Open(PJPARM sop) JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options // 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 (cp) - jpop->Append(sep); - + jpop->Append(sep); jpop->Append(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()); + } // endif trace options[0].optionString = jpop->GetStr(); //options[1].optionString = "-verbose:jni"; @@ -981,7 +1010,7 @@ int JDBConn::Open(PJPARM sop) jstring path = env->NewStringUTF(jpath); rc = env->CallStaticIntMethod(jdi, alp, path); - if ((msg = Check())) { + if ((msg = Check(rc))) { strcpy(g->Message, msg); env->DeleteLocalRef(path); return RC_FX; @@ -1022,33 +1051,36 @@ int JDBConn::Open(PJPARM sop) return RC_FX; } // endif job - if (!sop) // DRIVER catalog table - return RC_OK; - - jmethodID cid = env->GetMethodID(jdi, "JdbcConnect", "([Ljava/lang/String;IZ)I"); + errid = env->GetMethodID(jdi, "GetErrmsg", "()Ljava/lang/String;"); if (env->ExceptionCheck()) { - strcpy(g->Message, "ERROR: method JdbcConnect() not found!"); + strcpy(g->Message, "ERROR: method GetErrmsg() not found!"); env->ExceptionDescribe(); env->ExceptionClear(); return RC_FX; } // 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 jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4 env->FindClass("java/lang/String"), NULL); // Strings - 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 + 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 if (m_Driver) @@ -1065,23 +1097,17 @@ int JDBConn::Open(PJPARM sop) // call method rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable); + err = Check(rc); + env->DeleteLocalRef(parms); // Not used anymore - // Not used anymore - env->DeleteLocalRef(parms); - - if (rc != (jint)0) { - strcpy(g->Message, "Connection failed"); + if (err) { + sprintf(g->Message, "Connecting: %s rc=%d", Msg, (int)rc); return RC_FX; - } // endif rc + } // endif Msg - typid = env->GetMethodID(jdi, "ColumnType", "(ILjava/lang/String;)I"); - - if (env->ExceptionCheck()) { - strcpy(g->Message, "ERROR: method ColumnType() not found!"); - env->ExceptionDescribe(); - env->ExceptionClear(); + if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I")) return RC_FX; - } else + else m_Opened = true; return RC_OK; @@ -1092,43 +1118,37 @@ int JDBConn::Open(PJPARM sop) /***********************************************************************/ int JDBConn::ExecSQLcommand(char *sql) { - int rc = RC_NF; + int rc; jint n; jstring qry; PGLOBAL& g = m_G; - if (xid == nullptr) { - // Get the methods used to execute a query and get the result - xid = env->GetMethodID(jdi, "Execute", "(Ljava/lang/String;)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; - } // endif grs - - } // endif xid + // Get the methods used to execute a query and get the result + if (gmID(g, xid, "Execute", "(Ljava/lang/String;)I") || + gmID(g, grs, "GetResult", "()I")) + return RC_FX; qry = env->NewStringUTF(sql); n = env->CallIntMethod(job, xid, qry); env->DeleteLocalRef(qry); - if (n < 0) { - sprintf(g->Message, "Error executing %s", sql); + if (Check(n)) { + sprintf(g->Message, "Execute: %s", Msg); return RC_FX; } // 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"); rc = RC_OK; // A result set was returned } else { m_Aff = (int)n; // Affected rows strcpy(g->Message, "Affected rows"); + rc = RC_NF; } // endif ncol return rc; @@ -1139,44 +1159,29 @@ int JDBConn::ExecSQLcommand(char *sql) /***********************************************************************/ int JDBConn::Fetch(int pos) { - jint rc; + jint rc = JNI_ERR; + PGLOBAL& g = m_G; if (m_Full) // Result set has one row return 1; if (pos) { if (!m_Scrollable) { - strcpy(m_G->Message, "Cannot fetch(pos) if FORWARD ONLY"); - return -1; - } else if (fetchid == nullptr) { - fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); - - if (fetchid == nullptr) { - strcpy(m_G->Message, "Cannot find method Fetch"); - return -1; - } // endif fetchid - - } // endif's + strcpy(g->Message, "Cannot fetch(pos) if FORWARD ONLY"); + return rc; + } else if (gmID(m_G, fetchid, "Fetch", "(I)Z")) + return rc; if (env->CallBooleanMethod(job, fetchid, pos)) rc = m_Rows; - else - rc = -1; } else { - if (readid == nullptr) { - readid = env->GetMethodID(jdi, "ReadNext", "()I"); - - if (readid == nullptr) { - strcpy(m_G->Message, "Cannot find method ReadNext"); - return -1; - } // endif readid - - } // endif readid + if (gmID(g, readid, "ReadNext", "()I")) + return rc; rc = env->CallBooleanMethod(job, readid); - if (rc >= 0) { + if (!Check(rc)) { if (rc == 0) m_Full = (m_Fetch == 1); else @@ -1184,7 +1189,7 @@ int JDBConn::Fetch(int pos) m_Rows += (int)rc; } else - strcpy(m_G->Message, "Error fetching next row"); + sprintf(g->Message, "Fetch: %s", Msg); } // endif pos @@ -1201,15 +1206,8 @@ int JDBConn::Rewind(char *sql) if (m_Full) rbuf = m_Rows; // No need to "rewind" else if (m_Scrollable) { - if (fetchid == nullptr) { - fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); - - if (fetchid == nullptr) { - strcpy(m_G->Message, "Cannot find method Fetch"); - return -1; - } // endif readid - - } // endif readid + if (gmID(m_G, fetchid, "Fetch", "(I)Z")) + return -1; jboolean b = env->CallBooleanMethod(job, fetchid, 0); @@ -1227,15 +1225,15 @@ void JDBConn::Close() { if (m_Opened) { jint rc; - jmethodID did = env->GetMethodID(jdi, "JdbcDisconnect", "()I"); + jmethodID did = nullptr; - if (did == nullptr) - printf("ERROR: method JdbcDisconnect() not found !"); - else if ((rc = env->CallIntMethod(job, did))) - printf("jdbcDisconnect: rc=%d", (int)rc); + if (gmID(m_G, did, "JdbcDisconnect", "()I")) + printf("%s\n", Msg); + else if (Check(env->CallIntMethod(job, did))) + printf("jdbcDisconnect: %s\n", Msg); - if ((rc = jvm->DetachCurrentThread())) - printf("DetachCurrentThread: rc = %d", (int)rc); + if ((rc = jvm->DetachCurrentThread()) != JNI_OK) + printf("DetachCurrentThread: rc=%d\n", (int)rc); //rc = jvm->DestroyJavaVM(); m_Opened = false; @@ -1249,7 +1247,6 @@ void JDBConn::Close() void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) { PGLOBAL& g = m_G; - char *msg; jint ctyp; jlong dtv; jstring cn, jn = nullptr; @@ -1262,10 +1259,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); } // endif name + // Returns 666 is case of error ctyp = env->CallIntMethod(job, typid, rank, jn); - if ((msg = Check())) { - sprintf(g->Message, "Getting ctyp: %s", msg); + if (Check((ctyp == 666) ? -1 : 1)) { + sprintf(g->Message, "Getting ctyp: %s", Msg); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); } // endif Check @@ -1303,6 +1301,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case 8: // DOUBLE + case 2: // NUMERIC case 3: // DECIMAL fldid = env->GetMethodID(jdi, "DoubleField", "(ILjava/lang/String;)D"); @@ -1372,11 +1371,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) val->Reset(); } // endswitch Type - if ((msg = Check())) { + if (Check()) { if (rank == 0) 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); } // endif Check @@ -1390,21 +1389,22 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) /***********************************************************************/ bool JDBConn::PrepareSQL(char *sql) { - if (prepid == nullptr) { - prepid = env->GetMethodID(jdi, "CreatePrepStmt", "(Ljava/lang/String;)Z"); + bool b = true; + PGLOBAL& g = m_G; - if (prepid == nullptr) { - strcpy(m_G->Message, "Cannot find method CreatePrepStmt"); - return true; - } // endif prepid + if (!gmID(g, prepid, "CreatePrepStmt", "(Ljava/lang/String;)I")) { + // Create the prepared statement + jstring qry = env->NewStringUTF(sql); + if (Check(env->CallBooleanMethod(job, prepid, qry))) + sprintf(g->Message, "CreatePrepStmt: %s", Msg); + else + b = false; + + env->DeleteLocalRef(qry); } // endif prepid - - // Create the prepared statement - jstring qry = env->NewStringUTF(sql); - jboolean b = env->CallBooleanMethod(job, prepid, qry); - env->DeleteLocalRef(qry); - return (bool)b; + + return b; } // end of PrepareSQL /***********************************************************************/ @@ -1412,32 +1412,25 @@ bool JDBConn::PrepareSQL(char *sql) /***********************************************************************/ int JDBConn::ExecuteQuery(char *sql) { + int rc = RC_FX; jint ncol; jstring qry; PGLOBAL& g = m_G; - if (xqid == nullptr) { - // Get the methods used to execute a query and get the result - xqid = env->GetMethodID(jdi, "ExecuteQuery", "(Ljava/lang/String;)I"); + // Get the methods used to execute a query and get the result + if (!gmID(g, xqid, "ExecuteQuery", "(Ljava/lang/String;)I")) { + qry = env->NewStringUTF(sql); + ncol = env->CallIntMethod(job, xqid, qry); - if (xqid == nullptr) { - strcpy(g->Message, "Cannot find method ExecuteQuery"); - return RC_FX; - } // endif !xqid - - } // endif xqid - - qry = env->NewStringUTF(sql); - ncol = env->CallIntMethod(job, xqid, qry); - env->DeleteLocalRef(qry); + if (!Check(ncol)) { + m_Ncol = (int)ncol; + m_Aff = 0; // Affected rows + rc = RC_OK; + } else + sprintf(g->Message, "ExecuteQuery: %s", Msg); - if (ncol < 0) { - sprintf(g->Message, "Error executing %s: ncol = %d", sql, ncol); - return RC_FX; - } else { - m_Ncol = (int)ncol; - m_Aff = 0; // Affected rows - } // endif ncol + env->DeleteLocalRef(qry); + } // endif xqid return RC_OK; } // end of ExecuteQuery @@ -1447,34 +1440,27 @@ int JDBConn::ExecuteQuery(char *sql) /***********************************************************************/ int JDBConn::ExecuteUpdate(char *sql) { + int rc = RC_FX; jint n; jstring qry; PGLOBAL& g = m_G; - if (xuid == nullptr) { - // Get the methods used to execute a query and get the affected rows - xuid = env->GetMethodID(jdi, "ExecuteUpdate", "(Ljava/lang/String;)I"); + // Get the methods used to execute a query and get the affected rows + if (!gmID(g, xuid, "ExecuteUpdate", "(Ljava/lang/String;)I")) { + qry = env->NewStringUTF(sql); + n = env->CallIntMethod(job, xuid, qry); - if (xuid == nullptr) { - strcpy(g->Message, "Cannot find method ExecuteUpdate"); - return RC_FX; - } // endif !xuid - - } // endif xuid + if (!Check(n)) { + m_Ncol = 0; + m_Aff = (int)n; // Affected rows + rc = RC_OK; + } else + sprintf(g->Message, "ExecuteUpdate: %s n=%d", Msg, n); - qry = env->NewStringUTF(sql); - n = env->CallIntMethod(job, xuid, qry); - env->DeleteLocalRef(qry); + env->DeleteLocalRef(qry); + } // endif xuid - if (n < 0) { - 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; + return rc; } // end of ExecuteUpdate /***********************************************************************/ @@ -1507,32 +1493,21 @@ int JDBConn::ExecuteSQL(void) int rc = RC_FX; PGLOBAL& g = m_G; - if (xpid == nullptr) { - // Get the methods used to execute a prepared statement - xpid = env->GetMethodID(jdi, "ExecutePrep", "()I"); + // Get the methods used to execute a prepared statement + if (!gmID(g, xpid, "ExecutePrep", "()I")) { + jint n = env->CallIntMethod(job, xpid); - if (xpid == nullptr) { - strcpy(g->Message, "Cannot find method ExecutePrep"); - return rc; - } // endif xpid + if (n == -3) + strcpy(g->Message, "SQL statement is not prepared"); + else if (Check(n)) + sprintf(g->Message, "ExecutePrep: %s", Msg); + else { + m_Aff = (int)n; + rc = RC_OK; + } // endswitch n } // 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; } // end of ExecuteSQL @@ -1542,8 +1517,7 @@ int JDBConn::ExecuteSQL(void) bool JDBConn::SetParam(JDBCCOL *colp) { PGLOBAL& g = m_G; - char *msg; - int rc = false; + bool rc = false; PVAL val = colp->GetValue(); jint n, i = (jint)colp->GetRank(); jshort s; @@ -1557,58 +1531,38 @@ bool JDBConn::SetParam(JDBCCOL *colp) switch (val->GetType()) { case TYPE_STRING: - setid = env->GetMethodID(jdi, "SetStringParm", "(ILjava/lang/String;)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetStringParm"); + if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V")) return true; - } // endif setid jst = env->NewStringUTF(val->GetCharValue()); env->CallVoidMethod(job, setid, i, jst); break; case TYPE_INT: - setid = env->GetMethodID(jdi, "SetIntParm", "(II)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetIntParm"); + if (gmID(g, setid, "SetIntParm", "(II)V")) return true; - } // endif setid n = (jint)val->GetIntValue(); env->CallVoidMethod(job, setid, i, n); break; case TYPE_TINY: case TYPE_SHORT: - setid = env->GetMethodID(jdi, "SetShortParm", "(IS)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetShortParm"); + if (gmID(g, setid, "SetShortParm", "(IS)V")) return true; - } // endif setid s = (jshort)val->GetShortValue(); env->CallVoidMethod(job, setid, i, s); break; case TYPE_BIGINT: - setid = env->GetMethodID(jdi, "SetBigintParm", "(IJ)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetBigintParm"); + if (gmID(g, setid, "SetBigintParm", "(IJ)V")) return true; - } // endif setid lg = (jlong)val->GetBigintValue(); env->CallVoidMethod(job, setid, i, lg); break; case TYPE_DOUBLE: case TYPE_DECIM: - setid = env->GetMethodID(jdi, "SetDoubleParm", "(ID)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot find method SetDoubleParm"); + if (gmID(g, setid, "SetDoubleParm", "(ID)V")) return true; - } // endif setid d = (jdouble)val->GetFloatValue(); env->CallVoidMethod(job, setid, i, d); @@ -1627,11 +1581,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) { strcpy(g->Message, "Cannot make Timestamp object"); return true; - } else if ((setid = env->GetMethodID(jdi, "SetTimestampParm", - "(ILjava/sql/Timestamp;)V")) == nullptr) { - strcpy(g->Message, "Cannot find method SetTimestampParm"); + } else if (gmID(g, setid, "SetTimestampParm", "(ILjava/sql/Timestamp;)V")) return true; - } // endif setid env->CallVoidMethod(job, setid, i, datobj); break; @@ -1640,8 +1591,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) return true; } // endswitch Type - if ((msg = Check())) { - sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), msg); + if (Check()) { + sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), Msg); rc = true; } // endif msg @@ -1707,14 +1658,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) int i, n, size; PCOLRES crp; jstring js; - jmethodID gdid = env->GetMethodID(jdi, "GetDrivers", "([Ljava/lang/String;I)I"); - - if (env->ExceptionCheck()) { - strcpy(m_G->Message, "ERROR: method GetDrivers() not found!"); - env->ExceptionDescribe(); - env->ExceptionClear(); + jmethodID gdid = nullptr; + + if (gmID(m_G, gdid, "GetDrivers", "([Ljava/lang/String;I)I")) return true; - } // endif Check // Build the java string array jobjectArray s = env->NewObjectArray(4 * qrp->Maxres, @@ -1766,7 +1713,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ushort i; jint *n = nullptr; jstring label; - jmethodID colid; + jmethodID colid = nullptr; int rc = ExecSQLcommand(src); if (rc == RC_NF) { @@ -1779,20 +1726,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) return NULL; } // endif's - colid = env->GetMethodID(jdi, "ColumnDesc", "(I[I)Ljava/lang/String;"); - - if (colid == nullptr) { - strcpy(m_G->Message, "ERROR: method ColumnDesc() not found!"); + if (gmID(g, colid, "ColumnDesc", "(I[I)Ljava/lang/String;")) 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 len = GetMaxValue(5); @@ -1813,11 +1748,28 @@ bool JDBConn::SetParam(JDBCCOL *colp) case 5: crp->Name = "Nullable"; break; } // 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. */ /************************************************************************/ 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); crp = qrp->Colresp; // Column_Name crp->Kdata->SetValue((char*)name, i); @@ -1835,7 +1787,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) /* Cleanup */ env->ReleaseIntArrayElements(val, n, 0); - Close(); /************************************************************************/ /* Return the result pointer for use by GetData routines. */ @@ -1962,7 +1913,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) PVAL *pval = NULL; char* *pbuf = NULL; jobjectArray parms; - jmethodID catid; + jmethodID catid = nullptr; if (qrp->Maxres <= 0) return 0; // 0-sized result" @@ -2008,16 +1959,18 @@ bool JDBConn::SetParam(JDBCCOL *colp) return -1; } // endswitch infotype - catid = env->GetMethodID(jdi, fnc, "([Ljava/lang/String;)I"); - - if (catid == nullptr) { - sprintf(g->Message, "ERROR: method %s not found !", fnc); + if (gmID(g, catid, fnc, "([Ljava/lang/String;)I")) return -1; - } // endif maxid // call method 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 env->DeleteLocalRef(parms); @@ -2061,13 +2014,15 @@ bool JDBConn::SetParam(JDBCCOL *colp) // Now fetch the result 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) htrc("End of fetches i=%d\n", i); break; - } else if (rc < 0) - return -1; + } // endif rc for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) { SetColumnValue(n + 1, nullptr, pval[n]); diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index 4014a52cdcc..d8c36c6a637 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -120,7 +120,8 @@ public: // JDBC operations 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(PSZ msg); //void Free(void); @@ -150,9 +151,11 @@ protected: jmethodID prepid; // The CreatePrepStmt method ID jmethodID xpid; // The ExecutePrep method ID jmethodID pcid; // The ClosePrepStmt method ID + jmethodID errid; // The GetErrmsg method ID //DWORD m_LoginTimeout; //DWORD m_QueryTimeout; //DWORD m_UpdateOptions; + char *Msg; char m_IDQuoteChar[2]; PSZ m_Driver; PSZ m_Url; diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index 37850ce6358..fa5f093bae6 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -1,7 +1,7 @@ /************* TabJDBC C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABJDBC */ /* ------------- */ -/* Version 1.0 */ +/* Version 1.1 */ /* */ /* COPYRIGHT: */ /* ---------- */ @@ -34,8 +34,10 @@ /***********************************************************************/ /* Include relevant MariaDB header file. */ /***********************************************************************/ +#define MYSQL_SERVER 1 #include "my_global.h" #include "sql_class.h" +#include "sql_servers.h" #if defined(__WIN__) #include #include @@ -67,7 +69,6 @@ #include "plgdbsem.h" #include "mycat.h" #include "xtable.h" -#include "jdbccat.h" #include "tabjdbc.h" #include "tabmul.h" #include "reldef.h" @@ -101,11 +102,107 @@ JDBCDEF::JDBCDEF(void) Scrollable = Xsrc = false; } // 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. */ /***********************************************************************/ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { + int rc = RC_OK; + Driver = GetStringCatInfo(g, "Driver", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL); @@ -120,28 +217,33 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) } // endif Connect - Tabname = GetStringCatInfo(g, "Name", - (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); - 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); - Password = GetStringCatInfo(g, "Password", NULL); + 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", + (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); + Tabname = GetStringCatInfo(g, "Tabname", Tabname); + Username = GetStringCatInfo(g, "User", NULL); + Password = GetStringCatInfo(g, "Password", NULL); + } // endif rc if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) 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", "?"); Sep = GetStringCatInfo(g, "Separator", NULL); Xsrc = GetBoolCatInfo("Execsrc", FALSE); Maxerr = GetIntCatInfo("Maxerr", 0); Maxres = GetIntCatInfo("Maxres", 0); Quoted = GetIntCatInfo("Quoted", 0); -//Options = JDBConn::noJDBCDialog; -//Options = JDBConn::noJDBCDialog | JDBConn::useCursorLib; //Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); //Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); Scrollable = GetBoolCatInfo("Scrollable", false); @@ -274,6 +376,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) Ncol = 0; Nparm = 0; Placed = false; + Prepared = false; Werr = false; Rerr = false; Ops.Fsize = Ops.CheckSize(Rows); diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h index 1624b903610..537276a6a7f 100644 --- a/storage/connect/tabjdbc.h +++ b/storage/connect/tabjdbc.h @@ -7,6 +7,7 @@ /***********************************************************************/ #include "colblk.h" #include "resource.h" +#include "jdbccat.h" typedef class JDBCDEF *PJDBCDEF; typedef class TDBJDBC *PTDBJDBC; @@ -44,6 +45,8 @@ public: virtual int Indexable(void) { return 2; } virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual PTDB GetTable(PGLOBAL g, MODE m); + int ParseURL(PGLOBAL g, char *url, bool b = true); + bool SetParms(PJPARM sjp); protected: // Members -- cgit v1.2.1 From a982f59b9b7ed988d908fa75425c826d7e85e406 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 21 May 2016 11:56:59 +0200 Subject: - JDBC using separate jmethodID for data types Some DEBUG tests modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h --- storage/connect/jdbconn.cpp | 92 +++++++++++++++++++++++++++++---------------- storage/connect/jdbconn.h | 23 +++++++++++- 2 files changed, 80 insertions(+), 35 deletions(-) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 1d2242060e1..286d1141fe8 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -62,6 +62,9 @@ extern char *ClassPath; // The connect_class_path global variable value 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) */ @@ -646,6 +649,7 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) job = nullptr; // The JdbcInterface class object xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr; prepid = xpid = pcid = nullptr; + chrfldid = intfldid = dblfldid = fltfldid = datfldid = bigfldid = nullptr; //m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; //m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; //m_UpdateOptions = 0; @@ -811,6 +815,9 @@ void JDBConn::ResetJVM(void) LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; +#if defined(_DEBUG) + GetDefaultJavaVMInitArgs = NULL; +#endif // _DEBUG } // endif LibJvm } // end of ResetJVM @@ -851,6 +858,14 @@ bool JDBConn::GetJVM(PGLOBAL g) 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; @@ -874,7 +889,15 @@ bool JDBConn::GetJVM(PGLOBAL g) sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error)); dlclose(LibJvm); LibJvm = NULL; - } // endif LibJvm +#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 @@ -919,13 +942,17 @@ int JDBConn::Open(PJPARM sop) #if defined(__WIN__) sep = ';'; +#define N 1 +//#define N 2 +//#define N 3 #else sep = ':'; +#define N 1 #endif //================== prepare loading of Java VM ============================ 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 if (ClassPath && *ClassPath) { @@ -945,9 +972,20 @@ int JDBConn::Open(PJPARM sop) } // endif trace 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.nOptions = 1; // number of options +#endif // _DEBUG + vm_args.nOptions = N; // number of options vm_args.options = options; vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail @@ -985,8 +1023,10 @@ int JDBConn::Open(PJPARM sop) } // endif rc //=============== Display JVM version ======================================= -//jint ver = env->GetVersion(); -//cout << ((ver>>16)&0x0f) << "."<<(ver&0x0f) << endl; +#if defined(_DEBUG) + jint ver = env->GetVersion(); + printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); +#endif //_DEBUG // try to find the JdbcInterface class jdi = env->FindClass("JdbcInterface"); @@ -1251,7 +1291,6 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) jlong dtv; jstring cn, jn = nullptr; jobject dob; - jmethodID fldid = nullptr; if (rank == 0) if (!name || (jn = env->NewStringUTF(name)) == nullptr) { @@ -1271,11 +1310,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 12: // VARCHAR case -1: // LONGVARCHAR case 1: // CHAR - fldid = env->GetMethodID(jdi, "StringField", - "(ILjava/lang/String;)Ljava/lang/String;"); - - if (fldid != nullptr) { - cn = (jstring)env->CallObjectMethod(job, fldid, (jint)rank, jn); + if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;")) { + cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn); if (cn) { const char *field = env->GetStringUTFChars(cn, (jboolean)false); @@ -1292,10 +1328,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 4: // INTEGER case 5: // SMALLINT case -6: // TINYINT - fldid = env->GetMethodID(jdi, "IntField", "(ILjava/lang/String;)I"); - - if (fldid != nullptr) - val->SetValue((int)env->CallIntMethod(job, fldid, rank, jn)); + if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I")) + val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn)); else val->Reset(); @@ -1303,20 +1337,16 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 8: // DOUBLE case 2: // NUMERIC case 3: // DECIMAL - fldid = env->GetMethodID(jdi, "DoubleField", "(ILjava/lang/String;)D"); - - if (fldid != nullptr) - val->SetValue((double)env->CallDoubleMethod(job, fldid, rank, jn)); + if (!gmID(g, dblfldid, "DoubleField", "(ILjava/lang/String;)D")) + val->SetValue((double)env->CallDoubleMethod(job, dblfldid, rank, jn)); else val->Reset(); break; case 7: // REAL case 6: // FLOAT - fldid = env->GetMethodID(jdi, "FloatField", "(ILjava/lang/String;)F"); - - if (fldid != nullptr) - val->SetValue((float)env->CallFloatMethod(job, fldid, rank, jn)); + if (!gmID(g, fltfldid, "FloatField", "(ILjava/lang/String;)F")) + val->SetValue((float)env->CallFloatMethod(job, fltfldid, rank, jn)); else val->Reset(); @@ -1324,11 +1354,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 91: // DATE case 92: // TIME case 93: // TIMESTAMP - fldid = env->GetMethodID(jdi, "TimestampField", - "(ILjava/lang/String;)Ljava/sql/Timestamp;"); - - if (fldid != nullptr) { - dob = env->CallObjectMethod(job, fldid, (jint)rank, jn); + if (!gmID(g, datfldid, "TimestampField", + "(ILjava/lang/String;)Ljava/sql/Timestamp;")) { + dob = env->CallObjectMethod(job, datfldid, (jint)rank, jn); if (dob) { jclass jts = env->FindClass("java/sql/Timestamp"); @@ -1354,10 +1382,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case -5: // BIGINT - fldid = env->GetMethodID(jdi, "BigintField", "(ILjava/lang/String;)J"); - - if (fldid != nullptr) - val->SetValue((long long)env->CallLongMethod(job, fldid, (jint)rank, jn)); + if (!gmID(g, bigfldid, "BigintField", "(ILjava/lang/String;)J")) + val->SetValue((long long)env->CallLongMethod(job, bigfldid, (jint)rank, jn)); else val->Reset(); diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index d8c36c6a637..a7744ba6ba1 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -53,6 +53,9 @@ typedef struct tagJCATPARM { 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 class TDBJDBC; @@ -109,8 +112,15 @@ public: public: // Set static variables - static void SetJVM(void) - { LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; } + 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); @@ -135,6 +145,9 @@ protected: #endif // !__WIN__ static CRTJVM CreateJavaVM; static GETJVM GetCreatedJavaVMs; +#if defined(_DEBUG) + static GETDEF GetDefaultJavaVMInitArgs; +#endif // _DEBUG PGLOBAL m_G; TDBJDBC *m_Tdb; JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) @@ -152,6 +165,12 @@ protected: jmethodID xpid; // The ExecutePrep 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_QueryTimeout; //DWORD m_UpdateOptions; -- cgit v1.2.1 From 77dd5ece06904aa10c3fe05b9493cf3231edcd85 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 21 May 2016 14:28:21 +0200 Subject: - Fix wrong return from ExecuteQuery modified: storage/connect/jdbconn.cpp - Suppress GCC warning modified: storage/connect/tabjdbc.cpp --- storage/connect/jdbconn.cpp | 2 +- storage/connect/tabjdbc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 286d1141fe8..23bd64bfb88 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -1458,7 +1458,7 @@ int JDBConn::ExecuteQuery(char *sql) env->DeleteLocalRef(qry); } // endif xqid - return RC_OK; + return rc; } // end of ExecuteQuery /***********************************************************************/ diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index fa5f093bae6..f507e3df3ea 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -172,7 +172,7 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) if (server->port) { char buf[16]; - sprintf(buf, "%d", server->port); + sprintf(buf, "%ld", server->port); strcat(strcat(Url, ":"), buf); } // endif port -- cgit v1.2.1 From 0dae2932f42b10d86671d21de41cf0b444aedf5e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 23 May 2016 15:08:51 +0200 Subject: - New version of the java JdbcInterface modified: storage/connect/JdbcInterface.class modified: storage/connect/JdbcInterface.java - Ignore *.tlog and .res files modified: .gitignore --- .gitignore | 2 + storage/connect/JdbcInterface.class | Bin 15117 -> 15215 bytes storage/connect/JdbcInterface.java | 229 ++++++++++++++++++++++++------------ 3 files changed, 153 insertions(+), 78 deletions(-) diff --git a/.gitignore b/.gitignore index f2064537da4..279d3f59dc5 100644 --- a/.gitignore +++ b/.gitignore @@ -244,6 +244,8 @@ storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result *.exp *.dep *.idb +*.res +*.tlog # Precompiled Headers *.gch diff --git a/storage/connect/JdbcInterface.class b/storage/connect/JdbcInterface.class index 816f575212b..8c5ba6439f3 100644 Binary files a/storage/connect/JdbcInterface.class and b/storage/connect/JdbcInterface.class differ diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java index 5e01516d0cb..f9a6e734454 100644 --- a/storage/connect/JdbcInterface.java +++ b/storage/connect/JdbcInterface.java @@ -1,10 +1,14 @@ import java.math.*; import java.sql.*; +//import java.util.Arrays; import java.util.Collections; import java.util.List; +//import java.io.File; +//import java.lang.reflect.Field; public class JdbcInterface { boolean DEBUG = false; + String Errmsg = "No error"; Connection conn = null; DatabaseMetaData dbmd = null; Statement stmt = null; @@ -20,6 +24,20 @@ public class JdbcInterface { public JdbcInterface(boolean b) { DEBUG = b; } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { int rc = 0; @@ -32,7 +50,9 @@ public class JdbcInterface { System.out.println("In try block"); if (parms[0] != null && !parms[0].isEmpty()) { - System.out.println("b is true!"); + if (DEBUG) + System.out.println("Loading class" + parms[0]); + Class.forName(parms[0]); //loads the driver } // endif driver @@ -76,50 +96,40 @@ public class JdbcInterface { } // endif fsize } catch(ClassNotFoundException e) { - System.err.println("ClassNotFoundException: " + e.getMessage()); - rc = 1; + SetErrmsg(e); + rc = -1; } catch (SQLException se) { - System.out.println("SQL Exception:"); - - // Loop through the SQL Exceptions - while (se != null) { - System.out.println("State : " + se.getSQLState()); - System.out.println("Message: " + se.getMessage()); - System.out.println("Error : " + se.getErrorCode()); - - se = se.getNextException(); - } // end while se - - rc = 2; + SetErrmsg(se); + rc = -2; } catch( Exception e ) { - System.out.println(e); - rc = 3; + SetErrmsg(e); + rc = -3; } // end try/catch return rc; } // end of JdbcConnect - public boolean CreatePrepStmt(String sql) { - boolean b = false; + public int CreatePrepStmt(String sql) { + int rc = 0; try { pstmt = conn.prepareStatement(sql); } catch (SQLException se) { - System.out.println(se); - b = true; + SetErrmsg(se); + rc = -1; } catch (Exception e) { - System.out.println(e); - b = true; + SetErrmsg(e); + rc = -2; } // end try/catch - return b; + return rc; } // end of CreatePrepStmt public void SetStringParm(int i, String s) { try { pstmt.setString(i, s); } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); } // end try/catch } // end of SetStringParm @@ -128,7 +138,7 @@ public class JdbcInterface { try { pstmt.setInt(i, n); } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); } // end try/catch } // end of SetIntParm @@ -137,7 +147,7 @@ public class JdbcInterface { try { pstmt.setShort(i, n); } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); } // end try/catch } // end of SetShortParm @@ -146,7 +156,7 @@ public class JdbcInterface { try { pstmt.setLong(i, n); } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); } // end try/catch } // end of SetBigintParm @@ -155,8 +165,8 @@ public class JdbcInterface { try { pstmt.setFloat(i, f); } catch (Exception e) { - System.out.println(e); - } // end try/catch + SetErrmsg(e); + } // end try/catch } // end of SetFloatParm @@ -164,8 +174,8 @@ public class JdbcInterface { try { pstmt.setDouble(i, d); } catch (Exception e) { - System.out.println(e); - } // end try/catch + SetErrmsg(e); + } // end try/catch } // end of SetDoubleParm @@ -173,7 +183,7 @@ public class JdbcInterface { try { pstmt.setTimestamp(i, t); } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); } // end try/catch } // end of SetTimestampParm @@ -184,10 +194,10 @@ public class JdbcInterface { if (pstmt != null) try { n = pstmt.executeUpdate(); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); n = -1; } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); n = -2; } //end try/catch @@ -201,10 +211,10 @@ public class JdbcInterface { pstmt.close(); pstmt = null; } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); b = true; } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); b = true; } // end try/catch @@ -220,26 +230,30 @@ public class JdbcInterface { System.out.println("Cancelling statement"); stmt.cancel(); } catch(SQLException se) { - System.out.println(se); + SetErrmsg(se); rc += 1; } // nothing more we can do // Close the statement and the connection if (rs != null) try { - System.out.println("Closing result set"); + if (DEBUG) + System.out.println("Closing result set"); + rs.close(); } catch(SQLException se) { - System.out.println(se); + SetErrmsg(se); rc = 2; } // nothing more we can do if (stmt != null) try { - System.out.println("Closing statement"); + if (DEBUG) + System.out.println("Closing statement"); + stmt.close(); } catch(SQLException se) { - System.out.println(se); + SetErrmsg(se); rc += 4; } // nothing more we can do @@ -247,14 +261,18 @@ public class JdbcInterface { if (conn != null) try { - System.out.println("Closing connection"); + if (DEBUG) + System.out.println("Closing connection"); + conn.close(); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); rc += 8; } //end try/catch - System.out.println("All closed"); + if (DEBUG) + System.out.println("All closed"); + return rc; } // end of JdbcDisconnect @@ -281,7 +299,8 @@ public class JdbcInterface { } // endswitch n } catch(Exception e) { - System.out.println(e); + SetErrmsg(e); + m = -1; } // end try/catch return m; @@ -300,7 +319,7 @@ public class JdbcInterface { } // endif rs } catch(SQLException se) { - System.out.println(se); + SetErrmsg(se); } // end try/catch return ncol; @@ -325,7 +344,7 @@ public class JdbcInterface { } // endif rs } catch(SQLException se) { - System.out.println(se); + SetErrmsg(se); } // end try/catch return ncol; @@ -341,18 +360,18 @@ public class JdbcInterface { boolean b = stmt.execute(query); if (b == false) { - n = stmt.getUpdateCount(); - if (rs != null) rs.close(); + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); } // endif b if (DEBUG) System.out.println("Query '" + query + "' executed: n = " + n); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); n = -1; } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); n = -2; } //end try/catch @@ -375,10 +394,10 @@ public class JdbcInterface { } // endif rs } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); ncol = -1; } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); ncol = -2; } //end try/catch @@ -402,10 +421,10 @@ public class JdbcInterface { } // endif DEBUG } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); ncol = -1; } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); ncol = -2; } //end try/catch @@ -419,28 +438,28 @@ public class JdbcInterface { System.out.println("Executing update query '" + query + "'"); try { - n = stmt.executeUpdate(query); + n = stmt.executeUpdate(query); - if (DEBUG) - System.out.println("Update Query '" + query + "' executed: n = " + n); + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); n = -1; } catch (Exception e) { - System.out.println(e); + SetErrmsg(e); n = -2; } //end try/catch return n; - } // end of ExecuteQuery + } // end of ExecuteUpdate public int ReadNext() { if (rs != null) { try { return rs.next() ? 1 : 0; } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); return -1; } //end try/catch @@ -454,7 +473,7 @@ public class JdbcInterface { try { return rs.absolute(row); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); return false; } //end try/catch @@ -469,7 +488,7 @@ public class JdbcInterface { } else try { return rsmd.getColumnLabel(n); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -484,10 +503,10 @@ public class JdbcInterface { return rsmd.getColumnType(n); } catch (SQLException se) { - System.out.println("ColumnType: " + se); + SetErrmsg(se); } //end try/catch - return 0; + return 666; // Not a type } // end of ColumnType public String ColumnDesc(int n, int[] val) { @@ -501,11 +520,11 @@ public class JdbcInterface { val[3] = rsmd.isNullable(n); return rsmd.getColumnLabel(n); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; - } // end of ColumnType + } // end of ColumnDesc public String StringField(int n, String name) { if (rs == null) { @@ -513,7 +532,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getString(n) : rs.getString(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -525,7 +544,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getInt(n) : rs.getInt(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0; @@ -538,7 +557,7 @@ public class JdbcInterface { BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); return bigDecimal != null ? bigDecimal.longValue() : 0; } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0; @@ -550,7 +569,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0.; @@ -562,7 +581,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0; @@ -574,7 +593,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return false; @@ -586,7 +605,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getDate(n) : rs.getDate(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -598,7 +617,7 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getTime(n) : rs.getTime(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -610,12 +629,24 @@ public class JdbcInterface { } else try { return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; } // end of TimestampField + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + public int GetDrivers(String[] s, int mxs) { int n = 0; List drivers = Collections.list(DriverManager.getDrivers()); @@ -635,5 +666,47 @@ public class JdbcInterface { return size; } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ } // end of class JdbcInterface -- cgit v1.2.1 From 809422838d7c90e658b889712f45f4b953a7bdd6 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 24 May 2016 11:29:12 +0200 Subject: - Alternative versions of the java JdbcInterface Some of them (ap/ds) enable connection to a DataSource added 'storage/connect/java/ap/JdbcInterface.class' added 'storage/connect/java/ap/JdbcInterface.java' added 'storage/connect/java/ds/JdbcInterface.class' added 'storage/connect/java/ds/JdbcInterface.java' added 'storage/connect/java/std/JdbcInterface.class' added 'storage/connect/java/std/JdbcInterface.java' --- storage/connect/java/ap/JdbcInterface.class | Bin 0 -> 15339 bytes storage/connect/java/ap/JdbcInterface.java | 709 +++++++++++++++++++++++++ storage/connect/java/ds/JdbcInterface.class | Bin 0 -> 16169 bytes storage/connect/java/ds/JdbcInterface.java | 743 +++++++++++++++++++++++++++ storage/connect/java/std/JdbcInterface.class | Bin 0 -> 15215 bytes storage/connect/java/std/JdbcInterface.java | 712 +++++++++++++++++++++++++ 6 files changed, 2164 insertions(+) create mode 100644 storage/connect/java/ap/JdbcInterface.class create mode 100644 storage/connect/java/ap/JdbcInterface.java create mode 100644 storage/connect/java/ds/JdbcInterface.class create mode 100644 storage/connect/java/ds/JdbcInterface.java create mode 100644 storage/connect/java/std/JdbcInterface.class create mode 100644 storage/connect/java/std/JdbcInterface.java diff --git a/storage/connect/java/ap/JdbcInterface.class b/storage/connect/java/ap/JdbcInterface.class new file mode 100644 index 00000000000..0b08b2e9217 Binary files /dev/null and b/storage/connect/java/ap/JdbcInterface.class differ diff --git a/storage/connect/java/ap/JdbcInterface.java b/storage/connect/java/ap/JdbcInterface.java new file mode 100644 index 00000000000..10128cac682 --- /dev/null +++ b/storage/connect/java/ap/JdbcInterface.java @@ -0,0 +1,709 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import org.apache.commons.dbcp2.BasicDataSource; + +public class JdbcInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + static Hashtable pool = new Hashtable(); + + // === Constructors/finalize ========================================= + public JdbcInterface() { + this(true); + } // end of default constructor + + public JdbcInterface(boolean b) { + DEBUG = b; + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + BasicDataSource ds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif url + + try { + if ((ds = pool.get(url)) == null) { + ds = new BasicDataSource(); + ds.setDriverClassName(parms[0]); + ds.setUrl(url); + ds.setUsername(parms[2]); + ds.setPassword(parms[3]); + pool.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcInterface diff --git a/storage/connect/java/ds/JdbcInterface.class b/storage/connect/java/ds/JdbcInterface.class new file mode 100644 index 00000000000..85a52b016cb Binary files /dev/null and b/storage/connect/java/ds/JdbcInterface.class differ diff --git a/storage/connect/java/ds/JdbcInterface.java b/storage/connect/java/ds/JdbcInterface.java new file mode 100644 index 00000000000..fae688807f9 --- /dev/null +++ b/storage/connect/java/ds/JdbcInterface.java @@ -0,0 +1,743 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import javax.sql.DataSource; + +import org.mariadb.jdbc.MariaDbDataSource; +import org.postgresql.jdbc2.optional.PoolingDataSource; +import com.mysql.cj.jdbc.MysqlDataSource; +import oracle.jdbc.pool.OracleDataSource; + +public class JdbcInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + Hashtable dst = null; + + // === Constructors/finalize ========================================= + public JdbcInterface() { + this(true); + } // end of default constructor + + public JdbcInterface(boolean b) { + DEBUG = b; + dst = new Hashtable(); + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + MysqlDataSource mds = null; + MariaDbDataSource ads = null; + OracleDataSource ods = null; + PoolingDataSource pds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif driver + + try { + if ((ds = dst.get(url)) == null) { + if (url.toLowerCase().contains("mysql")) { + mds = new MysqlDataSource(); + mds.setURL(url); + mds.setUser(parms[2]); + mds.setPassword(parms[3]); + ds = mds; + } else if (url.toLowerCase().contains("mariadb")) { + ads = new MariaDbDataSource(); + ads.setUrl(url); + ads.setUser(parms[2]); + ads.setPassword(parms[3]); + ds = ads; + } else if (url.toLowerCase().contains("oracle")) { + ods = new OracleDataSource(); + ods.setURL(url); + ods.setUser(parms[2]); + ods.setPassword(parms[3]); + ds = ods; + } else if (url.toLowerCase().contains("postgresql")) { + pds = new PoolingDataSource(); + pds.setUrl(url); + pds.setUser(parms[2]); + pds.setPassword(parms[3]); + ds = pds; + } else { + SetErrmsg("Unsupported driver"); + return -4; + } // endif driver + + dst.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcInterface diff --git a/storage/connect/java/std/JdbcInterface.class b/storage/connect/java/std/JdbcInterface.class new file mode 100644 index 00000000000..8c5ba6439f3 Binary files /dev/null and b/storage/connect/java/std/JdbcInterface.class differ diff --git a/storage/connect/java/std/JdbcInterface.java b/storage/connect/java/std/JdbcInterface.java new file mode 100644 index 00000000000..f9a6e734454 --- /dev/null +++ b/storage/connect/java/std/JdbcInterface.java @@ -0,0 +1,712 @@ +import java.math.*; +import java.sql.*; +//import java.util.Arrays; +import java.util.Collections; +import java.util.List; +//import java.io.File; +//import java.lang.reflect.Field; + +public class JdbcInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + + // === Constructors/finalize ========================================= + public JdbcInterface() { + this(true); + } // end of default constructor + + public JdbcInterface(boolean b) { + DEBUG = b; + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + + if (DEBUG) + System.out.println("In JdbcInterface: driver=" + parms[0]); + + try { + if (DEBUG) + System.out.println("In try block"); + + if (parms[0] != null && !parms[0].isEmpty()) { + if (DEBUG) + System.out.println("Loading class" + parms[0]); + + Class.forName(parms[0]); //loads the driver + } // endif driver + + if (DEBUG) + System.out.println("URL=" + parms[1]); + + if (parms[2] != null && !parms[2].isEmpty()) { + if (DEBUG) + System.out.println("user=" + parms[2] + " pwd=" + parms[3]); + + conn = DriverManager.getConnection(parms[1], parms[2], parms[3]); + } else + conn = DriverManager.getConnection(parms[1]); + + if (DEBUG) + System.out.println("Connection " + conn.toString() + " established"); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch(ClassNotFoundException e) { + SetErrmsg(e); + rc = -1; + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcInterface -- cgit v1.2.1 From afa4657fd334056ea8de0c83e1ad655fd49566ae Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 24 May 2016 23:57:06 +0200 Subject: - Fix failing json_udf_bin test when --ps modified: storage/connect/jsonudf.cpp modified: storage/connect/mysql-test/connect/disabled.def --- storage/connect/jsonudf.cpp | 280 ++++++++++++++++++++---- storage/connect/mysql-test/connect/disabled.def | 2 +- 2 files changed, 240 insertions(+), 42 deletions(-) diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 26965672ba4..4cead259896 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1805,7 +1805,20 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa } else CalcLen(args, false, reslen, memlen); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_add_values_init char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -1850,7 +1863,7 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, } // endif str // Keep result of constant function - g->Xchk = (initid->const_item) ? str : NULL; + g->Xchk = (g->N) ? str : NULL; } else str = (char*)g->Xchk; @@ -1873,7 +1886,7 @@ void json_array_add_values_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen; if (args->arg_count < 2) { strcpy(message, "This function must have at least 2 arguments"); @@ -1884,7 +1897,20 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_add_init char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -1930,7 +1956,7 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -1966,7 +1992,20 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_delete_init char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2008,7 +2047,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2184,7 +2223,20 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, true, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_object_add_init char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2227,7 +2279,7 @@ char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2266,7 +2318,20 @@ my_bool json_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, true, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_object_delete_init char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2307,7 +2372,7 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2605,7 +2670,20 @@ my_bool json_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_item_merge_init char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2651,7 +2729,7 @@ char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -3552,11 +3630,11 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, PGLOBAL g = (PGLOBAL)initid->ptr; PGLOBAL gb = GetMemPtr(g, args, 0); - if (g->N) { + if (g->Alchecked) { str = (char*)g->Activityp; goto fin; - } else if (initid->const_item) - g->N = 1; + } else if (g->N) + g->Alchecked = 1; if (!strcmp(result, "$set")) w = 0; @@ -3632,7 +3710,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!(str = MakeResult(g, args, jsp, INT_MAX32))) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Activityp = (PACTIVITY)str; @@ -3677,7 +3755,21 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else if (n != 3) memlen += args->lengths[0] * 3; - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + g->Alchecked = 0; + return false; + } else + return true; + } // end of json_set_item_init char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3742,8 +3834,8 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count < 1 || args->arg_count > 4) { strcpy(message, "This function only accepts 1 to 4 arguments"); return true; - } else if (!args->args[0] || args->arg_type[0] != STRING_RESULT) { - strcpy(message, "First argument must be a constant string (file name)"); + } else if (args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a string (file name)"); return true; } // endif's args[0] @@ -3761,7 +3853,12 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) initid->maybe_null = 1; CalcLen(args, false, reslen, memlen); - fl = GetFileLength(args->args[0]); + + if (args->args[0]) + fl = GetFileLength(args->args[0]); + else + fl = 100; // What can be done here? + reslen += fl; if (initid->const_item) @@ -4020,7 +4117,18 @@ void jbin_array_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_add_values_init(initid, args, message); + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json string or item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + return JsonInit(initid, args, message, true, reslen, memlen); } // end of jbin_array_add_values_init char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -4090,7 +4198,18 @@ void jbin_array_add_values_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_add_init(initid, args, message); + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); } // end of jbin_array_add_init char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -4160,8 +4279,19 @@ void jbin_array_add_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_delete_init(initid, args, message); -} // end of jbin_array_delete_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_array_delete_init char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4383,8 +4513,19 @@ void jbin_object_key_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_object_add_init(initid, args, message); -} // end of jbin_object_add_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, true, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_object_add_init char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4449,8 +4590,22 @@ void jbin_object_add_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_object_delete_init(initid, args, message); -} // end of jbin_object_delete_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have 2 or 3 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else if (args->arg_type[1] != STRING_RESULT) { + strcpy(message, "Second argument must be a key string"); + return true; + } else + CalcLen(args, true, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_object_delete_init char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4659,8 +4814,22 @@ void jbin_get_item_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_item_merge_init(initid, args, message); -} // end of jbin_item_merge_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else if (!IsJson(args, 1)) { + strcpy(message, "Second argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_item_merge_init char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4820,8 +4989,31 @@ fin: /*********************************************************************************/ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_set_item_init(initid, args, message); -} // end of jbin_set_item_init + unsigned long reslen, memlen; + int n = IsJson(args, 0); + + if (!(args->arg_count % 2)) { + strcpy(message, "This function must have an odd number of arguments"); + return true; + } else if (!n && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + if (n == 2 && args->args[0]) { + char fn[_MAX_PATH]; + long fl; + + memcpy(fn, args->args[0], args->lengths[0]); + fn[args->lengths[0]] = 0; + fl = GetFileLength(fn); + memlen += fl * 3; + } else if (n != 3) + memlen += args->lengths[0] * 3; + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_set_item_init char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) @@ -4992,7 +5184,7 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count != 1) { strcpy(message, "This function must have 1 argument"); return true; - } else if (IsJson(args, 0) != 3) { + } else if (args->args[0] && IsJson(args, 0) != 3) { strcpy(message, "Argument must be a Jbin tree"); return true; } else @@ -5002,21 +5194,27 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_serialize_init char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, char *, char *error) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; if (!g->Xchk) { - PBSON bsp = (PBSON)args->args[0]; + if (IsJson(args, 0) == 3) { + PBSON bsp = (PBSON)args->args[0]; - JsonSubSet(g); + JsonSubSet(g); - if (!(str = Serialize(g, bsp->Jsp, NULL, 0))) - str = strcpy(result, g->Message); + if (!(str = Serialize(g, bsp->Jsp, NULL, 0))) + str = strcpy(result, g->Message); + + // Keep result of constant function + g->Xchk = (initid->const_item) ? str : NULL; + } else { + *error = 1; + str = strcpy(result, "Argument is not a Jbin tree"); + } // endif - // Keep result of constant function - g->Xchk = (initid->const_item) ? str : NULL; } else str = (char*)g->Xchk; diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def index 67acb5dff29..897c8fa741e 100644 --- a/storage/connect/mysql-test/connect/disabled.def +++ b/storage/connect/mysql-test/connect/disabled.def @@ -1 +1 @@ -json_udf_bin : broken upstream in --ps +#json_udf_bin : broken upstream in --ps -- cgit v1.2.1 From ead4147b13aa828f3b8393a2fc294479df9e4bb3 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 26 May 2016 18:48:47 +0200 Subject: - Reconize the JDBC type -7 (BIT) modified: storage/connect/jdbconn.cpp - Add the global variable connect_java_wrapper This enables to use different wrappers modified: storage/connect/CMakeLists.txt renamed: storage/connect/java/ap/JdbcInterface.class -> storage/connect/JdbcApacheInterface.class renamed: storage/connect/java/ap/JdbcInterface.java -> storage/connect/JdbcApacheInterface.java renamed: storage/connect/java/ds/JdbcInterface.class -> storage/connect/JdbcDSInterface.class renamed: storage/connect/java/ds/JdbcInterface.java -> storage/connect/JdbcDSInterface.java modified: storage/connect/ha_connect.cc deleted: storage/connect/java/std/JdbcInterface.class deleted: storage/connect/java/std/JdbcInterface.java modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h - Add JDBC tests (disabled) modified: storage/connect/mysql-test/connect/disabled.def new file: storage/connect/mysql-test/connect/r/jdbc.result new file: storage/connect/mysql-test/connect/r/jdbc_new.result new file: storage/connect/mysql-test/connect/r/jdbc_oracle.result new file: storage/connect/mysql-test/connect/r/jdbc_postgresql.result new file: storage/connect/mysql-test/connect/std_data/girls.txt new file: storage/connect/mysql-test/connect/t/jdbc.test new file: storage/connect/mysql-test/connect/t/jdbc_new.test new file: storage/connect/mysql-test/connect/t/jdbc_oracle.test new file: storage/connect/mysql-test/connect/t/jdbc_postgresql.test new file: storage/connect/mysql-test/connect/t/jdbconn.inc new file: storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc - Typo modified: storage/connect/jsonudf.cpp --- storage/connect/CMakeLists.txt | 4 +- storage/connect/JdbcApacheInterface.class | Bin 0 -> 15357 bytes storage/connect/JdbcApacheInterface.java | 709 ++++++++++++++++++++ storage/connect/JdbcDSInterface.class | Bin 0 -> 16175 bytes storage/connect/JdbcDSInterface.java | 743 +++++++++++++++++++++ storage/connect/ha_connect.cc | 8 + storage/connect/java/ap/JdbcInterface.class | Bin 15339 -> 0 bytes storage/connect/java/ap/JdbcInterface.java | 709 -------------------- storage/connect/java/ds/JdbcInterface.class | Bin 16169 -> 0 bytes storage/connect/java/ds/JdbcInterface.java | 743 --------------------- storage/connect/java/std/JdbcInterface.class | Bin 15215 -> 0 bytes storage/connect/java/std/JdbcInterface.java | 712 -------------------- storage/connect/jdbconn.cpp | 23 +- storage/connect/jdbconn.h | 4 +- storage/connect/jsonudf.cpp | 15 +- storage/connect/mysql-test/connect/disabled.def | 17 +- storage/connect/mysql-test/connect/r/jdbc.result | 269 ++++++++ .../connect/mysql-test/connect/r/jdbc_new.result | 214 ++++++ .../mysql-test/connect/r/jdbc_oracle.result | 70 ++ .../mysql-test/connect/r/jdbc_postgresql.result | 65 ++ .../connect/mysql-test/connect/std_data/girls.txt | 5 + storage/connect/mysql-test/connect/t/jdbc.test | 143 ++++ storage/connect/mysql-test/connect/t/jdbc_new.test | 179 +++++ .../connect/mysql-test/connect/t/jdbc_oracle.test | 56 ++ .../mysql-test/connect/t/jdbc_postgresql.test | 53 ++ storage/connect/mysql-test/connect/t/jdbconn.inc | 31 + .../mysql-test/connect/t/jdbconn_cleanup.inc | 6 + 27 files changed, 2597 insertions(+), 2181 deletions(-) create mode 100644 storage/connect/JdbcApacheInterface.class create mode 100644 storage/connect/JdbcApacheInterface.java create mode 100644 storage/connect/JdbcDSInterface.class create mode 100644 storage/connect/JdbcDSInterface.java delete mode 100644 storage/connect/java/ap/JdbcInterface.class delete mode 100644 storage/connect/java/ap/JdbcInterface.java delete mode 100644 storage/connect/java/ds/JdbcInterface.class delete mode 100644 storage/connect/java/ds/JdbcInterface.java delete mode 100644 storage/connect/java/std/JdbcInterface.class delete mode 100644 storage/connect/java/std/JdbcInterface.java create mode 100644 storage/connect/mysql-test/connect/r/jdbc.result create mode 100644 storage/connect/mysql-test/connect/r/jdbc_new.result create mode 100644 storage/connect/mysql-test/connect/r/jdbc_oracle.result create mode 100644 storage/connect/mysql-test/connect/r/jdbc_postgresql.result create mode 100644 storage/connect/mysql-test/connect/std_data/girls.txt create mode 100644 storage/connect/mysql-test/connect/t/jdbc.test create mode 100644 storage/connect/mysql-test/connect/t/jdbc_new.test create mode 100644 storage/connect/mysql-test/connect/t/jdbc_oracle.test create mode 100644 storage/connect/mysql-test/connect/t/jdbc_postgresql.test create mode 100644 storage/connect/mysql-test/connect/t/jdbconn.inc create mode 100644 storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index 41c1667afff..254d074612a 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -240,7 +240,7 @@ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) IF(CONNECT_WITH_JDBC) # TODO: detect Java SDK and the presence of JDBC connectors - # TODO: Find how to compile and install the JdbcInterface.java class + # TODO: Find how to compile and install the java wrapper class # Find required libraries and include directories FIND_PACKAGE(Java) @@ -251,6 +251,8 @@ IF(CONNECT_WITH_JDBC) # SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) SET(CONNECT_SOURCES ${CONNECT_SOURCES} JdbcInterface.java JdbcInterface.class + JdbcDSInterface.java JdbcDSInterface.class + JdbcApacheInterface.java JdbcApacheInterface.class jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) add_definitions(-DJDBC_SUPPORT) ELSE() diff --git a/storage/connect/JdbcApacheInterface.class b/storage/connect/JdbcApacheInterface.class new file mode 100644 index 00000000000..acd4258e3d3 Binary files /dev/null and b/storage/connect/JdbcApacheInterface.class differ diff --git a/storage/connect/JdbcApacheInterface.java b/storage/connect/JdbcApacheInterface.java new file mode 100644 index 00000000000..fdbc5bff203 --- /dev/null +++ b/storage/connect/JdbcApacheInterface.java @@ -0,0 +1,709 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import org.apache.commons.dbcp2.BasicDataSource; + +public class JdbcApacheInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + static Hashtable pool = new Hashtable(); + + // === Constructors/finalize ========================================= + public JdbcApacheInterface() { + this(true); + } // end of default constructor + + public JdbcApacheInterface(boolean b) { + DEBUG = b; + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + BasicDataSource ds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif url + + try { + if ((ds = pool.get(url)) == null) { + ds = new BasicDataSource(); + ds.setDriverClassName(parms[0]); + ds.setUrl(url); + ds.setUsername(parms[2]); + ds.setPassword(parms[3]); + pool.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcApacheInterface diff --git a/storage/connect/JdbcDSInterface.class b/storage/connect/JdbcDSInterface.class new file mode 100644 index 00000000000..d56c04bd81f Binary files /dev/null and b/storage/connect/JdbcDSInterface.class differ diff --git a/storage/connect/JdbcDSInterface.java b/storage/connect/JdbcDSInterface.java new file mode 100644 index 00000000000..09f545bfb74 --- /dev/null +++ b/storage/connect/JdbcDSInterface.java @@ -0,0 +1,743 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import javax.sql.DataSource; + +import org.mariadb.jdbc.MariaDbDataSource; +import org.postgresql.jdbc2.optional.PoolingDataSource; +import com.mysql.cj.jdbc.MysqlDataSource; +import oracle.jdbc.pool.OracleDataSource; + +public class JdbcDSInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + Hashtable dst = null; + + // === Constructors/finalize ========================================= + public JdbcDSInterface() { + this(true); + } // end of default constructor + + public JdbcDSInterface(boolean b) { + DEBUG = b; + dst = new Hashtable(); + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + MysqlDataSource mds = null; + MariaDbDataSource ads = null; + OracleDataSource ods = null; + PoolingDataSource pds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif driver + + try { + if ((ds = dst.get(url)) == null) { + if (url.toLowerCase().contains("mysql")) { + mds = new MysqlDataSource(); + mds.setURL(url); + mds.setUser(parms[2]); + mds.setPassword(parms[3]); + ds = mds; + } else if (url.toLowerCase().contains("mariadb")) { + ads = new MariaDbDataSource(); + ads.setUrl(url); + ads.setUser(parms[2]); + ads.setPassword(parms[3]); + ds = ads; + } else if (url.toLowerCase().contains("oracle")) { + ods = new OracleDataSource(); + ods.setURL(url); + ods.setUser(parms[2]); + ods.setPassword(parms[3]); + ds = ods; + } else if (url.toLowerCase().contains("postgresql")) { + pds = new PoolingDataSource(); + pds.setUrl(url); + pds.setUser(parms[2]); + pds.setPassword(parms[3]); + ds = pds; + } else { + SetErrmsg("Unsupported driver"); + return -4; + } // endif driver + + dst.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcDSInterface diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 6ef6fa4eab3..c08722f2547 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -195,6 +195,7 @@ extern "C" { #if defined(JDBC_SUPPORT) char *JvmPath; char *ClassPath; + char *Wrapper; #endif // JDBC_SUPPORT #if defined(__WIN__) @@ -6874,6 +6875,12 @@ static MYSQL_SYSVAR_STR(class_path, ClassPath, "Java class path", // check_class_path, update_class_path, NULL, NULL, NULL); + +static MYSQL_SYSVAR_STR(java_wrapper, Wrapper, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Java wrapper class", + // check_class_path, update_class_path, + NULL, NULL, "JdbcInterface"); #endif // JDBC_SUPPORT @@ -6897,6 +6904,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= { #if defined(JDBC_SUPPORT) MYSQL_SYSVAR(jvm_path), MYSQL_SYSVAR(class_path), + MYSQL_SYSVAR(java_wrapper), #endif // JDBC_SUPPORT NULL }; diff --git a/storage/connect/java/ap/JdbcInterface.class b/storage/connect/java/ap/JdbcInterface.class deleted file mode 100644 index 0b08b2e9217..00000000000 Binary files a/storage/connect/java/ap/JdbcInterface.class and /dev/null differ diff --git a/storage/connect/java/ap/JdbcInterface.java b/storage/connect/java/ap/JdbcInterface.java deleted file mode 100644 index 10128cac682..00000000000 --- a/storage/connect/java/ap/JdbcInterface.java +++ /dev/null @@ -1,709 +0,0 @@ -import java.math.*; -import java.sql.*; -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; - -import org.apache.commons.dbcp2.BasicDataSource; - -public class JdbcInterface { - boolean DEBUG = false; - String Errmsg = "No error"; - Connection conn = null; - DatabaseMetaData dbmd = null; - Statement stmt = null; - PreparedStatement pstmt = null; - ResultSet rs = null; - ResultSetMetaData rsmd = null; - static Hashtable pool = new Hashtable(); - - // === Constructors/finalize ========================================= - public JdbcInterface() { - this(true); - } // end of default constructor - - public JdbcInterface(boolean b) { - DEBUG = b; - } // end of constructor - - private void SetErrmsg(Exception e) { - if (DEBUG) - System.out.println(e.getMessage()); - - Errmsg = e.toString(); - } // end of SetErrmsg - - private void SetErrmsg(String s) { - if (DEBUG) - System.out.println(s); - - Errmsg = s; - } // end of SetErrmsg - - public String GetErrmsg() { - String err = Errmsg; - - Errmsg = "No error"; - return err; - } // end of GetErrmsg - - public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { - int rc = 0; - String url = parms[1]; - BasicDataSource ds = null; - - if (url == null) { - SetErrmsg("URL cannot be null"); - return -1; - } // endif url - - try { - if ((ds = pool.get(url)) == null) { - ds = new BasicDataSource(); - ds.setDriverClassName(parms[0]); - ds.setUrl(url); - ds.setUsername(parms[2]); - ds.setPassword(parms[3]); - pool.put(url, ds); - } // endif ds - - // Get a connection from the data source - conn = ds.getConnection(); - - // Get the data base meta data object - dbmd = conn.getMetaData(); - - // Get a statement from the connection - if (scrollable) - stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - else - stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); - - if (DEBUG) - System.out.println("Statement type = " + stmt.getResultSetType() - + " concurrency = " + stmt.getResultSetConcurrency()); - - if (DEBUG) // Get the fetch size of a statement - System.out.println("Default fetch size = " + stmt.getFetchSize()); - - if (fsize != 0) { - // Set the fetch size - stmt.setFetchSize(fsize); - - if (DEBUG) - System.out.println("New fetch size = " + stmt.getFetchSize()); - - } // endif fsize - - } catch (SQLException se) { - SetErrmsg(se); - rc = -2; - } catch( Exception e ) { - SetErrmsg(e); - rc = -3; - } // end try/catch - - return rc; - } // end of JdbcConnect - - public int CreatePrepStmt(String sql) { - int rc = 0; - - try { - pstmt = conn.prepareStatement(sql); - } catch (SQLException se) { - SetErrmsg(se); - rc = -1; - } catch (Exception e) { - SetErrmsg(e); - rc = -2; - } // end try/catch - - return rc; - } // end of CreatePrepStmt - - public void SetStringParm(int i, String s) { - try { - pstmt.setString(i, s); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetStringParm - - public void SetIntParm(int i, int n) { - try { - pstmt.setInt(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetIntParm - - public void SetShortParm(int i, short n) { - try { - pstmt.setShort(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetShortParm - - public void SetBigintParm(int i, long n) { - try { - pstmt.setLong(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetBigintParm - - public void SetFloatParm(int i, float f) { - try { - pstmt.setFloat(i, f); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetFloatParm - - public void SetDoubleParm(int i, double d) { - try { - pstmt.setDouble(i, d); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetDoubleParm - - public void SetTimestampParm(int i, Timestamp t) { - try { - pstmt.setTimestamp(i, t); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetTimestampParm - - public int ExecutePrep() { - int n = -3; - - if (pstmt != null) try { - n = pstmt.executeUpdate(); - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of ExecutePrep - - public boolean ClosePrepStmt() { - boolean b = false; - - if (pstmt != null) try { - pstmt.close(); - pstmt = null; - } catch (SQLException se) { - SetErrmsg(se); - b = true; - } catch (Exception e) { - SetErrmsg(e); - b = true; - } // end try/catch - - return b; - } // end of ClosePrepStmt - - public int JdbcDisconnect() { - int rc = 0; - - // Cancel pending statement - if (stmt != null) - try { - System.out.println("Cancelling statement"); - stmt.cancel(); - } catch(SQLException se) { - SetErrmsg(se); - rc += 1; - } // nothing more we can do - - // Close the statement and the connection - if (rs != null) - try { - if (DEBUG) - System.out.println("Closing result set"); - - rs.close(); - } catch(SQLException se) { - SetErrmsg(se); - rc = 2; - } // nothing more we can do - - if (stmt != null) - try { - if (DEBUG) - System.out.println("Closing statement"); - - stmt.close(); - } catch(SQLException se) { - SetErrmsg(se); - rc += 4; - } // nothing more we can do - - ClosePrepStmt(); - - if (conn != null) - try { - if (DEBUG) - System.out.println("Closing connection"); - - conn.close(); - } catch (SQLException se) { - SetErrmsg(se); - rc += 8; - } //end try/catch - - if (DEBUG) - System.out.println("All closed"); - - return rc; - } // end of JdbcDisconnect - - public int GetMaxValue(int n) { - int m = 0; - - try { - switch (n) { - case 1: // Max columns in table - m = dbmd.getMaxColumnsInTable(); - break; - case 2: // Max catalog name length - m = dbmd.getMaxCatalogNameLength(); - break; - case 3: // Max schema name length - m = dbmd.getMaxSchemaNameLength(); - break; - case 4: // Max table name length - m = dbmd.getMaxTableNameLength(); - break; - case 5: // Max column name length - m = dbmd.getMaxColumnNameLength(); - break; - } // endswitch n - - } catch(Exception e) { - SetErrmsg(e); - m = -1; - } // end try/catch - - return m; - } // end of GetMaxValue - - public int GetColumns(String[] parms) { - int ncol = 0; - - try { - if (rs != null) rs.close(); - rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - } // endif rs - - } catch(SQLException se) { - SetErrmsg(se); - } // end try/catch - - return ncol; - } // end of GetColumns - - public int GetTables(String[] parms) { - int ncol = 0; - String[] typ = null; - - if (parms[3] != null) { - typ = new String[1]; - typ[0] = parms[3]; - } // endif parms - - try { - if (rs != null) rs.close(); - rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - } // endif rs - - } catch(SQLException se) { - SetErrmsg(se); - } // end try/catch - - return ncol; - } // end of GetColumns - - public int Execute(String query) { - int n = 0; - - if (DEBUG) - System.out.println("Executing '" + query + "'"); - - try { - boolean b = stmt.execute(query); - - if (b == false) { - n = stmt.getUpdateCount(); - if (rs != null) rs.close(); - } // endif b - - if (DEBUG) - System.out.println("Query '" + query + "' executed: n = " + n); - - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of Execute - - public int GetResult() { - int ncol = 0; - - try { - rs = stmt.getResultSet(); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - - if (DEBUG) - System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); - - } // endif rs - - } catch (SQLException se) { - SetErrmsg(se); - ncol = -1; - } catch (Exception e) { - SetErrmsg(e); - ncol = -2; - } //end try/catch - - return ncol; - } // end of GetResult - - public int ExecuteQuery(String query) { - int ncol = 0; - - if (DEBUG) - System.out.println("Executing query '" + query + "'"); - - try { - rs = stmt.executeQuery(query); - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - - if (DEBUG) { - System.out.println("Query '" + query + "' executed successfully"); - System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); - } // endif DEBUG - - } catch (SQLException se) { - SetErrmsg(se); - ncol = -1; - } catch (Exception e) { - SetErrmsg(e); - ncol = -2; - } //end try/catch - - return ncol; - } // end of ExecuteQuery - - public int ExecuteUpdate(String query) { - int n = 0; - - if (DEBUG) - System.out.println("Executing update query '" + query + "'"); - - try { - n = stmt.executeUpdate(query); - - if (DEBUG) - System.out.println("Update Query '" + query + "' executed: n = " + n); - - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of ExecuteUpdate - - public int ReadNext() { - if (rs != null) { - try { - return rs.next() ? 1 : 0; - } catch (SQLException se) { - SetErrmsg(se); - return -1; - } //end try/catch - - } else - return 0; - - } // end of ReadNext - - public boolean Fetch(int row) { - if (rs != null) { - try { - return rs.absolute(row); - } catch (SQLException se) { - SetErrmsg(se); - return false; - } //end try/catch - - } else - return false; - - } // end of Fetch - - public String ColumnName(int n) { - if (rsmd == null) { - System.out.println("No result metadata"); - } else try { - return rsmd.getColumnLabel(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ColumnName - - public int ColumnType(int n, String name) { - if (rsmd == null) { - System.out.println("No result metadata"); - } else try { - if (n == 0) - n = rs.findColumn(name); - - return rsmd.getColumnType(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 666; // Not a type - } // end of ColumnType - - public String ColumnDesc(int n, int[] val) { - if (rsmd == null) { - System.out.println("No result metadata"); - return null; - } else try { - val[0] = rsmd.getColumnType(n); - val[1] = rsmd.getPrecision(n); - val[2] = rsmd.getScale(n); - val[3] = rsmd.isNullable(n); - return rsmd.getColumnLabel(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ColumnDesc - - public String StringField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getString(n) : rs.getString(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of StringField - - public int IntField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getInt(n) : rs.getInt(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of IntField - - public long BigintField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); - return bigDecimal != null ? bigDecimal.longValue() : 0; - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of BiginttField - - public double DoubleField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0.; - } // end of DoubleField - - public float FloatField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of FloatField - - public boolean BooleanField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return false; - } // end of BooleanField - - public Date DateField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getDate(n) : rs.getDate(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of DateField - - public Time TimeField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getTime(n) : rs.getTime(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of TimeField - - public Timestamp TimestampField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of TimestampField - - public String ObjectField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ObjectField - - public int GetDrivers(String[] s, int mxs) { - int n = 0; - List drivers = Collections.list(DriverManager.getDrivers()); - int size = Math.min(mxs, drivers.size()); - - for (int i = 0; i < size; i++) { - Driver driver = (Driver)drivers.get(i); - - // Get name of driver - s[n++] = driver.getClass().getName(); - - // Get version info - s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); - s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; - s[n++] = driver.toString(); - } // endfor i - - return size; - } // end of GetDrivers - - /** - * Adds the specified path to the java library path - * from Fahd Shariff blog - * - * @param pathToAdd the path to add - static public int addLibraryPath(String pathToAdd) { - System.out.println("jpath = " + pathToAdd); - - try { - Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); - usrPathsField.setAccessible(true); - - //get array of paths - String[] paths = (String[])usrPathsField.get(null); - - //check if the path to add is already present - for (String path : paths) { - System.out.println("path = " + path); - - if (path.equals(pathToAdd)) - return -5; - - } // endfor path - - //add the new path - String[] newPaths = Arrays.copyOf(paths, paths.length + 1); - newPaths[paths.length] = pathToAdd; - usrPathsField.set(null, newPaths); - System.setProperty("java.library.path", - System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); - Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); - fieldSysPath.setAccessible(true); - fieldSysPath.set(null, null); - } catch (Exception e) { - SetErrmsg(e); - return -1; - } // end try/catch - - return 0; - } // end of addLibraryPath - */ - -} // end of class JdbcInterface diff --git a/storage/connect/java/ds/JdbcInterface.class b/storage/connect/java/ds/JdbcInterface.class deleted file mode 100644 index 85a52b016cb..00000000000 Binary files a/storage/connect/java/ds/JdbcInterface.class and /dev/null differ diff --git a/storage/connect/java/ds/JdbcInterface.java b/storage/connect/java/ds/JdbcInterface.java deleted file mode 100644 index fae688807f9..00000000000 --- a/storage/connect/java/ds/JdbcInterface.java +++ /dev/null @@ -1,743 +0,0 @@ -import java.math.*; -import java.sql.*; -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; - -import javax.sql.DataSource; - -import org.mariadb.jdbc.MariaDbDataSource; -import org.postgresql.jdbc2.optional.PoolingDataSource; -import com.mysql.cj.jdbc.MysqlDataSource; -import oracle.jdbc.pool.OracleDataSource; - -public class JdbcInterface { - boolean DEBUG = false; - String Errmsg = "No error"; - Connection conn = null; - DatabaseMetaData dbmd = null; - Statement stmt = null; - PreparedStatement pstmt = null; - ResultSet rs = null; - ResultSetMetaData rsmd = null; - Hashtable dst = null; - - // === Constructors/finalize ========================================= - public JdbcInterface() { - this(true); - } // end of default constructor - - public JdbcInterface(boolean b) { - DEBUG = b; - dst = new Hashtable(); - } // end of constructor - - private void SetErrmsg(Exception e) { - if (DEBUG) - System.out.println(e.getMessage()); - - Errmsg = e.toString(); - } // end of SetErrmsg - - private void SetErrmsg(String s) { - if (DEBUG) - System.out.println(s); - - Errmsg = s; - } // end of SetErrmsg - - public String GetErrmsg() { - String err = Errmsg; - - Errmsg = "No error"; - return err; - } // end of GetErrmsg - - public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { - int rc = 0; - String url = parms[1]; - DataSource ds = null; - MysqlDataSource mds = null; - MariaDbDataSource ads = null; - OracleDataSource ods = null; - PoolingDataSource pds = null; - - if (url == null) { - SetErrmsg("URL cannot be null"); - return -1; - } // endif driver - - try { - if ((ds = dst.get(url)) == null) { - if (url.toLowerCase().contains("mysql")) { - mds = new MysqlDataSource(); - mds.setURL(url); - mds.setUser(parms[2]); - mds.setPassword(parms[3]); - ds = mds; - } else if (url.toLowerCase().contains("mariadb")) { - ads = new MariaDbDataSource(); - ads.setUrl(url); - ads.setUser(parms[2]); - ads.setPassword(parms[3]); - ds = ads; - } else if (url.toLowerCase().contains("oracle")) { - ods = new OracleDataSource(); - ods.setURL(url); - ods.setUser(parms[2]); - ods.setPassword(parms[3]); - ds = ods; - } else if (url.toLowerCase().contains("postgresql")) { - pds = new PoolingDataSource(); - pds.setUrl(url); - pds.setUser(parms[2]); - pds.setPassword(parms[3]); - ds = pds; - } else { - SetErrmsg("Unsupported driver"); - return -4; - } // endif driver - - dst.put(url, ds); - } // endif ds - - // Get a connection from the data source - conn = ds.getConnection(); - - // Get the data base meta data object - dbmd = conn.getMetaData(); - - // Get a statement from the connection - if (scrollable) - stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - else - stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); - - if (DEBUG) - System.out.println("Statement type = " + stmt.getResultSetType() - + " concurrency = " + stmt.getResultSetConcurrency()); - - if (DEBUG) // Get the fetch size of a statement - System.out.println("Default fetch size = " + stmt.getFetchSize()); - - if (fsize != 0) { - // Set the fetch size - stmt.setFetchSize(fsize); - - if (DEBUG) - System.out.println("New fetch size = " + stmt.getFetchSize()); - - } // endif fsize - - } catch (SQLException se) { - SetErrmsg(se); - rc = -2; - } catch( Exception e ) { - SetErrmsg(e); - rc = -3; - } // end try/catch - - return rc; - } // end of JdbcConnect - - public int CreatePrepStmt(String sql) { - int rc = 0; - - try { - pstmt = conn.prepareStatement(sql); - } catch (SQLException se) { - SetErrmsg(se); - rc = -1; - } catch (Exception e) { - SetErrmsg(e); - rc = -2; - } // end try/catch - - return rc; - } // end of CreatePrepStmt - - public void SetStringParm(int i, String s) { - try { - pstmt.setString(i, s); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetStringParm - - public void SetIntParm(int i, int n) { - try { - pstmt.setInt(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetIntParm - - public void SetShortParm(int i, short n) { - try { - pstmt.setShort(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetShortParm - - public void SetBigintParm(int i, long n) { - try { - pstmt.setLong(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetBigintParm - - public void SetFloatParm(int i, float f) { - try { - pstmt.setFloat(i, f); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetFloatParm - - public void SetDoubleParm(int i, double d) { - try { - pstmt.setDouble(i, d); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetDoubleParm - - public void SetTimestampParm(int i, Timestamp t) { - try { - pstmt.setTimestamp(i, t); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetTimestampParm - - public int ExecutePrep() { - int n = -3; - - if (pstmt != null) try { - n = pstmt.executeUpdate(); - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of ExecutePrep - - public boolean ClosePrepStmt() { - boolean b = false; - - if (pstmt != null) try { - pstmt.close(); - pstmt = null; - } catch (SQLException se) { - SetErrmsg(se); - b = true; - } catch (Exception e) { - SetErrmsg(e); - b = true; - } // end try/catch - - return b; - } // end of ClosePrepStmt - - public int JdbcDisconnect() { - int rc = 0; - - // Cancel pending statement - if (stmt != null) - try { - System.out.println("Cancelling statement"); - stmt.cancel(); - } catch(SQLException se) { - SetErrmsg(se); - rc += 1; - } // nothing more we can do - - // Close the statement and the connection - if (rs != null) - try { - if (DEBUG) - System.out.println("Closing result set"); - - rs.close(); - } catch(SQLException se) { - SetErrmsg(se); - rc = 2; - } // nothing more we can do - - if (stmt != null) - try { - if (DEBUG) - System.out.println("Closing statement"); - - stmt.close(); - } catch(SQLException se) { - SetErrmsg(se); - rc += 4; - } // nothing more we can do - - ClosePrepStmt(); - - if (conn != null) - try { - if (DEBUG) - System.out.println("Closing connection"); - - conn.close(); - } catch (SQLException se) { - SetErrmsg(se); - rc += 8; - } //end try/catch - - if (DEBUG) - System.out.println("All closed"); - - return rc; - } // end of JdbcDisconnect - - public int GetMaxValue(int n) { - int m = 0; - - try { - switch (n) { - case 1: // Max columns in table - m = dbmd.getMaxColumnsInTable(); - break; - case 2: // Max catalog name length - m = dbmd.getMaxCatalogNameLength(); - break; - case 3: // Max schema name length - m = dbmd.getMaxSchemaNameLength(); - break; - case 4: // Max table name length - m = dbmd.getMaxTableNameLength(); - break; - case 5: // Max column name length - m = dbmd.getMaxColumnNameLength(); - break; - } // endswitch n - - } catch(Exception e) { - SetErrmsg(e); - m = -1; - } // end try/catch - - return m; - } // end of GetMaxValue - - public int GetColumns(String[] parms) { - int ncol = 0; - - try { - if (rs != null) rs.close(); - rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - } // endif rs - - } catch(SQLException se) { - SetErrmsg(se); - } // end try/catch - - return ncol; - } // end of GetColumns - - public int GetTables(String[] parms) { - int ncol = 0; - String[] typ = null; - - if (parms[3] != null) { - typ = new String[1]; - typ[0] = parms[3]; - } // endif parms - - try { - if (rs != null) rs.close(); - rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - } // endif rs - - } catch(SQLException se) { - SetErrmsg(se); - } // end try/catch - - return ncol; - } // end of GetColumns - - public int Execute(String query) { - int n = 0; - - if (DEBUG) - System.out.println("Executing '" + query + "'"); - - try { - boolean b = stmt.execute(query); - - if (b == false) { - n = stmt.getUpdateCount(); - if (rs != null) rs.close(); - } // endif b - - if (DEBUG) - System.out.println("Query '" + query + "' executed: n = " + n); - - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of Execute - - public int GetResult() { - int ncol = 0; - - try { - rs = stmt.getResultSet(); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - - if (DEBUG) - System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); - - } // endif rs - - } catch (SQLException se) { - SetErrmsg(se); - ncol = -1; - } catch (Exception e) { - SetErrmsg(e); - ncol = -2; - } //end try/catch - - return ncol; - } // end of GetResult - - public int ExecuteQuery(String query) { - int ncol = 0; - - if (DEBUG) - System.out.println("Executing query '" + query + "'"); - - try { - rs = stmt.executeQuery(query); - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - - if (DEBUG) { - System.out.println("Query '" + query + "' executed successfully"); - System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); - } // endif DEBUG - - } catch (SQLException se) { - SetErrmsg(se); - ncol = -1; - } catch (Exception e) { - SetErrmsg(e); - ncol = -2; - } //end try/catch - - return ncol; - } // end of ExecuteQuery - - public int ExecuteUpdate(String query) { - int n = 0; - - if (DEBUG) - System.out.println("Executing update query '" + query + "'"); - - try { - n = stmt.executeUpdate(query); - - if (DEBUG) - System.out.println("Update Query '" + query + "' executed: n = " + n); - - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of ExecuteUpdate - - public int ReadNext() { - if (rs != null) { - try { - return rs.next() ? 1 : 0; - } catch (SQLException se) { - SetErrmsg(se); - return -1; - } //end try/catch - - } else - return 0; - - } // end of ReadNext - - public boolean Fetch(int row) { - if (rs != null) { - try { - return rs.absolute(row); - } catch (SQLException se) { - SetErrmsg(se); - return false; - } //end try/catch - - } else - return false; - - } // end of Fetch - - public String ColumnName(int n) { - if (rsmd == null) { - System.out.println("No result metadata"); - } else try { - return rsmd.getColumnLabel(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ColumnName - - public int ColumnType(int n, String name) { - if (rsmd == null) { - System.out.println("No result metadata"); - } else try { - if (n == 0) - n = rs.findColumn(name); - - return rsmd.getColumnType(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 666; // Not a type - } // end of ColumnType - - public String ColumnDesc(int n, int[] val) { - if (rsmd == null) { - System.out.println("No result metadata"); - return null; - } else try { - val[0] = rsmd.getColumnType(n); - val[1] = rsmd.getPrecision(n); - val[2] = rsmd.getScale(n); - val[3] = rsmd.isNullable(n); - return rsmd.getColumnLabel(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ColumnDesc - - public String StringField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getString(n) : rs.getString(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of StringField - - public int IntField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getInt(n) : rs.getInt(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of IntField - - public long BigintField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); - return bigDecimal != null ? bigDecimal.longValue() : 0; - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of BiginttField - - public double DoubleField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0.; - } // end of DoubleField - - public float FloatField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of FloatField - - public boolean BooleanField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return false; - } // end of BooleanField - - public Date DateField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getDate(n) : rs.getDate(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of DateField - - public Time TimeField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getTime(n) : rs.getTime(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of TimeField - - public Timestamp TimestampField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of TimestampField - - public String ObjectField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ObjectField - - public int GetDrivers(String[] s, int mxs) { - int n = 0; - List drivers = Collections.list(DriverManager.getDrivers()); - int size = Math.min(mxs, drivers.size()); - - for (int i = 0; i < size; i++) { - Driver driver = (Driver)drivers.get(i); - - // Get name of driver - s[n++] = driver.getClass().getName(); - - // Get version info - s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); - s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; - s[n++] = driver.toString(); - } // endfor i - - return size; - } // end of GetDrivers - - /** - * Adds the specified path to the java library path - * from Fahd Shariff blog - * - * @param pathToAdd the path to add - static public int addLibraryPath(String pathToAdd) { - System.out.println("jpath = " + pathToAdd); - - try { - Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); - usrPathsField.setAccessible(true); - - //get array of paths - String[] paths = (String[])usrPathsField.get(null); - - //check if the path to add is already present - for (String path : paths) { - System.out.println("path = " + path); - - if (path.equals(pathToAdd)) - return -5; - - } // endfor path - - //add the new path - String[] newPaths = Arrays.copyOf(paths, paths.length + 1); - newPaths[paths.length] = pathToAdd; - usrPathsField.set(null, newPaths); - System.setProperty("java.library.path", - System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); - Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); - fieldSysPath.setAccessible(true); - fieldSysPath.set(null, null); - } catch (Exception e) { - SetErrmsg(e); - return -1; - } // end try/catch - - return 0; - } // end of addLibraryPath - */ - -} // end of class JdbcInterface diff --git a/storage/connect/java/std/JdbcInterface.class b/storage/connect/java/std/JdbcInterface.class deleted file mode 100644 index 8c5ba6439f3..00000000000 Binary files a/storage/connect/java/std/JdbcInterface.class and /dev/null differ diff --git a/storage/connect/java/std/JdbcInterface.java b/storage/connect/java/std/JdbcInterface.java deleted file mode 100644 index f9a6e734454..00000000000 --- a/storage/connect/java/std/JdbcInterface.java +++ /dev/null @@ -1,712 +0,0 @@ -import java.math.*; -import java.sql.*; -//import java.util.Arrays; -import java.util.Collections; -import java.util.List; -//import java.io.File; -//import java.lang.reflect.Field; - -public class JdbcInterface { - boolean DEBUG = false; - String Errmsg = "No error"; - Connection conn = null; - DatabaseMetaData dbmd = null; - Statement stmt = null; - PreparedStatement pstmt = null; - ResultSet rs = null; - ResultSetMetaData rsmd = null; - - // === Constructors/finalize ========================================= - public JdbcInterface() { - this(true); - } // end of default constructor - - public JdbcInterface(boolean b) { - DEBUG = b; - } // end of constructor - - private void SetErrmsg(Exception e) { - if (DEBUG) - System.out.println(e.getMessage()); - - Errmsg = e.toString(); - } // end of SetErrmsg - - public String GetErrmsg() { - String err = Errmsg; - - Errmsg = "No error"; - return err; - } // end of GetErrmsg - - public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { - int rc = 0; - - if (DEBUG) - System.out.println("In JdbcInterface: driver=" + parms[0]); - - try { - if (DEBUG) - System.out.println("In try block"); - - if (parms[0] != null && !parms[0].isEmpty()) { - if (DEBUG) - System.out.println("Loading class" + parms[0]); - - Class.forName(parms[0]); //loads the driver - } // endif driver - - if (DEBUG) - System.out.println("URL=" + parms[1]); - - if (parms[2] != null && !parms[2].isEmpty()) { - if (DEBUG) - System.out.println("user=" + parms[2] + " pwd=" + parms[3]); - - conn = DriverManager.getConnection(parms[1], parms[2], parms[3]); - } else - conn = DriverManager.getConnection(parms[1]); - - if (DEBUG) - System.out.println("Connection " + conn.toString() + " established"); - - // Get the data base meta data object - dbmd = conn.getMetaData(); - - // Get a statement from the connection - if (scrollable) - stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - else - stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); - - if (DEBUG) - System.out.println("Statement type = " + stmt.getResultSetType() - + " concurrency = " + stmt.getResultSetConcurrency()); - - if (DEBUG) // Get the fetch size of a statement - System.out.println("Default fetch size = " + stmt.getFetchSize()); - - if (fsize != 0) { - // Set the fetch size - stmt.setFetchSize(fsize); - - if (DEBUG) - System.out.println("New fetch size = " + stmt.getFetchSize()); - - } // endif fsize - - } catch(ClassNotFoundException e) { - SetErrmsg(e); - rc = -1; - } catch (SQLException se) { - SetErrmsg(se); - rc = -2; - } catch( Exception e ) { - SetErrmsg(e); - rc = -3; - } // end try/catch - - return rc; - } // end of JdbcConnect - - public int CreatePrepStmt(String sql) { - int rc = 0; - - try { - pstmt = conn.prepareStatement(sql); - } catch (SQLException se) { - SetErrmsg(se); - rc = -1; - } catch (Exception e) { - SetErrmsg(e); - rc = -2; - } // end try/catch - - return rc; - } // end of CreatePrepStmt - - public void SetStringParm(int i, String s) { - try { - pstmt.setString(i, s); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetStringParm - - public void SetIntParm(int i, int n) { - try { - pstmt.setInt(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetIntParm - - public void SetShortParm(int i, short n) { - try { - pstmt.setShort(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetShortParm - - public void SetBigintParm(int i, long n) { - try { - pstmt.setLong(i, n); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetBigintParm - - public void SetFloatParm(int i, float f) { - try { - pstmt.setFloat(i, f); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetFloatParm - - public void SetDoubleParm(int i, double d) { - try { - pstmt.setDouble(i, d); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetDoubleParm - - public void SetTimestampParm(int i, Timestamp t) { - try { - pstmt.setTimestamp(i, t); - } catch (Exception e) { - SetErrmsg(e); - } // end try/catch - - } // end of SetTimestampParm - - public int ExecutePrep() { - int n = -3; - - if (pstmt != null) try { - n = pstmt.executeUpdate(); - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of ExecutePrep - - public boolean ClosePrepStmt() { - boolean b = false; - - if (pstmt != null) try { - pstmt.close(); - pstmt = null; - } catch (SQLException se) { - SetErrmsg(se); - b = true; - } catch (Exception e) { - SetErrmsg(e); - b = true; - } // end try/catch - - return b; - } // end of ClosePrepStmt - - public int JdbcDisconnect() { - int rc = 0; - - // Cancel pending statement - if (stmt != null) - try { - System.out.println("Cancelling statement"); - stmt.cancel(); - } catch(SQLException se) { - SetErrmsg(se); - rc += 1; - } // nothing more we can do - - // Close the statement and the connection - if (rs != null) - try { - if (DEBUG) - System.out.println("Closing result set"); - - rs.close(); - } catch(SQLException se) { - SetErrmsg(se); - rc = 2; - } // nothing more we can do - - if (stmt != null) - try { - if (DEBUG) - System.out.println("Closing statement"); - - stmt.close(); - } catch(SQLException se) { - SetErrmsg(se); - rc += 4; - } // nothing more we can do - - ClosePrepStmt(); - - if (conn != null) - try { - if (DEBUG) - System.out.println("Closing connection"); - - conn.close(); - } catch (SQLException se) { - SetErrmsg(se); - rc += 8; - } //end try/catch - - if (DEBUG) - System.out.println("All closed"); - - return rc; - } // end of JdbcDisconnect - - public int GetMaxValue(int n) { - int m = 0; - - try { - switch (n) { - case 1: // Max columns in table - m = dbmd.getMaxColumnsInTable(); - break; - case 2: // Max catalog name length - m = dbmd.getMaxCatalogNameLength(); - break; - case 3: // Max schema name length - m = dbmd.getMaxSchemaNameLength(); - break; - case 4: // Max table name length - m = dbmd.getMaxTableNameLength(); - break; - case 5: // Max column name length - m = dbmd.getMaxColumnNameLength(); - break; - } // endswitch n - - } catch(Exception e) { - SetErrmsg(e); - m = -1; - } // end try/catch - - return m; - } // end of GetMaxValue - - public int GetColumns(String[] parms) { - int ncol = 0; - - try { - if (rs != null) rs.close(); - rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - } // endif rs - - } catch(SQLException se) { - SetErrmsg(se); - } // end try/catch - - return ncol; - } // end of GetColumns - - public int GetTables(String[] parms) { - int ncol = 0; - String[] typ = null; - - if (parms[3] != null) { - typ = new String[1]; - typ[0] = parms[3]; - } // endif parms - - try { - if (rs != null) rs.close(); - rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - } // endif rs - - } catch(SQLException se) { - SetErrmsg(se); - } // end try/catch - - return ncol; - } // end of GetColumns - - public int Execute(String query) { - int n = 0; - - if (DEBUG) - System.out.println("Executing '" + query + "'"); - - try { - boolean b = stmt.execute(query); - - if (b == false) { - n = stmt.getUpdateCount(); - if (rs != null) rs.close(); - } // endif b - - if (DEBUG) - System.out.println("Query '" + query + "' executed: n = " + n); - - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of Execute - - public int GetResult() { - int ncol = 0; - - try { - rs = stmt.getResultSet(); - - if (rs != null) { - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - - if (DEBUG) - System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); - - } // endif rs - - } catch (SQLException se) { - SetErrmsg(se); - ncol = -1; - } catch (Exception e) { - SetErrmsg(e); - ncol = -2; - } //end try/catch - - return ncol; - } // end of GetResult - - public int ExecuteQuery(String query) { - int ncol = 0; - - if (DEBUG) - System.out.println("Executing query '" + query + "'"); - - try { - rs = stmt.executeQuery(query); - rsmd = rs.getMetaData(); - ncol = rsmd.getColumnCount(); - - if (DEBUG) { - System.out.println("Query '" + query + "' executed successfully"); - System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); - } // endif DEBUG - - } catch (SQLException se) { - SetErrmsg(se); - ncol = -1; - } catch (Exception e) { - SetErrmsg(e); - ncol = -2; - } //end try/catch - - return ncol; - } // end of ExecuteQuery - - public int ExecuteUpdate(String query) { - int n = 0; - - if (DEBUG) - System.out.println("Executing update query '" + query + "'"); - - try { - n = stmt.executeUpdate(query); - - if (DEBUG) - System.out.println("Update Query '" + query + "' executed: n = " + n); - - } catch (SQLException se) { - SetErrmsg(se); - n = -1; - } catch (Exception e) { - SetErrmsg(e); - n = -2; - } //end try/catch - - return n; - } // end of ExecuteUpdate - - public int ReadNext() { - if (rs != null) { - try { - return rs.next() ? 1 : 0; - } catch (SQLException se) { - SetErrmsg(se); - return -1; - } //end try/catch - - } else - return 0; - - } // end of ReadNext - - public boolean Fetch(int row) { - if (rs != null) { - try { - return rs.absolute(row); - } catch (SQLException se) { - SetErrmsg(se); - return false; - } //end try/catch - - } else - return false; - - } // end of Fetch - - public String ColumnName(int n) { - if (rsmd == null) { - System.out.println("No result metadata"); - } else try { - return rsmd.getColumnLabel(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ColumnName - - public int ColumnType(int n, String name) { - if (rsmd == null) { - System.out.println("No result metadata"); - } else try { - if (n == 0) - n = rs.findColumn(name); - - return rsmd.getColumnType(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 666; // Not a type - } // end of ColumnType - - public String ColumnDesc(int n, int[] val) { - if (rsmd == null) { - System.out.println("No result metadata"); - return null; - } else try { - val[0] = rsmd.getColumnType(n); - val[1] = rsmd.getPrecision(n); - val[2] = rsmd.getScale(n); - val[3] = rsmd.isNullable(n); - return rsmd.getColumnLabel(n); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ColumnDesc - - public String StringField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getString(n) : rs.getString(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of StringField - - public int IntField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getInt(n) : rs.getInt(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of IntField - - public long BigintField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); - return bigDecimal != null ? bigDecimal.longValue() : 0; - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of BiginttField - - public double DoubleField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0.; - } // end of DoubleField - - public float FloatField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return 0; - } // end of FloatField - - public boolean BooleanField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return false; - } // end of BooleanField - - public Date DateField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getDate(n) : rs.getDate(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of DateField - - public Time TimeField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getTime(n) : rs.getTime(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of TimeField - - public Timestamp TimestampField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of TimestampField - - public String ObjectField(int n, String name) { - if (rs == null) { - System.out.println("No result set"); - } else try { - return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); - } catch (SQLException se) { - SetErrmsg(se); - } //end try/catch - - return null; - } // end of ObjectField - - public int GetDrivers(String[] s, int mxs) { - int n = 0; - List drivers = Collections.list(DriverManager.getDrivers()); - int size = Math.min(mxs, drivers.size()); - - for (int i = 0; i < size; i++) { - Driver driver = (Driver)drivers.get(i); - - // Get name of driver - s[n++] = driver.getClass().getName(); - - // Get version info - s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); - s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; - s[n++] = driver.toString(); - } // endfor i - - return size; - } // end of GetDrivers - - /** - * Adds the specified path to the java library path - * from Fahd Shariff blog - * - * @param pathToAdd the path to add - static public int addLibraryPath(String pathToAdd) { - System.out.println("jpath = " + pathToAdd); - - try { - Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); - usrPathsField.setAccessible(true); - - //get array of paths - String[] paths = (String[])usrPathsField.get(null); - - //check if the path to add is already present - for (String path : paths) { - System.out.println("path = " + path); - - if (path.equals(pathToAdd)) - return -5; - - } // endfor path - - //add the new path - String[] newPaths = Arrays.copyOf(paths, paths.length + 1); - newPaths[paths.length] = pathToAdd; - usrPathsField.set(null, newPaths); - System.setProperty("java.library.path", - System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); - Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); - fieldSysPath.setAccessible(true); - fieldSysPath.set(null, null); - } catch (Exception e) { - SetErrmsg(e); - return -1; - } // end try/catch - - return 0; - } // end of addLibraryPath - */ - -} // end of class JdbcInterface diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 23bd64bfb88..7a508cd989b 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -53,8 +53,9 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #endif // !__WIN__ int GetConvSize(); -extern char *JvmPath; // The connect_jvm_path global variable value -extern char *ClassPath; // The connect_class_path global variable value +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. */ @@ -645,8 +646,8 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) m_Tdb = tdbp; jvm = nullptr; // Pointer to the JVM (Java Virtual Machine) env= nullptr; // Pointer to native interface - jdi = nullptr; // Pointer to the JdbcInterface class - job = nullptr; // The JdbcInterface class object + jdi = nullptr; // Pointer to the java wrapper class + job = nullptr; // The java wrapper class object xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr; prepid = xpid = pcid = nullptr; chrfldid = intfldid = dblfldid = fltfldid = datfldid = bigfldid = nullptr; @@ -1028,11 +1029,11 @@ int JDBConn::Open(PJPARM sop) printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); #endif //_DEBUG - // try to find the JdbcInterface class - jdi = env->FindClass("JdbcInterface"); + // try to find the java wrapper class + jdi = env->FindClass(Wrapper); if (jdi == nullptr) { - strcpy(g->Message, "ERROR: class JdbcInterface not found !"); + sprintf(g->Message, "ERROR: class %s not found!", Wrapper); return RC_FX; } // endif jdi @@ -1078,7 +1079,7 @@ int JDBConn::Open(PJPARM sop) jmethodID ctor = env->GetMethodID(jdi, "", "()V"); if (ctor == nullptr) { - strcpy(g->Message, "ERROR: JdbcInterface constructor not found !"); + sprintf(g->Message, "ERROR: %s constructor not found!", Wrapper); return RC_FX; } else job = env->NewObject(jdi, ctor); @@ -1087,7 +1088,7 @@ int JDBConn::Open(PJPARM sop) // we can then search for the method we want to call, // and invoke it for the object: if (job == nullptr) { - strcpy(g->Message, "JdbcInterface class object not constructed !"); + sprintf(g->Message, "%s class object not constructed!", Wrapper); return RC_FX; } // endif job @@ -1328,6 +1329,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 4: // INTEGER case 5: // SMALLINT case -6: // TINYINT + case -7: // BIT if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I")) val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn)); else @@ -1393,6 +1395,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case java.sql.Types.BOOLEAN: System.out.print(jdi.BooleanField(i)); */ + case 0: // NULL + val->SetNull(true); + // passthru default: val->Reset(); } // endswitch Type diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index a7744ba6ba1..db8a11716e5 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -152,8 +152,8 @@ protected: TDBJDBC *m_Tdb; JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) JNIEnv *env; // Pointer to native interface - jclass jdi; // Pointer to the JdbcInterface class - jobject job; // The JdbcInterface class object + jclass jdi; // Pointer to the java wrapper class + jobject job; // The java wrapper class object jmethodID xqid; // The ExecuteQuery method ID jmethodID xuid; // The ExecuteUpdate method ID jmethodID xid; // The Execute method ID diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 4cead259896..29af7b95f66 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -5235,21 +5235,28 @@ my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count != 1) { strcpy(message, "Unique argument must be an environment variable name"); return true; - } else + } else { + initid->maybe_null = true; return false; + } // endif count } // end of envar_init char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, char *is_null, char *) { char *str, name[256]; int n = MY_MIN(args->lengths[0], sizeof(name) - 1); memcpy(name, args->args[0], n); name[n] = 0; - str = getenv(name); - *res_length = (str) ? strlen(str) : 0; + + if (!(str = getenv(name))) { + *res_length = 0; + *is_null = 1; + } else + *res_length = strlen(str); + return str; } // end of envar diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def index 897c8fa741e..9b4570915c7 100644 --- a/storage/connect/mysql-test/connect/disabled.def +++ b/storage/connect/mysql-test/connect/disabled.def @@ -1 +1,16 @@ -#json_udf_bin : broken upstream in --ps +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# : BUG# +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +#json_udf_bin : broken upstream in --ps (fixed) +jdbc : Variable settings depend on machine configuration +jdbc_new : Variable settings depend on machine configuration +jdbc_oracle : Variable settings depend on machine configuration +jdbc_postgresql : Variable settings depend on machine configuration diff --git a/storage/connect/mysql-test/connect/r/jdbc.result b/storage/connect/mysql-test/connect/r/jdbc.result new file mode 100644 index 00000000000..5e844bc9900 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc.result @@ -0,0 +1,269 @@ +CREATE DATABASE connect; +USE connect; +CREATE TABLE t2 ( +id bigint not null, +msg varchar(500), +tm time, +dt date, +dtm datetime, +ts timestamp); +INSERT INTO t2 VALUES(455000000000, 'A very big number', '18:10:25', '2016-03-16', '1999-12-11 23:01:52', '2015-07-24 09:32:45'); +SELECT * FROM t2; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +# +# Testing JDBC connection to MySQL driver +# +USE test; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root'; +SELECT * FROM t1; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +INSERT INTO t1 VALUES(786325481247, 'Hello!', '19:45:03', '1933-08-10', '1985-11-12 09:02:44', '2014-06-17 10:32:01'); +Warnings: +Note 1105 t2: 1 affected rows +SELECT * FROM t1; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +786325481247 Hello! 19:45:03 1933-08-09 1985-11-12 09:02:44 2014-06-17 10:32:01 +DELETE FROM t1 WHERE msg = 'Hello!'; +Warnings: +Note 1105 t2: 1 affected rows +SELECT * FROM t1; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +DROP TABLE t1; +# +# Testing JDBC view +# +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root'; +SELECT * FROM t1; +id msg tm dt +455000000000 A very big number 18:10:25 2016-03-16 +SELECT msg, dt FROM t1; +msg dt +A very big number 2016-03-16 +DROP TABLE t1, connect.t2; +# +# Testing JDBC write operations +# +USE connect; +CREATE TABLE boys ( +name CHAR(12) NOT NULL, +city CHAR(11), +birth DATE DATE_FORMAT='DD/MM/YYYY', +hired DATE DATE_FORMAT='DD/MM/YYYY' flag=36) +ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; +SELECT * FROM boys; +name city birth hired +John Boston 1986-01-25 2010-06-02 +Henry Boston 1987-06-07 2008-04-01 +George San Jose 1981-08-10 2010-06-02 +Sam Chicago 1979-11-22 2007-10-10 +James Dallas 1992-05-13 2009-12-14 +Bill Boston 1986-09-11 2008-02-10 +USE test; +CREATE TABLE t3 ( +name CHAR(12) NOT NULL, +city CHAR(12), +birth DATE, +hired DATE); +INSERT INTO t3 VALUES('Donald','Atlanta','1999-04-01','2016-03-31'),('Mick','New York','1980-01-20','2002-09-11'); +SELECT * FROM t3; +name city birth hired +Donald Atlanta 1999-04-01 2016-03-31 +Mick New York 1980-01-20 2002-09-11 +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root' OPTION_LIST='scrollable=1'; +SELECT * FROM t1; +name city birth hired +John Boston 1986-01-25 2010-06-02 +Henry Boston 1987-06-07 2008-04-01 +George San Jose 1981-08-10 2010-06-02 +Sam Chicago 1979-11-22 2007-10-10 +James Dallas 1992-05-13 2009-12-14 +Bill Boston 1986-09-11 2008-02-10 +UPDATE t1 SET city = 'Phoenix' WHERE name = 'Henry'; +Warnings: +Note 1105 boys: 1 affected rows +INSERT INTO t1 SELECT * FROM t3; +Warnings: +Note 1105 boys: 2 affected rows +INSERT INTO t1 VALUES('Tom','Seatle','2002-03-15',NULL); +Warnings: +Note 1105 boys: 1 affected rows +SELECT * FROM t1; +name city birth hired +John Boston 1986-01-25 2010-06-02 +Henry Phoenix 1987-06-07 2008-04-01 +George San Jose 1981-08-10 2010-06-02 +Sam Chicago 1979-11-22 2007-10-10 +James Dallas 1992-05-13 2009-12-14 +Bill Boston 1986-09-11 2008-02-10 +Donald Atlanta 1999-04-01 2016-03-31 +Mick New York 1980-01-20 2002-09-11 +Tom Seatle 2002-03-15 1970-01-01 +DROP TABLE t3; +# +# Testing JDBC join operations +# +CREATE TABLE t3 ( +name CHAR(9) NOT NULL, +city CHAR(12) NOT NULL, +age INT(2)) +engine=CONNECT table_type=FIX file_name='girls.txt'; +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN connect.boys b where g.city = b.city; +name name city +Mary John Boston +Susan Sam Chicago +Betty Sam Chicago +Mary Bill Boston +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN t1 b where g.city = b.city; +name name city +Mary John Boston +Susan Sam Chicago +Betty Sam Chicago +Mary Bill Boston +DROP TABLE t1, t3, connect.boys; +# +# Testing MariaDB JDBC driver +# +USE connect; +CREATE TABLE emp ( +serialno CHAR(5) NOT NULL, +name VARCHAR(12) NOT NULL FLAG=6, +sex TINYINT(1) NOT NULL, +title VARCHAR(15) NOT NULL FLAG=20, +manager CHAR(5) NOT NULL, +department CHAR(4) NOT NULL FLAG=41, +secretary CHAR(5) NOT NULL FLAG=46, +salary DOUBLE(8,2) NOT NULL FLAG=52) +ENGINE=connect TABLE_TYPE=fix FILE_NAME='employee.dat' ENDING=1; +SELECT * FROM emp; +serialno name sex title manager department secretary salary +74200 BANCROFT 2 SALESMAN 70012 0318 24888 9600.00 +02345 SMITH 1 ENGINEER 31416 2452 11111 9000.00 +78943 MERCHANT 1 SALESMAN 70012 0318 24888 8700.00 +07654 FUNNIGUY 1 ADMINISTRATOR 40567 0319 33333 8500.00 +45678 BUGHAPPY 1 PROGRAMMER 40567 0319 12345 8500.00 +34567 BIGHEAD 1 SCIENTIST 31416 2452 11111 8000.00 +77777 SHRINKY 2 ADMINISTRATOR 70012 0318 27845 7500.00 +74234 WALTER 1 ENGINEER 70012 0318 24888 7400.00 +56789 FODDERMAN 1 SALESMAN 40567 0319 12345 7000.00 +73452 TONGHO 1 ENGINEER 70012 0318 24888 6800.00 +22222 SHORTSIGHT 2 SECRETARY 87777 0021 5500.00 +55555 MESSIFUL 2 SECRETARY 40567 0319 12345 5000.50 +27845 HONEY 2 SECRETARY 70012 0318 24888 4900.00 +98765 GOOSEPEN 1 ADMINISTRATOR 07654 0319 33333 4700.00 +11111 CHERRY 2 SECRETARY 31416 2452 4500.00 +33333 MONAPENNY 2 SECRETARY 07654 0319 3800.00 +12345 KITTY 2 TYPIST 40567 0319 3000.45 +24888 PLUMHEAD 2 TYPIST 27845 0318 2800.00 +87777 STRONG 1 DIRECTOR 0021 22222 23000.00 +76543 BULLOZER 1 SALESMAN 40567 0319 12345 14800.00 +70012 WERTHER 1 DIRECTOR 87777 0318 27845 14500.00 +40567 QUINN 1 DIRECTOR 87777 0319 55555 14000.00 +31416 ORELLY 1 ENGINEER 87777 2452 11111 13400.00 +36666 BIGHORN 1 SCIENTIST 31416 2452 11111 11000.00 +00137 BROWNY 1 ENGINEER 40567 0319 12345 10500.00 +73111 WHEELFOR 1 SALESMAN 70012 0318 24888 10030.00 +00023 MARTIN 1 ENGINEER 40567 0319 12345 10000.00 +USE test; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `serialno` char(5) NOT NULL, + `name` varchar(12) NOT NULL, + `sex` tinyint(3) NOT NULL, + `title` varchar(15) NOT NULL, + `manager` char(5) NOT NULL, + `department` char(4) NOT NULL, + `secretary` char(5) NOT NULL, + `salary` double(12,2) NOT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root' `TABLE_TYPE`='JDBC' `TABNAME`='emp' +SELECT * FROM t1; +serialno name sex title manager department secretary salary +74200 BANCROFT 2 SALESMAN 70012 0318 24888 9600.00 +02345 SMITH 1 ENGINEER 31416 2452 11111 9000.00 +78943 MERCHANT 1 SALESMAN 70012 0318 24888 8700.00 +07654 FUNNIGUY 1 ADMINISTRATOR 40567 0319 33333 8500.00 +45678 BUGHAPPY 1 PROGRAMMER 40567 0319 12345 8500.00 +34567 BIGHEAD 1 SCIENTIST 31416 2452 11111 8000.00 +77777 SHRINKY 2 ADMINISTRATOR 70012 0318 27845 7500.00 +74234 WALTER 1 ENGINEER 70012 0318 24888 7400.00 +56789 FODDERMAN 1 SALESMAN 40567 0319 12345 7000.00 +73452 TONGHO 1 ENGINEER 70012 0318 24888 6800.00 +22222 SHORTSIGHT 2 SECRETARY 87777 0021 5500.00 +55555 MESSIFUL 2 SECRETARY 40567 0319 12345 5000.50 +27845 HONEY 2 SECRETARY 70012 0318 24888 4900.00 +98765 GOOSEPEN 1 ADMINISTRATOR 07654 0319 33333 4700.00 +11111 CHERRY 2 SECRETARY 31416 2452 4500.00 +33333 MONAPENNY 2 SECRETARY 07654 0319 3800.00 +12345 KITTY 2 TYPIST 40567 0319 3000.45 +24888 PLUMHEAD 2 TYPIST 27845 0318 2800.00 +87777 STRONG 1 DIRECTOR 0021 22222 23000.00 +76543 BULLOZER 1 SALESMAN 40567 0319 12345 14800.00 +70012 WERTHER 1 DIRECTOR 87777 0318 27845 14500.00 +40567 QUINN 1 DIRECTOR 87777 0319 55555 14000.00 +31416 ORELLY 1 ENGINEER 87777 2452 11111 13400.00 +36666 BIGHORN 1 SCIENTIST 31416 2452 11111 11000.00 +00137 BROWNY 1 ENGINEER 40567 0319 12345 10500.00 +73111 WHEELFOR 1 SALESMAN 70012 0318 24888 10030.00 +00023 MARTIN 1 ENGINEER 40567 0319 12345 10000.00 +SELECT name, title, salary FROM t1 WHERE sex = 1; +name title salary +SMITH ENGINEER 9000.00 +MERCHANT SALESMAN 8700.00 +FUNNIGUY ADMINISTRATOR 8500.00 +BUGHAPPY PROGRAMMER 8500.00 +BIGHEAD SCIENTIST 8000.00 +WALTER ENGINEER 7400.00 +FODDERMAN SALESMAN 7000.00 +TONGHO ENGINEER 6800.00 +GOOSEPEN ADMINISTRATOR 4700.00 +STRONG DIRECTOR 23000.00 +BULLOZER SALESMAN 14800.00 +WERTHER DIRECTOR 14500.00 +QUINN DIRECTOR 14000.00 +ORELLY ENGINEER 13400.00 +BIGHORN SCIENTIST 11000.00 +BROWNY ENGINEER 10500.00 +WHEELFOR SALESMAN 10030.00 +MARTIN ENGINEER 10000.00 +DROP TABLE t1, connect.emp; +CREATE TABLE t2 (command varchar(128) not null,number int(5) not null flag=1,message varchar(255) flag=2) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mariadb://localhost:PORT/connect' OPTION_LIST='User=root,Execsrc=1'; +SELECT * FROM t2 WHERE command='drop table tx1'; +command number message +drop table tx1 0 Execute: java.sql.SQLSyntaxErrorException: Unknown table 'connect.tx1' +Query is : drop table tx1 +SELECT * FROM t2 WHERE command = 'create table tx1 (a int not null, b char(32), c double(8,2))'; +command number message +create table tx1 (a int not null, b char(32), c double(8,2)) 0 Affected rows +SELECT * FROM t2 WHERE command in ('insert into tx1 values(1,''The number one'',456.12)',"insert into tx1(a,b) values(2,'The number two'),(3,'The number three')"); +command number message +insert into tx1 values(1,'The number one',456.12) 1 Affected rows +insert into tx1(a,b) values(2,'The number two'),(3,'The number three') 2 Affected rows +SELECT * FROM t2 WHERE command='update tx1 set c = 3.1416 where a = 2'; +command number message +update tx1 set c = 3.1416 where a = 2 1 Affected rows +SELECT * FROM t2 WHERE command='select * from tx1'; +command number message +select * from tx1 3 Result set column number +SELECT * FROM t2 WHERE command='delete from tx1 where a = 2'; +command number message +delete from tx1 where a = 2 1 Affected rows +SELECT * FROM connect.tx1; +a b c +1 The number one 456.12 +3 The number three NULL +DROP TABLE t2; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:mariadb://localhost:PORT/connect' option_list='User=root,Maxres=50'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Table_Type Remark +connect NULL tx1 BASE TABLE +DROP TABLE t1; +DROP TABLE connect.tx1; +DROP DATABASE connect; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result new file mode 100644 index 00000000000..794ab050f05 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc_new.result @@ -0,0 +1,214 @@ +CREATE TABLE t1 (a int, b char(10)); +INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03'); +SELECT * FROM t1; +a b +NULL NULL +0 test00 +1 test01 +2 test02 +3 test03 +# +# Testing errors +# +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown'; +SELECT * FROM t1; +ERROR HY000: Got error 174 'Connecting: java.sql.SQLException: Access denied for user 'unknown'@'localhost' (using password: NO) rc=-2' from CONNECT +DROP TABLE t1; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root'; +ERROR HY000: Connecting: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'unknown' rc=-2 +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' + CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +ERROR HY000: Cannot get columns from unknown +SHOW CREATE TABLE t1; +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL, + `y` char(10) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +SELECT * FROM t1; +ERROR HY000: Got error 174 'ExecuteQuery: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'x' in 'field list'' from CONNECT +DROP TABLE t1; +CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +ALTER TABLE t1 RENAME t1backup; +SELECT * FROM t1; +ERROR HY000: Got error 174 'ExecuteQuery: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'test.t1' doesn't exist' from CONNECT +ALTER TABLE t1backup RENAME t1; +DROP TABLE t1; +# +# Testing SELECT, etc. +# +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(10) DEFAULT NULL, + `b` char(10) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b +0 NULL +0 test00 +1 test01 +2 test02 +3 test03 +DROP TABLE t1; +CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1' + CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` char(10) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC `TABNAME`='t1' +SELECT * FROM t1; +a b +0 NULL +0 test00 +1 test01 +2 test02 +3 test03 +DROP TABLE t1; +CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` char(10) NOT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +SELECT * FROM t1; +a b +0 +0 test00 +1 test01 +2 test02 +3 test03 +DROP TABLE t1; +CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +SELECT * FROM t1; +a b +0 NULL +0 0 +1 0 +2 0 +3 0 +DROP TABLE t1; +DROP TABLE t1; +# +# Testing numeric data types +# +CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` tinyint(4) DEFAULT NULL, + `b` smallint(6) DEFAULT NULL, + `c` mediumint(9) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` bigint(20) DEFAULT NULL, + `f` float DEFAULT NULL, + `g` double DEFAULT NULL, + `h` decimal(20,5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265); +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` tinyint(3) DEFAULT NULL, + `b` smallint(5) DEFAULT NULL, + `c` int(7) DEFAULT NULL, + `d` int(10) DEFAULT NULL, + `e` bigint(19) DEFAULT NULL, + `f` double(14,0) DEFAULT NULL, + `g` double(24,0) DEFAULT NULL, + `h` decimal(27,5) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b c d e f g h +100 3333 41235 1234567890 235000000000 3 3 3141.59265 +DROP TABLE t1; +DROP TABLE t1; +# +# Testing character data types +# +CREATE TABLE t1 (a char(12), b varchar(12)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(12) DEFAULT NULL, + `b` varchar(12) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES('Welcome','Hello, World'); +SELECT * FROM t1; +a b +Welcome Hello, World +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(12) DEFAULT NULL, + `b` varchar(12) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b +Welcome Hello, World +DROP TABLE t1; +DROP TABLE t1; +# +# Testing temporal data types +# +CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` time DEFAULT NULL, + `d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `e` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23'); +Warnings: +Note 1265 Data truncated for column 'a' at row 1 +Note 1265 Data truncated for column 'c' at row 1 +Warning 1265 Data truncated for column 'e' at row 1 +SELECT * FROM t1; +a b c d e +2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003 +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL, + `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `c` time DEFAULT NULL, + `d` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `e` date DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b c d e +2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003-01-01 +DROP TABLE t1; +DROP TABLE t1; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result new file mode 100644 index 00000000000..2e36891a037 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result @@ -0,0 +1,70 @@ +CREATE TABLE t2 ( +command varchar(128) not null, +number int(5) not null flag=1, +message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager,Execsrc=1'; +SELECT * FROM t2 WHERE command = 'drop table employee'; +command number message +drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist + +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; +command number message +create table employee (id int not null, name varchar(32), title char(16), salary number(8,2)) 0 Affected rows +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; +command number message +insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1 WHERE table_name='employee'; +Table_Cat Table_Schema Table_Name Table_Type Remark +NULL SYSTEM EMPLOYEE TABLE NULL +DROP TABLE t1; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks +NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL +NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 0 10 1 NULL +NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 0 10 1 NULL +NULL SYSTEM EMPLOYEE SALARY 3 NUMBER 8 0 2 10 1 NULL +DROP TABLE t1; +CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS ( +HOST 'jdbc:oracle:thin:@localhost:1521:xe', +DATABASE 'SYSTEM', +USER 'system', +PASSWORD 'manager', +PORT 0, +SOCKET '', +OWNER 'SYSTEM'); +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='oracle' tabname='EMPLOYEE'; +SELECT * FROM t1; +ID NAME TITLE SALARY +4567 Johnson Engineer 12560.50 +INSERT INTO t1 VALUES(6214, 'Clinton', 'Retired', NULL); +Warnings: +Note 1105 EMPLOYEE: 1 affected rows +UPDATE t1 set name='Trump' WHERE id = 4567; +Warnings: +Note 1105 EMPLOYEE: 1 affected rows +SELECT * FROM t1; +ID NAME TITLE SALARY +4567 Trump Engineer 12560.50 +6214 Clinton Retired 0.00 +DELETE FROM t1 WHERE id = 6214; +Warnings: +Note 1105 EMPLOYEE: 1 affected rows +SELECT * FROM t1; +ID NAME TITLE SALARY +4567 Trump Engineer 12560.50 +DROP TABLE t1; +SELECT * FROM t2 WHERE command = 'drop table employee'; +command number message +drop table employee 0 Affected rows +DROP TABLE t2; +DROP SERVER 'oracle'; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result new file mode 100644 index 00000000000..6d77d79d5d3 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result @@ -0,0 +1,65 @@ +CREATE TABLE t2 ( +command varchar(128) not null, +number int(5) not null flag=1, +message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1'; +SELECT * FROM t2 WHERE command='drop table employee'; +command number message +drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))'; +command number message +create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2)) 0 Affected rows +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; +command number message +insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Table_Type Remark + public employee TABLE NULL + public t1 TABLE NULL + public t2 TABLE NULL +DROP TABLE t1; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns +CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee +OPTION_LIST='User=mtr,Password=mtr,Maxres=10'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks +NULL public employee id 4 int4 10 0 0 10 0 NULL +NULL public employee name 12 varchar 32 0 0 10 1 NULL +NULL public employee title 1 bpchar 16 0 0 10 1 NULL +NULL public employee salary 2 numeric 8 0 2 10 1 NULL +DROP TABLE t1; +CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS ( +HOST 'localhost', +DATABASE 'mtr', +USER 'mtr', +PASSWORD 'mtr', +PORT 0, +SOCKET '', +OWNER 'root'); +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee'; +SELECT * FROM t1; +id name title salary +4567 Johnson Engineer 12560.50 +INSERT INTO t1 VALUES(3126,'Smith', 'Clerk', 5230.00); +Warnings: +Note 1105 public.employee: 1 affected rows +UPDATE t1 SET salary = salary + 100.00; +Warnings: +Note 1105 public.employee: 2 affected rows +SELECT * FROM t1; +id name title salary +4567 Johnson Engineer 12660.50 +3126 Smith Clerk 5330.00 +DROP TABLE t1; +DROP SERVER 'postgresql'; +SELECT * FROM t2 WHERE command='drop table employee'; +command number message +drop table employee 0 Affected rows +DROP TABLE t2; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/std_data/girls.txt b/storage/connect/mysql-test/connect/std_data/girls.txt new file mode 100644 index 00000000000..8c883d0d847 --- /dev/null +++ b/storage/connect/mysql-test/connect/std_data/girls.txt @@ -0,0 +1,5 @@ +Mary Boston 25 +Nancy Palo Alto 23 +Susan Chicago 18 +Betty Chicago 32 +Anne Denver 23 diff --git a/storage/connect/mysql-test/connect/t/jdbc.test b/storage/connect/mysql-test/connect/t/jdbc.test new file mode 100644 index 00000000000..9389747ad9c --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc.test @@ -0,0 +1,143 @@ +-- source jdbconn.inc + +let $MYSQLD_DATADIR= `select @@datadir`; +--copy_file $MTR_SUITE_DIR/std_data/girls.txt $MYSQLD_DATADIR/test/girls.txt + +let $PORT= `select @@port`; + +# +# This test is run against a local MariaDB server +# +CREATE DATABASE connect; +USE connect; +CREATE TABLE t2 ( + id bigint not null, + msg varchar(500), + tm time, + dt date, + dtm datetime, + ts timestamp); +INSERT INTO t2 VALUES(455000000000, 'A very big number', '18:10:25', '2016-03-16', '1999-12-11 23:01:52', '2015-07-24 09:32:45'); +SELECT * FROM t2; + +--echo # +--echo # Testing JDBC connection to MySQL driver +--echo # +USE test; +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' +SELECT * FROM t1; +INSERT INTO t1 VALUES(786325481247, 'Hello!', '19:45:03', '1933-08-10', '1985-11-12 09:02:44', '2014-06-17 10:32:01'); +SELECT * FROM t1; +DELETE FROM t1 WHERE msg = 'Hello!'; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # Testing JDBC view +--echo # +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' +SELECT * FROM t1; +SELECT msg, dt FROM t1; +DROP TABLE t1, connect.t2; + +--echo # +--echo # Testing JDBC write operations +--echo # +USE connect; +--copy_file $MTR_SUITE_DIR/std_data/boys.txt $MYSQLD_DATADIR/connect/boys.txt +CREATE TABLE boys ( + name CHAR(12) NOT NULL, + city CHAR(11), + birth DATE DATE_FORMAT='DD/MM/YYYY', + hired DATE DATE_FORMAT='DD/MM/YYYY' flag=36) +ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; +SELECT * FROM boys; + +USE test; +CREATE TABLE t3 ( + name CHAR(12) NOT NULL, + city CHAR(12), + birth DATE, + hired DATE); +INSERT INTO t3 VALUES('Donald','Atlanta','1999-04-01','2016-03-31'),('Mick','New York','1980-01-20','2002-09-11'); +SELECT * FROM t3; + +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' OPTION_LIST='scrollable=1' +SELECT * FROM t1; +UPDATE t1 SET city = 'Phoenix' WHERE name = 'Henry'; +INSERT INTO t1 SELECT * FROM t3; +INSERT INTO t1 VALUES('Tom','Seatle','2002-03-15',NULL); +SELECT * FROM t1; +DROP TABLE t3; + +--echo # +--echo # Testing JDBC join operations +--echo # +CREATE TABLE t3 ( + name CHAR(9) NOT NULL, + city CHAR(12) NOT NULL, + age INT(2)) +engine=CONNECT table_type=FIX file_name='girls.txt'; +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN connect.boys b where g.city = b.city; +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN t1 b where g.city = b.city; +DROP TABLE t1, t3, connect.boys; + +--echo # +--echo # Testing MariaDB JDBC driver +--echo # +USE connect; +--copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/connect/employee.dat +CREATE TABLE emp ( + serialno CHAR(5) NOT NULL, + name VARCHAR(12) NOT NULL FLAG=6, + sex TINYINT(1) NOT NULL, + title VARCHAR(15) NOT NULL FLAG=20, + manager CHAR(5) NOT NULL, + department CHAR(4) NOT NULL FLAG=41, + secretary CHAR(5) NOT NULL FLAG=46, + salary DOUBLE(8,2) NOT NULL FLAG=52) +ENGINE=connect TABLE_TYPE=fix FILE_NAME='employee.dat' ENDING=1; +SELECT * FROM emp; + +USE test; +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:$PORT/connect?user=root' +--replace_result $PORT PORT +--eval SHOW CREATE TABLE t1 +SELECT * FROM t1; +SELECT name, title, salary FROM t1 WHERE sex = 1; + +DROP TABLE t1, connect.emp; + +# +# Testing remote command execution +# +--replace_result $PORT PORT +--eval CREATE TABLE t2 (command varchar(128) not null,number int(5) not null flag=1,message varchar(255) flag=2) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mariadb://localhost:$PORT/connect' OPTION_LIST='User=root,Execsrc=1' +SELECT * FROM t2 WHERE command='drop table tx1'; +SELECT * FROM t2 WHERE command = 'create table tx1 (a int not null, b char(32), c double(8,2))'; +SELECT * FROM t2 WHERE command in ('insert into tx1 values(1,''The number one'',456.12)',"insert into tx1(a,b) values(2,'The number two'),(3,'The number three')"); +SELECT * FROM t2 WHERE command='update tx1 set c = 3.1416 where a = 2'; +SELECT * FROM t2 WHERE command='select * from tx1'; +SELECT * FROM t2 WHERE command='delete from tx1 where a = 2'; +SELECT * FROM connect.tx1; +DROP TABLE t2; + +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:mariadb://localhost:$PORT/connect' option_list='User=root,Maxres=50' +SELECT * FROM t1; +DROP TABLE t1; +DROP TABLE connect.tx1; + +# +# Clean up +# +--remove_file $MYSQLD_DATADIR/connect/boys.txt +--remove_file $MYSQLD_DATADIR/connect/employee.dat +DROP DATABASE connect; +--remove_file $MYSQLD_DATADIR/test/girls.txt + +-- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbc_new.test b/storage/connect/mysql-test/connect/t/jdbc_new.test new file mode 100644 index 00000000000..33ec1b343cc --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc_new.test @@ -0,0 +1,179 @@ +# +# This test is run against a remote MySQL server +# +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,); +connection master; + +-- source jdbconn.inc + +connection slave; +CREATE TABLE t1 (a int, b char(10)); +INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03'); +SELECT * FROM t1; + +--echo # +--echo # Testing errors +--echo # +connection master; + +# Bad user name +# Suppress "mysql_real_connect failed:" (printed in _DEBUG build) +--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " "" +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown'; +--error ER_GET_ERRMSG +SELECT * FROM t1; +DROP TABLE t1; + +# Bad database name +--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " "" +--error ER_UNKNOWN_ERROR +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/unknown?user=root'; + +# Bad table name +--replace_result $SLAVE_MYPORT SLAVE_PORT +--error ER_UNKNOWN_ERROR +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t1; + +# Bad column name +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +--error ER_GET_ERRMSG +SELECT * FROM t1; +DROP TABLE t1; + +# The remote table disappeared +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + +connection slave; +ALTER TABLE t1 RENAME t1backup; + +connection master; +--error ER_GET_ERRMSG +SELECT * FROM t1; + +connection slave; +ALTER TABLE t1backup RENAME t1; + +connection master; +DROP TABLE t1; + +--echo # +--echo # Testing SELECT, etc. +--echo # + +# Automatic table structure +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +# Explicit table structure +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1' + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +# Explicit table structure: remote NULL, local NOT NULL +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +# Explicit table structure with wrong column types +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +--echo # +--echo # Testing numeric data types +--echo # + +# TODO: mediumint is converted to int, float is converted to double, decimal is converted to double +CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5)); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265); + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +--echo # +--echo # Testing character data types +--echo # + +CREATE TABLE t1 (a char(12), b varchar(12)); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES('Welcome','Hello, World'); +SELECT * FROM t1; + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +--echo # +--echo # Testing temporal data types +--echo # + +CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23'); +SELECT * FROM t1; + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +connection master; +-- source jdbconn_cleanup.inc + diff --git a/storage/connect/mysql-test/connect/t/jdbc_oracle.test b/storage/connect/mysql-test/connect/t/jdbc_oracle.test new file mode 100644 index 00000000000..10cb7a7b77d --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc_oracle.test @@ -0,0 +1,56 @@ +-- source jdbconn.inc + +# +# This test is run against Oracle driver +# +CREATE TABLE t2 ( + command varchar(128) not null, + number int(5) not null flag=1, + message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager,Execsrc=1'; +SELECT * FROM t2 WHERE command = 'drop table employee'; +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1 WHERE table_name='employee'; +DROP TABLE t1; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1; +DROP TABLE t1; + +# +# Test connecting via a Federated server +# +CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS ( +HOST 'jdbc:oracle:thin:@localhost:1521:xe', +DATABASE 'SYSTEM', +USER 'system', +PASSWORD 'manager', +PORT 0, +SOCKET '', +OWNER 'SYSTEM'); + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='oracle' tabname='EMPLOYEE'; +SELECT * FROM t1; +INSERT INTO t1 VALUES(6214, 'Clinton', 'Retired', NULL); +UPDATE t1 set name='Trump' WHERE id = 4567; +SELECT * FROM t1; +DELETE FROM t1 WHERE id = 6214; +SELECT * FROM t1; +DROP TABLE t1; +SELECT * FROM t2 WHERE command = 'drop table employee'; +DROP TABLE t2; +DROP SERVER 'oracle'; + +# +# Clean up +# + +-- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbc_postgresql.test b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test new file mode 100644 index 00000000000..1041ef468d7 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test @@ -0,0 +1,53 @@ +-- source jdbconn.inc + +# +# This test is run against Postgresql driver +# +CREATE TABLE t2 ( + command varchar(128) not null, + number int(5) not null flag=1, + message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1'; +SELECT * FROM t2 WHERE command='drop table employee'; +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))'; +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10'; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns +CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee +OPTION_LIST='User=mtr,Password=mtr,Maxres=10'; +SELECT * FROM t1; +DROP TABLE t1; + +# +# Test connecting via a Federated server +# +CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS ( +HOST 'localhost', +DATABASE 'mtr', +USER 'mtr', +PASSWORD 'mtr', +PORT 0, +SOCKET '', +OWNER 'root'); + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee'; +SELECT * FROM t1; +INSERT INTO t1 VALUES(3126,'Smith', 'Clerk', 5230.00); +UPDATE t1 SET salary = salary + 100.00; +SELECT * FROM t1; +DROP TABLE t1; +DROP SERVER 'postgresql'; +SELECT * FROM t2 WHERE command='drop table employee'; +DROP TABLE t2; + +# +# Clean up +# +-- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbconn.inc b/storage/connect/mysql-test/connect/t/jdbconn.inc new file mode 100644 index 00000000000..0bac0b35fc4 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbconn.inc @@ -0,0 +1,31 @@ +--source include/not_embedded.inc + +--disable_query_log +--error 0,ER_UNKNOWN_ERROR +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=drivers; +if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1' + AND ENGINE='CONNECT' + AND (CREATE_OPTIONS LIKE "%`table_type`='JDBC'%" OR CREATE_OPTIONS LIKE '%`table_type`=JDBC%')`) +{ + Skip Need Java support; +} +DROP TABLE t1; + +# This is specific and explains why this test is disabled. +# You should edit this file to reflect what is the required files location on your machine. +# This is the path to the JVM library (dll or so) +SET GLOBAL connect_jvm_path='C:\\Program Files\\Java\\jdk1.8.0_77\\jre\\bin\\client'; + +# The complete class path send when creating the Java Virtual Machine is, in that order: +# 1 - The current directory. +# 2 - The paths of the connect_class_path global variable. +# 3 - The paths of the CLASSPATH environment variable. +# These are the paths to the needed classes or jar files. The Apache ones are only for the JdbcApacheInterface wrapper. +SET GLOBAL connect_class_path='E:\\MariaDB-10.1\\Connect\\storage\\connect;E:\\MariaDB-10.1\\Connect\\sql\\data\\postgresql-9.4.1208.jar;E:\\Oracle\\ojdbc6.jar;E:\\Apache\\commons-dbcp2-2.1.1\\commons-dbcp2-2.1.1.jar;E:\\Apache\\commons-pool2-2.4.2\\commons-pool2-2.4.2.jar;E:\\Apache\\commons-logging-1.2\\commons-logging-1.2.jar'; + +# On my machine, paths to the JDK classes and to the MySQL and MariaDB drivers are defined in the CLASSPATH environment variable +#CREATE FUNCTION envar RETURNS STRING SONAME 'ha_connect.dll'; +#SELECT envar('CLASSPATH'); + +--enable_query_log diff --git a/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc b/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc new file mode 100644 index 00000000000..48e321495ad --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc @@ -0,0 +1,6 @@ +--disable_warnings +#DROP FUNCTION envar; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; +--enable_warnings -- cgit v1.2.1 From 613680a04179f0f5832832e82c429832aab322f5 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 2 Jun 2016 22:11:08 +0200 Subject: - Fix MDEV-10111 Reconize unsigned integers when creating tables via srcdef modified: storage/connect/ha_connect.cc modified: storage/connect/myconn.cpp - Fix MDEV-10136 crash on SELECT jsonget_string(NULL, 'a') modified: storage/connect/jsonudf.cpp - Assert longjmp initialized when suballocating modified: storage/connect/plugutil.c - Avoid crash in MakeRecord when table->vcol_set isnull (trace > 1) modified: storage/connect/ha_connect.cc --- storage/connect/ha_connect.cc | 4 ++-- storage/connect/jsonudf.cpp | 2 +- storage/connect/myconn.cpp | 8 ++++++-- storage/connect/plugutil.c | 4 +++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index c08722f2547..45ad4a484e1 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1961,7 +1961,7 @@ int ha_connect::MakeRecord(char *buf) if (trace > 1) htrc("Maps: read=%08X write=%08X vcol=%08X defr=%08X defw=%08X\n", *table->read_set->bitmap, *table->write_set->bitmap, - *table->vcol_set->bitmap, + (table->vcol_set) ? *table->vcol_set->bitmap : 0, *table->def_read_set.bitmap, *table->def_write_set.bitmap); // Avoid asserts in field::store() for columns that are not updated @@ -5619,7 +5619,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, len= crp->Length; dec= crp->Prec; flg= crp->Flag; - v= crp->Var; + v= (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var; tm= (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG; if (!len && typ == TYPE_STRING) diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 29af7b95f66..0bc964d7351 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1433,7 +1433,7 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n, char *p = args->args[0]; // Is this a file name? - if (!strchr("[{ \t\r\n", *p) && (len = GetFileLength(p))) + if (p && !strchr("[{ \t\r\n", *p) && (len = GetFileLength(p))) ml += len * (M + 1); else ml += args->lengths[0] * M; diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index e9bd64cf8e6..b844d68e1cd 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -901,8 +901,12 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb) if (fld->flags & NOT_NULL_FLAG) crp->Nulls = NULL; else { - crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); - memset(crp->Nulls, ' ', m_Rows); + if (m_Rows) { + crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); + memset(crp->Nulls, ' ', m_Rows); + } // endif m_Rows + + crp->Kdata->SetNullable(true); } // endelse fld->flags } // endfor fld diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c index 38e28a171b2..2551b603349 100644 --- a/storage/connect/plugutil.c +++ b/storage/connect/plugutil.c @@ -516,7 +516,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) if (trace) htrc("PlugSubAlloc: %s\n", g->Message); - longjmp(g->jumper[g->jump_level], 1); + /* Nothing we can do if longjmp is not initialized. */ + assert(g->jump_level >= 0); + longjmp(g->jumper[g->jump_level], 1); } /* endif size OS32 code */ /*********************************************************************/ -- cgit v1.2.1 From 74009534a10c1d30a85309cfca13a4cea37f0667 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 13 Jun 2016 12:58:24 +0200 Subject: - Possibly fix MDEV-10179 Reset remote tables when re-opening modified: storage/connect/tabtbl.cpp - Add trace and make m_Stmt conditional modified: storage/connect/myconn.cpp modified: storage/connect/myconn.h - Protect trace from null string (for Linux) modified: storage/connect/tabcol.cpp - Record error changes modified: storage/connect/mysql-test/connect/r/jdbc_new.result - Typo modified: storage/connect/jdbconn.cpp modified: storage/connect/jsonudf.cpp --- storage/connect/jdbconn.cpp | 2 +- storage/connect/jsonudf.cpp | 4 ++-- storage/connect/myconn.cpp | 24 +++++++++++++++++----- storage/connect/myconn.h | 6 ++++-- .../connect/mysql-test/connect/r/jdbc_new.result | 10 +++++---- storage/connect/tabcol.cpp | 2 +- storage/connect/tabtbl.cpp | 8 ++++++++ 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 7a508cd989b..a8c0b193dcd 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -2081,7 +2081,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) if (!m_Rows) { strcpy(g->Message, "Void result"); return NULL; - } // endif m_Res + } // endif m_Rows /*********************************************************************/ /* Allocate the result storage for future retrieval. */ diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 0bc964d7351..e94d3817926 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1,6 +1,6 @@ /****************** jsonudf C++ Program Source Code File (.CPP) ******************/ -/* PROGRAM NAME: jsonudf Version 1.3 */ -/* (C) Copyright to the author Olivier BERTRAND 2015 */ +/* PROGRAM NAME: jsonudf Version 1.4 */ +/* (C) Copyright to the author Olivier BERTRAND 2015-2016 */ /* This program are the JSON User Defined Functions . */ /*********************************************************************************/ diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index b844d68e1cd..644ca019e4a 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2007-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2007-2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -401,8 +401,10 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db, MYSQLC::MYSQLC(void) { m_DB = NULL; - m_Stmt = NULL; - m_Res = NULL; +#if defined (MYSQL_PREPARED_STATEMENTS) + m_Stmt = NULL; +#endif // MYSQL_PREPARED_STATEMENTS + m_Res = NULL; m_Rows = -1; m_Row = NULL; m_Fields = -1; @@ -444,7 +446,10 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, return RC_FX; } // endif m_DB - // Removed to do like FEDERATED do + if (trace) + htrc("MYSQLC Open: m_DB=%.4X size=%d\n", m_DB, (int)sizeof(*m_DB)); + + // Removed to do like FEDERATED do //mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb"); mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL); mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto); @@ -701,6 +706,11 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w) } else { m_Fields = mysql_num_fields(m_Res); m_Rows = (!m_Use) ? (int)mysql_num_rows(m_Res) : 0; + + if (trace) + htrc("ExecSQL: m_Res=%.4X size=%d m_Fields=%d m_Rows=%d\n", + m_Res, sizeof(*m_Res), m_Fields, m_Rows); + } // endif m_Res } else { @@ -1017,7 +1027,11 @@ int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w) void MYSQLC::Close(void) { FreeResult(); - mysql_close(m_DB); + + if (trace) + htrc("MYSQLC Close: m_DB=%.4X\n", m_DB); + + mysql_close(m_DB); m_DB = NULL; } // end of Close diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h index 79f095f5c93..9ebd37527a6 100644 --- a/storage/connect/myconn.h +++ b/storage/connect/myconn.h @@ -90,8 +90,10 @@ class DllItem MYSQLC { // Members MYSQL *m_DB; // The return from MySQL connection - MYSQL_STMT *m_Stmt; // Prepared statement handle - MYSQL_RES *m_Res; // Points to MySQL Result +#if defined (MYSQL_PREPARED_STATEMENTS) + MYSQL_STMT *m_Stmt; // Prepared statement handle +#endif // MYSQL_PREPARED_STATEMENTS + MYSQL_RES *m_Res; // Points to MySQL Result MYSQL_ROW m_Row; // Point to current row int m_Rows; // The number of rows of the result int N; diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result index 794ab050f05..e5356edd5d8 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_new.result +++ b/storage/connect/mysql-test/connect/r/jdbc_new.result @@ -17,7 +17,7 @@ ERROR HY000: Got error 174 'Connecting: java.sql.SQLException: Access denied for DROP TABLE t1; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root'; -ERROR HY000: Connecting: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'unknown' rc=-2 +ERROR HY000: Connecting: java.sql.SQLSyntaxErrorException: Unknown database 'unknown' rc=-2 CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; ERROR HY000: Cannot get columns from unknown @@ -32,13 +32,15 @@ t1 CREATE TABLE `t1` ( `y` char(10) DEFAULT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC SELECT * FROM t1; -ERROR HY000: Got error 174 'ExecuteQuery: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'x' in 'field list'' from CONNECT +ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Unknown column 'x' in 'field list' +Query is : SELECT x, y FROM t1' from CONNECT DROP TABLE t1; CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; ALTER TABLE t1 RENAME t1backup; SELECT * FROM t1; -ERROR HY000: Got error 174 'ExecuteQuery: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'test.t1' doesn't exist' from CONNECT +ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Table 'test.t1' doesn't exist +Query is : SELECT a, b FROM t1' from CONNECT ALTER TABLE t1backup RENAME t1; DROP TABLE t1; # @@ -206,7 +208,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' SELECT * FROM t1; a b c d e -2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003-01-01 +2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 1970-01-01 DROP TABLE t1; DROP TABLE t1; SET GLOBAL connect_jvm_path=NULL; diff --git a/storage/connect/tabcol.cpp b/storage/connect/tabcol.cpp index 662c0b514cf..fde1baa6317 100644 --- a/storage/connect/tabcol.cpp +++ b/storage/connect/tabcol.cpp @@ -50,7 +50,7 @@ XTAB::XTAB(PTABLE tp) : Name(tp->Name) Qualifier = tp->Qualifier; if (trace) - htrc(" making copy TABLE %s %s\n", Name, Srcdef); + htrc(" making copy TABLE %s %s\n", Name, SVP(Srcdef)); } // end of XTAB constructor diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index 36849146746..e3baf7c3da5 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -569,6 +569,9 @@ pthread_handler_t ThreadOpen(void *p) if (!my_thread_init()) { set_current_thd(cmp->Thd); + if (trace) + htrc("ThreadOpen: Thd=%d\n", cmp->Thd); + // Try to open the connection if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) { cmp->Ready = true; @@ -604,9 +607,14 @@ void TDBTBM::ResetDB(void) if (colp->GetAmType() == TYPE_AM_TABID) colp->COLBLK::Reset(); + // Local tables for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) ((PTDBASE)tabp->GetTo_Tdb())->ResetDB(); + // Remote tables + for (PTBMT tp = Tmp; tp; tp = tp->Next) + ((PTDBASE)tp->Tap->GetTo_Tdb())->ResetDB(); + Tdbp = (Tablist) ? (PTDBASE)Tablist->GetTo_Tdb() : NULL; Crp = 0; } // end of ResetDB -- cgit v1.2.1 From 7e64b079680b5f0f1e1cb735e3c83e45e96ec0e3 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 20 Jun 2016 16:37:57 +0200 Subject: - Add column pattern and table type argument to catalog tables modified: storage/connect/ha_connect.cc modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h modified: storage/connect/odbccat.h modified: storage/connect/odbconn.cpp modified: storage/connect/tabjdbc.cpp modified: storage/connect/tabjdbc.h modified: storage/connect/tabodbc.cpp modified: storage/connect/tabodbc.h - Avoid longjump in AllocCatInfo functions modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h modified: storage/connect/odbconn.cpp - Change GetColumns error return value from 0 to -1 modified: storage/connect/JdbcInterface.class modified: storage/connect/JdbcInterface.java --- storage/connect/JdbcInterface.class | Bin 15215 -> 15215 bytes storage/connect/JdbcInterface.java | 2 +- storage/connect/ha_connect.cc | 2 +- storage/connect/jdbconn.cpp | 49 ++++++++++-------------------------- storage/connect/jdbconn.h | 6 ++--- storage/connect/odbccat.h | 2 +- storage/connect/odbconn.cpp | 4 +-- storage/connect/tabjdbc.cpp | 20 ++++++++++++--- storage/connect/tabjdbc.h | 9 ++++--- storage/connect/tabodbc.cpp | 27 +++++++++++++++----- storage/connect/tabodbc.h | 15 +++++++---- 11 files changed, 75 insertions(+), 61 deletions(-) diff --git a/storage/connect/JdbcInterface.class b/storage/connect/JdbcInterface.class index 8c5ba6439f3..51a0e69bad5 100644 Binary files a/storage/connect/JdbcInterface.class and b/storage/connect/JdbcInterface.class differ diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java index f9a6e734454..8c4db1db8c3 100644 --- a/storage/connect/JdbcInterface.java +++ b/storage/connect/JdbcInterface.java @@ -307,7 +307,7 @@ public class JdbcInterface { } // end of GetMaxValue public int GetColumns(String[] parms) { - int ncol = 0; + int ncol = -1; try { if (rs != null) rs.close(); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 45ad4a484e1..6a8fc4514f1 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -5508,7 +5508,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, break; case FNC_TABLE: - qrp= ODBCTables(g, dsn, shm, tab, mxr, true, sop); + qrp= ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop); break; case FNC_DSN: qrp= ODBCDataSources(g, mxr, true); diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index a8c0b193dcd..9b479277df2 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -174,42 +174,20 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db, char *tab, PQRYRES qrp) { -//size_t m, n; JCATPARM *cap; #if defined(_DEBUG) assert(qrp); #endif - // Save stack and allocation environment and prepare error return - 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)); - cap->Id = fid; - cap->Qrp = qrp; - cap->DB = (PUCHAR)db; - cap->Tab = (PUCHAR)tab; -//cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *)); + if ((cap = (JCATPARM *)PlgDBSubAlloc(g, NULL, sizeof(JCATPARM)))) { + memset(cap, 0, sizeof(JCATPARM)); + cap->Id = fid; + cap->Qrp = qrp; + cap->DB = db; + cap->Tab = tab; + } // 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; } // end of AllocCatInfo @@ -291,7 +269,8 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp))) 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. */ @@ -402,7 +381,7 @@ PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp))) return NULL; - cap->Pat = (PUCHAR)tabtyp; + cap->Pat = tabtyp; if (trace) htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol); @@ -1931,9 +1910,9 @@ bool JDBConn::SetParam(JDBCCOL *colp) { PGLOBAL& g = m_G; // void *buffer; - int i; + int i, ncol; PSZ fnc = "Unknown"; - uint n, ncol; + uint n; short len, tp; int crow = 0; PQRYRES qrp = cap->Qrp; @@ -1956,9 +1935,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) env->SetObjectArrayElement(parms, 0, env->NewStringUTF(name.ptr(2))); env->SetObjectArrayElement(parms, 1, env->NewStringUTF(name.ptr(1))); 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 switch (cap->Id) { diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index db8a11716e5..abec3919e52 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -46,9 +46,9 @@ enum JCATINFO { typedef struct tagJCATPARM { JCATINFO Id; // Id to indicate function PQRYRES Qrp; // Result set pointer - PUCHAR DB; // Database (Schema) - PUCHAR Tab; // Table name or pattern - PUCHAR Pat; // Table type or column pattern + char *DB; // Database (Schema) + char *Tab; // Table name or pattern + char *Pat; // Table type or column pattern } JCATPARM; typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *); diff --git a/storage/connect/odbccat.h b/storage/connect/odbccat.h index 1b5febadd3a..3b729bcb4bb 100644 --- a/storage/connect/odbccat.h +++ b/storage/connect/odbccat.h @@ -21,5 +21,5 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table, char *colpat, int maxres, bool info, POPARM sop); PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src, POPARM sop); 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); diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 8b2626fe962..f1f8327f91a 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -606,7 +606,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info) /* an ODBC database that will be retrieved by GetData commands. */ /**************************************************************************/ 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, TYPE_STRING, TYPE_STRING}; @@ -668,7 +668,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat, if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp))) return NULL; -//cap->Pat = (PUCHAR)tabtyp; + cap->Pat = (PUCHAR)tabtyp; if (trace) htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol); diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index f507e3df3ea..e6782e71753 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -96,7 +96,7 @@ bool ExactInfo(void); /***********************************************************************/ JDBCDEF::JDBCDEF(void) { - Driver = Url = Tabname = Tabschema = Username = NULL; + Driver = Url = Tabname = Tabschema = Username = Colpat = NULL; Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL; Options = Quoted = Maxerr = Maxres = Memory = 0; Scrollable = Xsrc = false; @@ -237,7 +237,13 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); Tabschema = GetStringCatInfo(g, "Dbname", NULL); Tabschema = GetStringCatInfo(g, "Schema", Tabschema); - Tabtype = GetStringCatInfo(g, "Tabtype", NULL); + + if (Catfunc == FNC_COL) + Colpat = GetStringCatInfo(g, "Colpat", NULL); + + if (Catfunc == FNC_TABLE) + Tabtype = GetStringCatInfo(g, "Tabtype", NULL); + Qrystr = GetStringCatInfo(g, "Query_String", "?"); Sep = GetStringCatInfo(g, "Separator", NULL); Xsrc = GetBoolCatInfo("Execsrc", FALSE); @@ -1787,12 +1793,20 @@ PQRYRES TDBJTB::GetResult(PGLOBAL g) /* --------------------------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. */ /***********************************************************************/ PQRYRES TDBJDBCL::GetResult(PGLOBAL g) { - return JDBCColumns(g, Schema, Tab, NULL, Maxres, false, &Ops); + return JDBCColumns(g, Schema, Tab, Colpat, Maxres, false, &Ops); } // end of GetResult #if 0 diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h index 537276a6a7f..cf5e662c9d1 100644 --- a/storage/connect/tabjdbc.h +++ b/storage/connect/tabjdbc.h @@ -26,6 +26,7 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ friend class TDBXJDC; friend class TDBJDRV; friend class TDBJTB; + friend class TDBJDBCL; public: // Constructor JDBCDEF(void); @@ -58,6 +59,7 @@ protected: PSZ Password; /* Password connect info */ PSZ Tabcat; /* External table catalog */ PSZ Tabtype; /* External table type */ + PSZ Colpat; /* Catalog column pattern */ PSZ Srcdef; /* The source table SQL definition */ PSZ Qchar; /* Identifier quoting character */ PSZ Qrystr; /* The original query */ @@ -317,14 +319,15 @@ protected: class TDBJDBCL : public TDBJTB { public: // Constructor - TDBJDBCL(PJDBCDEF tdp) : TDBJTB(tdp) {} + TDBJDBCL(PJDBCDEF tdp); protected: // Specific routines virtual PQRYRES GetResult(PGLOBAL g); - // No additional Members -}; // end of class TDBJCL + // Members + char *Colpat; // Points to catalog column pattern +}; // end of class TDBJDBCL #if 0 /***********************************************************************/ diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index 5fd0534210d..8a43ca9e591 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -1,7 +1,7 @@ /************* Tabodbc C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABODBC */ /* ------------- */ -/* Version 3.0 */ +/* Version 3.1 */ /* */ /* COPYRIGHT: */ /* ---------- */ @@ -96,7 +96,7 @@ bool ExactInfo(void); ODBCDEF::ODBCDEF(void) { 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; Scrollable = Xsrc = UseCnc = false; } // end of ODBCDEF constructor @@ -120,7 +120,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Tabschema = GetStringCatInfo(g, "Schema", Tabschema); Tabcat = GetStringCatInfo(g, "Qualifier", NULL); Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); - Username = GetStringCatInfo(g, "User", NULL); + Username = GetStringCatInfo(g, "User", NULL); Password = GetStringCatInfo(g, "Password", NULL); if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) @@ -141,7 +141,13 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt) Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch - UseCnc = GetBoolCatInfo("UseDSN", false); + if (Catfunc == FNC_COL) + Colpat = GetStringCatInfo(g, "Colpat", NULL); + + if (Catfunc == FNC_TABLE) + Tabtyp = GetStringCatInfo(g, "Tabtype", NULL); + + UseCnc = GetBoolCatInfo("UseDSN", false); // Memory was Boolean, it is now integer if (!(Memory = GetIntCatInfo("Memory", 0))) @@ -1768,6 +1774,7 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) Dsn = tdp->GetConnect(); Schema = tdp->GetTabschema(); Tab = tdp->GetTabname(); + Tabtyp = tdp->Tabtyp; Ops.User = tdp->Username; Ops.Pwd = tdp->Password; Ops.Cto = tdp->Cto; @@ -1780,17 +1787,25 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) /***********************************************************************/ 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 /* ---------------------------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. */ /***********************************************************************/ 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 Tabodbc --------------------------- */ diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h index 6440dee830d..aa6592d8abf 100644 --- a/storage/connect/tabodbc.h +++ b/storage/connect/tabodbc.h @@ -25,7 +25,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ friend class TDBXDBC; friend class TDBDRV; friend class TDBOTB; - public: + friend class TDBOCL; +public: // Constructor ODBCDEF(void); @@ -54,7 +55,9 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ PSZ Username; /* User connect name */ PSZ Password; /* Password connect info */ PSZ Tabcat; /* External table catalog */ - PSZ Srcdef; /* The source table SQL definition */ + PSZ Tabtyp; /* Catalog table type */ + PSZ Colpat; /* Catalog column pattern */ + PSZ Srcdef; /* The source table SQL definition */ PSZ Qchar; /* Identifier quoting character */ PSZ Qrystr; /* The original query */ PSZ Sep; /* Decimal separator */ @@ -326,7 +329,8 @@ class TDBOTB : public TDBDRV { char *Dsn; // Points to connection string char *Schema; // Points to schema name or NULL char *Tab; // Points to ODBC table name or pattern - ODBCPARM Ops; // Additional parameters + char *Tabtyp; // Points to ODBC table type + ODBCPARM Ops; // Additional parameters }; // end of class TDBOTB /***********************************************************************/ @@ -335,13 +339,14 @@ class TDBOTB : public TDBDRV { class TDBOCL : public TDBOTB { public: // Constructor - TDBOCL(PODEF tdp) : TDBOTB(tdp) {} + TDBOCL(PODEF tdp); protected: // Specific routines virtual PQRYRES GetResult(PGLOBAL g); - // No additional Members + // Members + char *Colpat; // Points to column pattern }; // end of class TDBOCL #endif // !NODBC -- cgit v1.2.1