diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-08-10 19:58:42 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-08-10 19:58:42 +0200 |
commit | 2bd94951c6dbe7fe7e0b5d03dc97c2923dbd594e (patch) | |
tree | c491b686255d3aae701421aef9b2a9b12e50a960 /storage | |
parent | 077f29a921d8d689532a7e94078aec715ed2876c (diff) | |
parent | a2934d2710d24c20ec205007bdad2495a492ad83 (diff) | |
download | mariadb-git-2bd94951c6dbe7fe7e0b5d03dc97c2923dbd594e.tar.gz |
Merge branch 'connect/10.0' into 10.0
1.04.0008
Diffstat (limited to 'storage')
34 files changed, 962 insertions, 1708 deletions
diff --git a/storage/connect/ApacheInterface.java b/storage/connect/ApacheInterface.java new file mode 100644 index 00000000000..b4c8a4e9885 --- /dev/null +++ b/storage/connect/ApacheInterface.java @@ -0,0 +1,58 @@ +package wrappers; + +import java.sql.*; +import java.util.Hashtable; +import org.apache.commons.dbcp2.BasicDataSource; + +public class ApacheInterface extends JdbcInterface { + static Hashtable<String,BasicDataSource> pool = new Hashtable<String, BasicDataSource>(); + + public ApacheInterface() { + this(true); + } // end of default constructor + + public ApacheInterface(boolean b) { + super(b); + } // end of constructor + + @Override + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + BasicDataSource ds = null; + + if (DEBUG) + System.out.println("Connecting to Apache data source"); + + try { + CheckURL(url, null); + + 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 + stmt = GetStmt(fsize, scrollable); + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch (Exception e) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + +} // end of class ApacheInterface diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index c6b808acc60..95d88538119 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -235,25 +235,29 @@ ENDIF(CONNECT_WITH_ODBC) # # JDBC # - -OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) +IF(APPLE) + OPTION(CONNECT_WITH_JDBC "some comment" OFF) +ELSE() + OPTION(CONNECT_WITH_JDBC "some comment" ON) +ENDIF() IF(CONNECT_WITH_JDBC) - # TODO: detect Java SDK and the presence of JDBC connectors - # TODO: Find how to compile and install the java wrapper class - # Find required libraries and include directories - FIND_PACKAGE(Java 1.6) FIND_PACKAGE(JNI) IF (JAVA_FOUND AND JNI_FOUND) + INCLUDE(UseJava) 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 - JdbcDSInterface.java JdbcDSInterface.class - JdbcApacheInterface.java JdbcApacheInterface.class - jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) + # SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) will be dynamically linked + SET(CONNECT_SOURCES ${CONNECT_SOURCES} + jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h + JdbcInterface.java ApacheInterface.java MariadbInterface.java + MysqlInterface.java OracleInterface.java PostgresqlInterface.java) + # TODO: Find how to compile and install the java wrapper classes + # Find required libraries and include directories + SET (JAVA_SOURCES JdbcInterface.java) + add_jar(JdbcInterface ${JAVA_SOURCES}) + install_jar(JdbcInterface DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine) add_definitions(-DJDBC_SUPPORT) ELSE() SET(JDBC_LIBRARY "") diff --git a/storage/connect/Client.java b/storage/connect/Client.java new file mode 100644 index 00000000000..aaf1b7bf2f8 --- /dev/null +++ b/storage/connect/Client.java @@ -0,0 +1,183 @@ +package wrappers; + +import java.io.BufferedReader; +import java.io.Console; +import java.io.IOException; +import java.io.InputStreamReader; + +public class Client { + static boolean DEBUG = true; + static final Console c = System.console(); + static JdbcInterface jdi = null; + + public static void main(String[] args) { + int rc, n, ncol, i = 0, fsize = 0; + boolean scrollable = false; + String s; + String[] parms = new String[4]; + + if (args.length > 0) + try { + i = Integer.parseInt(args[i]); + } catch (NumberFormatException e) { + i = 0; + } // end try/catch + + switch (i) { + case 1: + jdi = new ApacheInterface(DEBUG); + break; + case 2: + jdi = new MysqlInterface(DEBUG); + break; + case 3: + jdi = new MariadbInterface(DEBUG); + break; + case 4: + jdi = new OracleInterface(DEBUG); + break; + case 5: + jdi = new PostgresqlInterface(DEBUG); + break; + default: + jdi = new JdbcInterface(DEBUG); + } // endswitch i + + parms[0] = getLine("Driver: ", false); + parms[1] = getLine("URL: ", false); + parms[2] = getLine("User: ", false); + parms[3] = getLine("Password: ", true); + s = getLine("Fsize: ", false); + fsize = (s != null) ? Integer.parseInt(s) : 0; + s = getLine("Scrollable: ", false); + scrollable = (s != null) ? s.toLowerCase().charAt(0) != 'n' : false; + + rc = jdi.JdbcConnect(parms, fsize, scrollable); + + if (rc == 0) { + String query; + System.out.println("Successfully connected to " + parms[1]); + + while ((query = getLine("Query: ", false)) != null) { + n = jdi.Execute(query); + System.out.println("Returned n = " + n); + + if ((ncol = jdi.GetResult()) > 0) + PrintResult(ncol); + else + System.out.println("Affected rows = " + n); + + } // endwhile + + rc = jdi.JdbcDisconnect(); + System.out.println("Disconnect returned " + rc); + } else + System.out.println(jdi.GetErrmsg() + " rc=" + rc); + + } // end of main + + private static void PrintResult(int ncol) { + // Get result set meta data + int i; + String columnName; + + // Get the column names; column indices start from 1 + for (i = 1; i <= ncol; i++) { + columnName = jdi.ColumnName(i); + + if (columnName == null) + return; + + // Get the name of the column's table name + //String tableName = rsmd.getTableName(i); + + if (i > 1) + System.out.print("\t"); + + System.out.print(columnName); + } // endfor i + + System.out.println(); + + // Loop through the result set + while (jdi.ReadNext() > 0) { + for (i = 1; i <= ncol; i++) { + if (i > 1) + System.out.print("\t"); + + if (DEBUG) + System.out.print("(" + jdi.ColumnType(i, null) + ")"); + + switch (jdi.ColumnType(i, null)) { + case java.sql.Types.VARCHAR: + case java.sql.Types.LONGVARCHAR: + case java.sql.Types.CHAR: + System.out.print(jdi.StringField(i, null)); + break; + case java.sql.Types.INTEGER: + System.out.print(jdi.IntField(i, null)); + break; + case java.sql.Types.BIGINT: + System.out.print(jdi.BigintField(i, null)); + break; + case java.sql.Types.TIMESTAMP: + System.out.print(jdi.TimestampField(i, null)); + break; + case java.sql.Types.TIME: + System.out.print(jdi.TimeField(i, null)); + break; + case java.sql.Types.DATE: + System.out.print(jdi.DateField(i, null)); + break; + case java.sql.Types.SMALLINT: + System.out.print(jdi.IntField(i, null)); + break; + case java.sql.Types.DOUBLE: + case java.sql.Types.REAL: + case java.sql.Types.FLOAT: + case java.sql.Types.DECIMAL: + System.out.print(jdi.DoubleField(i, null)); + break; + case java.sql.Types.BOOLEAN: + System.out.print(jdi.BooleanField(i, null)); + default: + break; + } // endswitch Type + + } // endfor i + + System.out.println(); + } // end while rs + + } // end of PrintResult + + // ================================================================== + private static String getLine(String p, boolean b) { + String response; + + if (c != null) { + // Standard console mode + if (b) { + response = new String(c.readPassword(p)); + } else + response = c.readLine(p); + + } else { + // For instance when testing from Eclipse + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + System.out.print(p); + + try { + // Cannot suppress echo for password entry + response = in.readLine(); + } catch (IOException e) { + response = ""; + } // end of try/catch + + } // endif c + + return (response.isEmpty()) ? null : response; + } // end of getLine + +} // end of class Client diff --git a/storage/connect/JdbcApacheInterface.class b/storage/connect/JdbcApacheInterface.class Binary files differdeleted file mode 100644 index acd4258e3d3..00000000000 --- a/storage/connect/JdbcApacheInterface.class +++ /dev/null diff --git a/storage/connect/JdbcApacheInterface.java b/storage/connect/JdbcApacheInterface.java deleted file mode 100644 index fdbc5bff203..00000000000 --- a/storage/connect/JdbcApacheInterface.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 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<String,BasicDataSource> pool = new Hashtable<String, BasicDataSource>(); - - // === 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<Driver> 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 Binary files differdeleted file mode 100644 index d56c04bd81f..00000000000 --- a/storage/connect/JdbcDSInterface.class +++ /dev/null diff --git a/storage/connect/JdbcDSInterface.java b/storage/connect/JdbcDSInterface.java deleted file mode 100644 index 09f545bfb74..00000000000 --- a/storage/connect/JdbcDSInterface.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 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<String,DataSource> dst = null; - - // === Constructors/finalize ========================================= - public JdbcDSInterface() { - this(true); - } // end of default constructor - - public JdbcDSInterface(boolean b) { - DEBUG = b; - dst = new Hashtable<String, DataSource>(); - } // 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<Driver> 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/JdbcInterface.class b/storage/connect/JdbcInterface.class Binary files differdeleted file mode 100644 index 8c5ba6439f3..00000000000 --- a/storage/connect/JdbcInterface.class +++ /dev/null diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java index f9a6e734454..f765052915d 100644 --- a/storage/connect/JdbcInterface.java +++ b/storage/connect/JdbcInterface.java @@ -1,13 +1,19 @@ +package wrappers; + import java.math.*; import java.sql.*; -//import java.util.Arrays; import java.util.Collections; +import java.util.Hashtable; import java.util.List; -//import java.io.File; -//import java.lang.reflect.Field; + +import javax.sql.DataSource; public class JdbcInterface { + // This is used by DS classes + static Hashtable<String,DataSource> dst = null; + boolean DEBUG = false; + boolean CatisSchema = false; String Errmsg = "No error"; Connection conn = null; DatabaseMetaData dbmd = null; @@ -18,14 +24,14 @@ public class JdbcInterface { // === Constructors/finalize ========================================= public JdbcInterface() { - this(true); + this(false); } // end of default constructor public JdbcInterface(boolean b) { DEBUG = b; } // end of constructor - private void SetErrmsg(Exception e) { + protected void SetErrmsg(Exception e) { if (DEBUG) System.out.println(e.getMessage()); @@ -38,6 +44,22 @@ public class JdbcInterface { Errmsg = "No error"; return err; } // end of GetErrmsg + + protected void CheckURL(String url, String vendor) throws Exception { + if (url == null) + throw new Exception("URL cannot be null"); + + String[] tk = url.split(":", 3); + + if (!tk[0].equals("jdbc") || tk[1] == null) + throw new Exception("Invalid URL"); + + if (vendor != null && !tk[1].equals(vendor)) + throw new Exception("Wrong URL for this wrapper"); + + // Some drivers use Catalog as Schema + CatisSchema = tk[1].equals("mysql") || tk[1].equals("mariadb"); + } // end of CatalogIsSchema public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { int rc = 0; @@ -58,6 +80,8 @@ public class JdbcInterface { if (DEBUG) System.out.println("URL=" + parms[1]); + + CheckURL(parms[1], null); if (parms[2] != null && !parms[2].isEmpty()) { if (DEBUG) @@ -74,27 +98,7 @@ public class JdbcInterface { 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 - + stmt = GetStmt(fsize, scrollable); } catch(ClassNotFoundException e) { SetErrmsg(e); rc = -1; @@ -109,6 +113,34 @@ public class JdbcInterface { return rc; } // end of JdbcConnect + protected Statement GetStmt(int fsize, boolean scrollable) throws SQLException, Exception { + Statement stmt = null; + + 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 + + return stmt; + } // end of GetStmt + + public int CreatePrepStmt(String sql) { int rc = 0; @@ -227,7 +259,9 @@ public class JdbcInterface { // Cancel pending statement if (stmt != null) try { - System.out.println("Cancelling statement"); + if (DEBUG) + System.out.println("Cancelling statement"); + stmt.cancel(); } catch(SQLException se) { SetErrmsg(se); @@ -307,11 +341,15 @@ public class JdbcInterface { } // end of GetMaxValue public int GetColumns(String[] parms) { - int ncol = 0; + int ncol = -1; try { if (rs != null) rs.close(); - rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (CatisSchema) + rs = dbmd.getColumns(parms[1], null, parms[2], parms[3]); + else + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); if (rs != null) { rsmd = rs.getMetaData(); @@ -326,7 +364,7 @@ public class JdbcInterface { } // end of GetColumns public int GetTables(String[] parms) { - int ncol = 0; + int ncol = -1; String[] typ = null; if (parms[3] != null) { @@ -336,7 +374,11 @@ public class JdbcInterface { try { if (rs != null) rs.close(); - rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (CatisSchema) + rs = dbmd.getTables(parms[1], null, parms[2], typ); + else + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); if (rs != null) { rsmd = rs.getMetaData(); @@ -599,40 +641,43 @@ public class JdbcInterface { return false; } // end of BooleanField - public Date DateField(int n, String name) { + public int 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); + Date d = (n > 0) ? rs.getDate(n) : rs.getDate(name); + return (d != null) ? (int)(d.getTime() / 1000) : 0; } catch (SQLException se) { SetErrmsg(se); } //end try/catch - return null; + return 0; } // end of DateField - public Time TimeField(int n, String name) { + public int 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); + Time t = (n > 0) ? rs.getTime(n) : rs.getTime(name); + return (t != null) ? (int)(t.getTime() / 1000) : 0; } catch (SQLException se) { SetErrmsg(se); } //end try/catch - return null; + return 0; } // end of TimeField - public Timestamp TimestampField(int n, String name) { + public int 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); + Timestamp ts = (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + return (ts != null) ? (int)(ts.getTime() / 1000) : 0; } catch (SQLException se) { SetErrmsg(se); } //end try/catch - return null; + return 0; } // end of TimestampField public String ObjectField(int n, String name) { @@ -710,3 +755,4 @@ public class JdbcInterface { */ } // end of class JdbcInterface + diff --git a/storage/connect/MariadbInterface.java b/storage/connect/MariadbInterface.java new file mode 100644 index 00000000000..26ff7a82301 --- /dev/null +++ b/storage/connect/MariadbInterface.java @@ -0,0 +1,69 @@ +package wrappers; + +import java.sql.*; +import java.util.Hashtable; + +import javax.sql.DataSource; +import org.mariadb.jdbc.MariaDbDataSource; + +public class MariadbInterface extends JdbcInterface { + public MariadbInterface() { + this(true); + } // end of default constructor + + public MariadbInterface(boolean b) { + super(b); + + if (dst == null) + dst = new Hashtable<String, DataSource>(); + + } // end of default constructor + + @Override + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + MariaDbDataSource ads = null; + + if (DEBUG) + System.out.println("Connecting to MariaDB data source"); + + try { + CheckURL(url, "mariadb"); + + if ((ds = dst.get(url)) == null) { + ads = new MariaDbDataSource(); + ads.setUrl(url); + + if (parms[2] != null) + ads.setUser(parms[2]); + + if (parms[3] != null) + ads.setPassword(parms[3]); + + ds = ads; + + 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 + stmt = GetStmt(fsize, scrollable); + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + +} diff --git a/storage/connect/MysqlInterface.java b/storage/connect/MysqlInterface.java new file mode 100644 index 00000000000..a13020e30b0 --- /dev/null +++ b/storage/connect/MysqlInterface.java @@ -0,0 +1,69 @@ +package wrappers; + +import java.sql.*; +import java.util.Hashtable; + +import javax.sql.DataSource; +import com.mysql.cj.jdbc.MysqlDataSource; + +public class MysqlInterface extends JdbcInterface { + public MysqlInterface() { + this(true); + } // end of default constructor + + public MysqlInterface(boolean b) { + super(b); + + if (dst == null) + dst = new Hashtable<String, DataSource>(); + + } // end of default constructor + + @Override + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + MysqlDataSource mds = null; + + if (DEBUG) + System.out.println("Connecting to MySQL data source"); + + try { + CheckURL(url, "mysql"); + + if ((ds = dst.get(url)) == null) { + mds = new MysqlDataSource(); + mds.setUrl(url); + + if (parms[2] != null) + mds.setUser(parms[2]); + + if (parms[3] != null) + mds.setPassword(parms[3]); + + ds = mds; + + 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 + stmt = GetStmt(fsize, scrollable); + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + +} // end of class MysqlInterface diff --git a/storage/connect/OracleInterface.java b/storage/connect/OracleInterface.java new file mode 100644 index 00000000000..0bfdd20e032 --- /dev/null +++ b/storage/connect/OracleInterface.java @@ -0,0 +1,69 @@ +package wrappers; + +import java.sql.*; +import java.util.Hashtable; + +import javax.sql.DataSource; +import oracle.jdbc.pool.OracleDataSource; + +public class OracleInterface extends JdbcInterface { + public OracleInterface() { + this(true); + } // end of OracleInterface constructor + + public OracleInterface(boolean b) { + super(b); + + if (dst == null) + dst = new Hashtable<String, DataSource>(); + + } // end of OracleInterface constructor + + @Override + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + OracleDataSource ods = null; + + if (DEBUG) + System.out.println("Connecting to Oracle data source"); + + try { + CheckURL(url, "oracle"); + + if ((ds = dst.get(url)) == null) { + ods = new OracleDataSource(); + ods.setURL(url); + + if (parms[2] != null) + ods.setUser(parms[2]); + + if (parms[3] != null) + ods.setPassword(parms[3]); + + ds = ods; + + 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 + stmt = GetStmt(fsize, scrollable); + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + +} // end of class OracleInterface diff --git a/storage/connect/PostgresqlInterface.java b/storage/connect/PostgresqlInterface.java new file mode 100644 index 00000000000..adce0616a1b --- /dev/null +++ b/storage/connect/PostgresqlInterface.java @@ -0,0 +1,69 @@ +package wrappers; + +import java.sql.*; +import java.util.Hashtable; + +import javax.sql.DataSource; +import org.postgresql.jdbc2.optional.PoolingDataSource; + +public class PostgresqlInterface extends JdbcInterface { + public PostgresqlInterface() { + this(true); + } // end of constructor + + public PostgresqlInterface(boolean b) { + super(b); + + if (dst == null) + dst = new Hashtable<String, DataSource>(); + + } // end of constructor + + @Override + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + PoolingDataSource pds = null; + + if (DEBUG) + System.out.println("Connecting to Postgresql data source"); + + try { + CheckURL(url, "postgresql"); + + if ((ds = dst.get(url)) == null) { + pds = new PoolingDataSource(); + pds.setUrl(url); + + if (parms[2] != null) + pds.setUser(parms[2]); + + if (parms[3] != null) + pds.setPassword(parms[3]); + + ds = pds; + + 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 + stmt = GetStmt(fsize, scrollable); + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + +} // end of class PostgresqlInterface diff --git a/storage/connect/connect.h b/storage/connect/connect.h index bbefda52274..ce4cf9bf8b9 100644 --- a/storage/connect/connect.h +++ b/storage/connect/connect.h @@ -65,7 +65,8 @@ class TDBDOX: public TDBDOS { friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*, bool*, key_part_map*); friend class ha_connect; - }; // end of class TDBDOX + TDBDOX() : TDBDOS((PGLOBAL)0, (PTDBDOS)0) {} /* Never called */ +}; // end of class TDBDOX class XKPDEF: public KPARTDEF { friend class TDBDOX; diff --git a/storage/connect/csort.cpp b/storage/connect/csort.cpp index 2f918782c80..13f325d8f3f 100644 --- a/storage/connect/csort.cpp +++ b/storage/connect/csort.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier Bertrand 1995-2012 */ +/* (C) Copyright to the author Olivier Bertrand 1995-2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -721,8 +721,8 @@ int CSORT::Qsortc(void) void CSORT::Qstc(int *base, int *max) { register int *i, *j, *jj, *lt, *eq, *gt, *mid; - int c, lo, hi, rc; - size_t zlo, zhi, cnm; + int c = 0, lo, hi, rc; + size_t zlo, zhi, cnm; zlo = zhi = cnm = 0; // Avoid warning message @@ -774,8 +774,11 @@ void CSORT::Qstc(int *base, int *max) /*****************************************************************/ /* Small group. Do special quicker processing. */ /*****************************************************************/ - if ((rc = Qcompare(base, (i = base + 1))) > 0) - c = *base, *base = *i, *i = c; + if ((rc = Qcompare(base, (i = base + 1))) > 0) { + c = *base; + *base = *i; + *i = c; + } // endif rc if (Pof) Pof[base - Pex] = Pof[i - Pex] = (rc) ? 1 : 2; diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 45ad4a484e1..ea6fb1b08c1 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -171,9 +171,9 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.04.0006 May 08, 2016"; + char version[]= "Version 1.04.0008 August 10, 2016"; #if defined(__WIN__) - char compver[]= "Version 1.04.0006 " __DATE__ " " __TIME__; + char compver[]= "Version 1.04.0008 " __DATE__ " " __TIME__; char slash= '\\'; #else // !__WIN__ char slash= '/'; @@ -195,7 +195,6 @@ extern "C" { #if defined(JDBC_SUPPORT) char *JvmPath; char *ClassPath; - char *Wrapper; #endif // JDBC_SUPPORT #if defined(__WIN__) @@ -211,7 +210,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); PQRYRES VirColumns(PGLOBAL g, bool info); PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info); PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info); -int TranslateJDBCType(int stp, int prec, int& len, char& v); +int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v); void PushWarning(PGLOBAL g, THD *thd, int level); bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, const char *db, char *tab, const char *src, int port); @@ -220,6 +219,7 @@ USETEMP UseTemp(void); int GetConvSize(void); TYPCONV GetTypeConv(void); uint GetJsonGrpSize(void); +char *GetJavaWrapper(void); uint GetWorkSize(void); void SetWorkSize(uint); extern "C" const char *msglang(void); @@ -332,6 +332,15 @@ static MYSQL_THDVAR_UINT(json_grp_size, "max number of rows for JSON aggregate functions.", NULL, NULL, JSONMAX, 1, INT_MAX, 1); +#if defined(JDBC_SUPPORT) +// Default java wrapper to use with JDBC tables +static MYSQL_THDVAR_STR(java_wrapper, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Java wrapper class name", + // check_class_path, update_class_path, + NULL, NULL, "wrappers/JdbcInterface"); +#endif // JDBC_SUPPORT + #if defined(XMSG) || defined(NEWMSG) const char *language_names[]= { @@ -384,6 +393,12 @@ extern "C" const char *msglang(void) return language_names[THDVAR(current_thd, msg_lang)]; } // end of msglang #else // !XMSG && !NEWMSG + +#if defined(JDBC_SUPPORT) +char *GetJavaWrapper(void) +{return connect_hton ? THDVAR(current_thd, java_wrapper) : (char*)"wrappers/JdbcInterface";} +#endif // JDBC_SUPPORT + extern "C" const char *msglang(void) { #if defined(FRENCH) @@ -1123,7 +1138,7 @@ bool GetBooleanTableOption(PGLOBAL g, PTOS options, char *opname, bool bdef) /****************************************************************************/ int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef) { - ulonglong opval= NO_IVAL; + ulonglong opval= (ulonglong) NO_IVAL; if (!options) return idef; @@ -5508,7 +5523,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); @@ -5633,6 +5648,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, } else { char *schem= NULL; + char *tn= NULL; // Not a catalog table if (!qrp->Nblin) { @@ -5649,7 +5665,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, typ= len= prec= dec= 0; tm= NOT_NULL_FLAG; cnm= (char*)"noname"; - dft= xtra= key= fmt= NULL; + dft= xtra= key= fmt= tn= NULL; v= ' '; rem= NULL; @@ -5669,7 +5685,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, typ= crp->Kdata->GetIntValue(i); v = (crp->Nulls) ? crp->Nulls[i] : 0; break; - case FLD_PREC: + case FLD_TYPENAME: + tn= crp->Kdata->GetCharValue(i); + break; + case FLD_PREC: // PREC must be always before LENGTH len= prec= crp->Kdata->GetIntValue(i); break; @@ -5713,8 +5732,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd, break; case FLD_SCHEM: -#if defined(ODBC_SUPPORT) - if (ttp == TAB_ODBC && crp->Kdata) { +#if defined(ODBC_SUPPORT) || defined(JDBC_SUPPORT) + if ((ttp == TAB_ODBC || ttp == TAB_JDBC) && crp->Kdata) { if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) { sprintf(g->Message, "Several %s tables found, specify DBNAME", tab); @@ -5724,7 +5743,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, schem= crp->Kdata->GetCharValue(i); } // endif ttp -#endif // ODBC_SUPPORT +#endif // ODBC_SUPPORT || JDBC_SUPPORT default: break; // Ignore } // endswitch Fld @@ -5777,7 +5796,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, int plgtyp; // typ must be PLG type, not SQL type - if (!(plgtyp= TranslateJDBCType(typ, dec, prec, v))) { + if (!(plgtyp= TranslateJDBCType(typ, tn, dec, prec, v))) { if (GetTypeConv() == TPC_SKIP) { // Skip this column sprintf(g->Message, "Column %s skipped (unsupported type %d)", @@ -6875,12 +6894,6 @@ 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 @@ -6922,7 +6935,7 @@ maria_declare_plugin(connect) 0x0104, /* version number (1.04) */ NULL, /* status variables */ connect_system_variables, /* system variables */ - "1.04.0006", /* string version */ + "1.04.0008", /* string version */ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ } maria_declare_plugin_end; diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index a8c0b193dcd..3b8de3e975b 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -6,6 +6,13 @@ /* This file contains the JDBC connection classes functions. */ /***********************************************************************/ +#if defined(__WIN__) +// This is needed for RegGetValue +#define _WINVER 0x0601 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 +#endif // __WIN__ + /***********************************************************************/ /* Include relevant MariaDB header file. */ /***********************************************************************/ @@ -52,10 +59,12 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #define nullptr 0 #endif // !__WIN__ +TYPCONV GetTypeConv(); int GetConvSize(); extern char *JvmPath; // The connect_jvm_path global variable value extern char *ClassPath; // The connect_class_path global variable value -extern char *Wrapper; // The connect_java_wrapper global variable value + +char *GetJavaWrapper(void); // The connect_java_wrapper variable value /***********************************************************************/ /* Static JDBConn objects. */ @@ -79,7 +88,7 @@ GETDEF JDBConn::GetDefaultJavaVMInitArgs = NULL; #endif // !_DEBUG // To avoid gcc warning -int TranslateJDBCType(int stp, int prec, int& len, char& v); +int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v); /***********************************************************************/ /* GetJDBCType: returns the SQL_TYPE corresponding to a PLG type. */ @@ -107,13 +116,16 @@ static short GetJDBCType(int type) /***********************************************************************/ /* TranslateJDBCType: translate a JDBC Type to a PLG type. */ /***********************************************************************/ -int TranslateJDBCType(int stp, int prec, int& len, char& v) +int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v) { int type; switch (stp) { case -1: // LONGVARCHAR - len = MY_MIN(abs(len), GetConvSize()); + if (GetTypeConv() != TPC_YES) + return TYPE_ERROR; + else + len = MY_MIN(abs(len), GetConvSize()); case 12: // VARCHAR v = 'V'; case 1: // CHAR @@ -139,17 +151,24 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) case 8: // DOUBLE type = TYPE_DOUBLE; break; - case 93: // TIMESTAMP + case 93: // TIMESTAMP, DATETIME type = TYPE_DATE; len = 19 + ((prec) ? (prec+1) : 0); - v = 'S'; + v = (tn && toupper(tn[0]) == 'T') ? 'S' : 'E'; break; - case 91: // TYPE_DATE + case 91: // DATE, YEAR type = TYPE_DATE; - len = 10; - v = 'D'; + + if (!tn || toupper(tn[0]) != 'Y') { + len = 10; + v = 'D'; + } else { + len = 4; + v = 'Y'; + } // endif len + break; - case 92: // TYPE_TIME + case 92: // TIME type = TYPE_DATE; len = 8 + ((prec) ? (prec+1) : 0); v = 'T'; @@ -174,42 +193,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 *)); - -//for (i = 0; i < n; i++) -// cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * 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 -//cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD)); - -fin: - g->jump_level--; return cap; } // end of AllocCatInfo @@ -291,7 +288,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 : PlugDup(g, "%"); /************************************************************************/ /* Now get the results into blocks. */ @@ -399,10 +397,12 @@ PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, if (info || !qrp) return qrp; - if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp))) + // Tabpat cannot be null or empty for some drivers + if (!(cap = AllocCatInfo(g, CAT_TAB, db, + (tabpat && *tabpat) ? tabpat : PlugDup(g, "%"), qrp))) return NULL; - cap->Pat = (PUCHAR)tabtyp; + cap->Pat = tabtyp; if (trace) htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol); @@ -650,11 +650,20 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) 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; -//m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; + chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr; + datfldid = timfldid = tspfldid = nullptr; + //m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; //m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; //m_UpdateOptions = 0; Msg = NULL; + m_Wrap = (tdbp && tdbp->WrapName) ? tdbp->WrapName : GetJavaWrapper(); + + if (!strchr(m_Wrap, '/')) { + // Add the wrapper package name + char *wn = (char*)PlugSubAlloc(g, NULL, strlen(m_Wrap) + 10); + m_Wrap = strcat(strcpy(wn, "wrappers/"), m_Wrap); + } // endif m_Wrap + m_Driver = NULL; m_Url = NULL; m_User = NULL; @@ -830,17 +839,52 @@ void JDBConn::ResetJVM(void) /***********************************************************************/ bool JDBConn::GetJVM(PGLOBAL g) { + int ntry; + if (!LibJvm) { char soname[512]; #if defined(__WIN__) - if (JvmPath) - strcat(strcpy(soname, JvmPath), "\\jvm.dll"); - else - strcpy(soname, "jvm.dll"); + for (ntry = 0; !LibJvm && ntry < 3; ntry++) { + if (!ntry && JvmPath) { + strcat(strcpy(soname, JvmPath), "\\jvm.dll"); + ntry = 3; // No other try + } else if (ntry < 2 && getenv("JAVA_HOME")) { + strcpy(soname, getenv("JAVA_HOME")); - // Load the desired shared library - if (!(LibJvm = LoadLibrary(soname))) { + if (ntry == 1) + strcat(soname, "\\jre"); + + strcat(soname, "\\bin\\client\\jvm.dll"); + } else { + // Try to find it through the registry + char version[16]; + char javaKey[64] = "SOFTWARE\\JavaSoft\\Java Runtime Environment"; + LONG rc; + DWORD BufferSize = 16; + + strcpy(soname, "jvm.dll"); // In case it fails + + if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "CurrentVersion", + RRF_RT_ANY, NULL, (PVOID)&version, &BufferSize)) == ERROR_SUCCESS) { + strcat(strcat(javaKey, "\\"), version); + BufferSize = sizeof(soname); + + if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "RuntimeLib", + RRF_RT_ANY, NULL, (PVOID)&soname, &BufferSize)) != ERROR_SUCCESS) + printf("RegGetValue: rc=%ld\n", rc); + + } // endif rc + + ntry = 3; // Try this only once + } // endelse + + // Load the desired shared library + LibJvm = LoadLibrary(soname); + } // endfor ntry + + // Get the needed entries + if (!LibJvm) { char buf[256]; DWORD rc = GetLastError(); @@ -871,13 +915,23 @@ bool JDBConn::GetJVM(PGLOBAL g) #else // !__WIN__ const char *error = NULL; - if (JvmPath) - strcat(strcpy(soname, JvmPath), "/libjvm.so"); - else - strcpy(soname, "libjvm.so"); + for (ntry = 0; !LibJvm && ntry < 2; ntry++) { + if (!ntry && JvmPath) { + strcat(strcpy(soname, JvmPath), "/libjvm.so"); + ntry = 2; + } else if (!ntry && getenv("JAVA_HOME")) { + // TODO: Replace i386 by a better guess + strcat(strcpy(soname, getenv("JAVA_HOME")), "/jre/lib/i386/client/libjvm.so"); + } else { // Will need LD_LIBRARY_PATH to be set + strcpy(soname, "libjvm.so"); + ntry = 2; + } // endelse + + LibJvm = dlopen(soname, RTLD_LAZY); + } // endfor ntry // Load the desired shared library - if (!(LibJvm = dlopen(soname, RTLD_LAZY))) { + if (!LibJvm) { error = dlerror(); sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error)); } else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) { @@ -911,7 +965,9 @@ bool JDBConn::GetJVM(PGLOBAL g) /***********************************************************************/ int JDBConn::Open(PJPARM sop) { + bool err = false; + jboolean jt = (trace > 0); PGLOBAL& g = m_G; // Link or check whether jvm library was linked @@ -951,6 +1007,11 @@ int JDBConn::Open(PJPARM sop) #define N 1 #endif + // Java source will be compiled as ajar file installed in the plugin dir + jpop->Append(sep); + jpop->Append(GetPluginDir()); + jpop->Append("JdbcInterface.jar"); + //================== prepare loading of Java VM ============================ JavaVMInitArgs vm_args; // Initialization arguments JavaVMOption* options = new JavaVMOption[N]; // JVM invocation options @@ -1021,19 +1082,16 @@ int JDBConn::Open(PJPARM sop) return RC_FX; } // endswitch rc + //=============== Display JVM version =============== + jint ver = env->GetVersion(); + printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); } // endif rc - //=============== Display JVM version ======================================= -#if defined(_DEBUG) - jint ver = env->GetVersion(); - printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); -#endif //_DEBUG - // try to find the java wrapper class - jdi = env->FindClass(Wrapper); + jdi = env->FindClass(m_Wrap); if (jdi == nullptr) { - sprintf(g->Message, "ERROR: class %s not found!", Wrapper); + sprintf(g->Message, "ERROR: class %s not found!", m_Wrap); return RC_FX; } // endif jdi @@ -1076,19 +1134,19 @@ int JDBConn::Open(PJPARM sop) #endif // 0 // if class found, continue - jmethodID ctor = env->GetMethodID(jdi, "<init>", "()V"); + jmethodID ctor = env->GetMethodID(jdi, "<init>", "(Z)V"); if (ctor == nullptr) { - sprintf(g->Message, "ERROR: %s constructor not found!", Wrapper); + sprintf(g->Message, "ERROR: %s constructor not found!", m_Wrap); return RC_FX; } else - job = env->NewObject(jdi, ctor); + job = env->NewObject(jdi, ctor, jt); // If the object is successfully constructed, // we can then search for the method we want to call, // and invoke it for the object: if (job == nullptr) { - sprintf(g->Message, "%s class object not constructed!", Wrapper); + sprintf(g->Message, "%s class object not constructed!", m_Wrap); return RC_FX; } // endif job @@ -1289,9 +1347,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) { PGLOBAL& g = m_G; jint ctyp; - jlong dtv; jstring cn, jn = nullptr; - jobject dob; if (rank == 0) if (!name || (jn = env->NewStringUTF(name)) == nullptr) { @@ -1354,31 +1410,22 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case 91: // DATE - case 92: // TIME - case 93: // TIMESTAMP - 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"); - - if (env->ExceptionCheck()) { - val->Reset(); - } else { - jmethodID getTime = env->GetMethodID(jts, "getTime", "()J"); - - if (getTime != nullptr) { - dtv = env->CallLongMethod(dob, getTime); - val->SetValue((int)(dtv / 1000)); - } else - val->Reset(); - - } // endif check + if (!gmID(g, datfldid, "DateField", "(ILjava/lang/String;)I")) { + val->SetValue((int)env->CallIntMethod(job, datfldid, (jint)rank, jn)); + } else + val->Reset(); - } else - val->Reset(); + break; + case 92: // TIME + if (!gmID(g, timfldid, "TimeField", "(ILjava/lang/String;)I")) { + val->SetValue((int)env->CallIntMethod(job, timfldid, (jint)rank, jn)); + } else + val->Reset(); + break; + case 93: // TIMESTAMP + if (!gmID(g, tspfldid, "TimestampField", "(ILjava/lang/String;)I")) { + val->SetValue((int)env->CallIntMethod(job, tspfldid, (jint)rank, jn)); } else val->Reset(); @@ -1931,9 +1978,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 +2003,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..095b1565bd2 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -24,7 +24,7 @@ //efine MAX_FNAME_LEN 256 // Max size of field names //efine MAX_STRING_INFO 256 // Max size of string from SQLGetInfo //efine MAX_DNAME_LEN 256 // Max size of Recordset names -#define MAX_CONNECT_LEN 512 // Max size of Connect string +//efine MAX_CONNECT_LEN 512 // Max size of Connect string //efine MAX_CURSOR_NAME 18 // Max size of a cursor name #define DEFAULT_FIELD_TYPE 0 // TYPE_NULL @@ -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 *); @@ -169,12 +169,15 @@ protected: 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 datfldid; // The DateField method ID + jmethodID timfldid; // The TimeField method ID + jmethodID tspfldid; // The TimestampField method ID jmethodID bigfldid; // The BigintField method ID //DWORD m_LoginTimeout; //DWORD m_QueryTimeout; //DWORD m_UpdateOptions; char *Msg; + char *m_Wrap; char m_IDQuoteChar[2]; PSZ m_Driver; PSZ m_Url; diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index e94d3817926..8bddc68e2ae 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -30,6 +30,10 @@ uint GetJsonGrpSize(void); static int IsJson(UDF_ARGS *args, uint i); static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i); +static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *error); +static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *error); static uint JsonGrpSize = 10; @@ -1302,7 +1306,7 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj, { char fn[_MAX_PATH]; unsigned long i, k, m, n; - long fl= 0, j = -1; + long fl = 0, j = -1; reslen = args->arg_count + 2; @@ -2126,7 +2130,7 @@ my_bool json_object_nonull_init(UDF_INIT *initid, UDF_ARGS *args, char *json_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *, char *) { - char *str= 0; + char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; if (!g->Xchk) { @@ -2699,7 +2703,7 @@ char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, } // endif Xchk if (!CheckMemory(g, initid, args, 2, false, false, true)) { - PJSON top= 0; + PJSON top = NULL; PJVAL jvp; PJSON jsp[2] = {NULL, NULL}; @@ -4899,7 +4903,7 @@ char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, my_bool b = true; PJSON jsp; PJSNX jsx; - PJVAL jvp= 0; + PJVAL jvp = NULL; PBSON bsp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; PGLOBAL gb = GetMemPtr(g, args, 0); diff --git a/storage/connect/mysql-test/connect/r/jdbc.result b/storage/connect/mysql-test/connect/r/jdbc.result index 5e844bc9900..895b4070d70 100644 --- a/storage/connect/mysql-test/connect/r/jdbc.result +++ b/storage/connect/mysql-test/connect/r/jdbc.result @@ -1,3 +1,4 @@ +SET GLOBAL time_zone='+1:00'; CREATE DATABASE connect; USE connect; CREATE TABLE t2 ( @@ -99,8 +100,8 @@ 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 +Donald Atlanta 1999-03-31 2016-03-30 +Mick New York 1980-01-20 2002-09-10 Tom Seatle 2002-03-15 1970-01-01 DROP TABLE t3; # @@ -110,7 +111,7 @@ 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'; +ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='girls.txt' ENDING=1; 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 @@ -167,8 +168,11 @@ serialno name sex title manager department secretary salary 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 +# +# Option Driver is required to find the Driver class inside the executable jar file +# USE test; -CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root'; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root' OPTION_LIST='Driver=org.mariadb.jdbc.Driver'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -180,7 +184,7 @@ t1 CREATE TABLE `t1` ( `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' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root' `TABLE_TYPE`='JDBC' `TABNAME`='emp' `OPTION_LIST`='Driver=org.mariadb.jdbc.Driver' SELECT * FROM t1; serialno name sex title manager department secretary salary 74200 BANCROFT 2 SALESMAN 70012 0318 24888 9600.00 @@ -260,10 +264,8 @@ 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 +connect NULL tx1 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; +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 index e5356edd5d8..14381b0b11f 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_new.result +++ b/storage/connect/mysql-test/connect/r/jdbc_new.result @@ -1,3 +1,4 @@ +SET GLOBAL time_zone='+1:00'; 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; @@ -10,6 +11,7 @@ NULL NULL # # Testing errors # +SET GLOBAL time_zone='+1:00'; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown'; SELECT * FROM t1; @@ -32,15 +34,13 @@ 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: java.sql.SQLSyntaxErrorException: Unknown column 'x' in 'field list' -Query is : SELECT x, y FROM t1' from CONNECT +ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: 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: java.sql.SQLSyntaxErrorException: Table 'test.t1' doesn't exist -Query is : SELECT a, b FROM t1' from CONNECT +ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Table 'test.t1' doesn't exist' from CONNECT ALTER TABLE t1backup RENAME t1; DROP TABLE t1; # @@ -201,16 +201,15 @@ 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, + `b` datetime DEFAULT NULL, `c` time DEFAULT NULL, - `d` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', - `e` date DEFAULT NULL + `d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `e` year(4) 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 1970-01-01 +2003-05-27 2003-05-27 11:45:23 10:45:23 2003-05-27 10:45:23 2003 DROP TABLE t1; DROP TABLE t1; -SET GLOBAL connect_jvm_path=NULL; -SET GLOBAL connect_class_path=NULL; -SET GLOBAL time_zone = SYSTEM; +SET GLOBAL time_zone=SYSTEM; +SET GLOBAL time_zone=SYSTEM; diff --git a/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar b/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar Binary files differnew file mode 100644 index 00000000000..81f91e4465a --- /dev/null +++ b/storage/connect/mysql-test/connect/std_data/JdbcMariaDB.jar diff --git a/storage/connect/mysql-test/connect/t/jdbc.test b/storage/connect/mysql-test/connect/t/jdbc.test index 9389747ad9c..41fd298776b 100644 --- a/storage/connect/mysql-test/connect/t/jdbc.test +++ b/storage/connect/mysql-test/connect/t/jdbc.test @@ -1,4 +1,5 @@ -- source jdbconn.inc +SET GLOBAL time_zone='+1:00'; let $MYSQLD_DATADIR= `select @@datadir`; --copy_file $MTR_SUITE_DIR/std_data/girls.txt $MYSQLD_DATADIR/test/girls.txt @@ -80,7 +81,7 @@ 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'; +ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='girls.txt' ENDING=1; 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; @@ -102,9 +103,12 @@ CREATE TABLE emp ( ENGINE=connect TABLE_TYPE=fix FILE_NAME='employee.dat' ENDING=1; SELECT * FROM emp; +--echo # +--echo # Option Driver is required to find the Driver class inside the executable jar file +--echo # 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' +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:$PORT/connect?user=root' OPTION_LIST='Driver=org.mariadb.jdbc.Driver' --replace_result $PORT PORT --eval SHOW CREATE TABLE t1 SELECT * FROM t1; @@ -113,7 +117,7 @@ SELECT name, title, salary FROM t1 WHERE sex = 1; DROP TABLE t1, connect.emp; # -# Testing remote command execution +# Testing remote command execution (Driver option is no more necessary) # --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' @@ -139,5 +143,5 @@ DROP TABLE connect.tx1; --remove_file $MYSQLD_DATADIR/connect/employee.dat DROP DATABASE connect; --remove_file $MYSQLD_DATADIR/test/girls.txt - +SET GLOBAL time_zone=SYSTEM; -- 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 index 33ec1b343cc..d1ad5117b72 100644 --- a/storage/connect/mysql-test/connect/t/jdbc_new.test +++ b/storage/connect/mysql-test/connect/t/jdbc_new.test @@ -8,6 +8,8 @@ connection master; -- source jdbconn.inc connection slave; +SET GLOBAL time_zone='+1:00'; + 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; @@ -16,6 +18,7 @@ SELECT * FROM t1; --echo # Testing errors --echo # connection master; +SET GLOBAL time_zone='+1:00'; # Bad user name # Suppress "mysql_real_connect failed:" (printed in _DEBUG build) @@ -173,7 +176,9 @@ DROP TABLE t1; connection slave; DROP TABLE t1; +SET GLOBAL time_zone=SYSTEM; connection master; +SET GLOBAL time_zone=SYSTEM; -- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbconn.inc b/storage/connect/mysql-test/connect/t/jdbconn.inc index 0bac0b35fc4..05122f51924 100644 --- a/storage/connect/mysql-test/connect/t/jdbconn.inc +++ b/storage/connect/mysql-test/connect/t/jdbconn.inc @@ -12,19 +12,20 @@ if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES } 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. +# You cand 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'; +# If not set CONNECT will try to use the JAVA_HOME environment variable +# and if not found try to find it in the registers (Windows only) +#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'; +# In this test we use an executable jar file that contains all what is needed. +eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JdbcMariaDB.jar'; -# On my machine, paths to the JDK classes and to the MySQL and MariaDB drivers are defined in the CLASSPATH environment variable +# Paths to the JDK classes and to the MySQL and MariaDB drivers can be defined in the CLASSPATH environment variable #CREATE FUNCTION envar RETURNS STRING SONAME 'ha_connect.dll'; #SELECT envar('CLASSPATH'); diff --git a/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc b/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc index 48e321495ad..d70e594df63 100644 --- a/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc +++ b/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc @@ -1,6 +1,8 @@ +--disable_query_log --disable_warnings #DROP FUNCTION envar; SET GLOBAL connect_jvm_path=NULL; SET GLOBAL connect_class_path=NULL; SET GLOBAL time_zone = SYSTEM; --enable_warnings +--enable_query_log 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..7320f4cc1d9 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -53,6 +53,7 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #endif // __WIN__ +TYPCONV GetTypeConv(); int GetConvSize(); /***********************************************************************/ @@ -135,9 +136,13 @@ int TranslateSQLType(int stp, int prec, int& len, char& v, bool& w) case SQL_WLONGVARCHAR: // (-10) w = true; case SQL_LONGVARCHAR: // (-1) - v = 'V'; - type = TYPE_STRING; - len = MY_MIN(abs(len), GetConvSize()); + if (GetTypeConv() == TPC_YES) { + v = 'V'; + type = TYPE_STRING; + len = MY_MIN(abs(len), GetConvSize()); + } else + type = TYPE_ERROR; + break; case SQL_NUMERIC: // 2 case SQL_DECIMAL: // 3 @@ -606,7 +611,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 +673,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); @@ -1752,7 +1757,7 @@ bool ODBConn::BindParam(ODBCCOL *colp) void *buf; int buftype = colp->GetResultType(); SQLUSMALLINT n = colp->GetRank(); - SQLSMALLINT ct, sqlt, dec, nul; + SQLSMALLINT ct, sqlt, dec, nul __attribute__((unused)); SQLULEN colsize; SQLLEN len; SQLLEN *strlen = colp->GetStrLen(); diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h index 6a24334f08c..063985218ec 100644 --- a/storage/connect/odbconn.h +++ b/storage/connect/odbconn.h @@ -25,7 +25,7 @@ //efine MAX_FNAME_LEN 256 // Max size of field names #define MAX_STRING_INFO 256 // Max size of string from SQLGetInfo //efine MAX_DNAME_LEN 256 // Max size of Recordset names -#define MAX_CONNECT_LEN 512 // Max size of Connect string +#define MAX_CONNECT_LEN 1024 // Max size of Connect string //efine MAX_CURSOR_NAME 18 // Max size of a cursor name #define DEFAULT_FIELD_TYPE SQL_TYPE_NULL // pick "C" data type to match SQL data type diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index f507e3df3ea..86fd831b262 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 = Wrapname =Tabname = Tabschema = Username = Colpat = NULL; Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL; Options = Quoted = Maxerr = Maxres = Memory = 0; Scrollable = Xsrc = false; @@ -233,11 +233,18 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) Read_Only = true; + Wrapname = GetStringCatInfo(g, "Wrapper", NULL); 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); + + 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); @@ -325,6 +332,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) if (tdp) { Ops.Driver = tdp->Driver; Ops.Url = tdp->Url; + WrapName = tdp->Wrapname; TableName = tdp->Tabname; Schema = tdp->Tabschema; Ops.User = tdp->Username; @@ -341,6 +349,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) Memory = tdp->Memory; Ops.Scrollable = tdp->Scrollable; } else { + WrapName = NULL; TableName = NULL; Schema = NULL; Ops.Driver = NULL; @@ -386,6 +395,7 @@ TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp) { Jcp = tdbp->Jcp; // is that right ? Cnp = tdbp->Cnp; + WrapName = tdbp->WrapName; TableName = tdbp->TableName; Schema = tdbp->Schema; Ops = tdbp->Ops; @@ -512,9 +522,10 @@ bool TDBJDBC::MakeSQL(PGLOBAL g, bool cnt) if (Catalog && *Catalog) catp = Catalog; - if (tablep->GetSchema()) - schmp = (char*)tablep->GetSchema(); - else if (Schema && *Schema) + //if (tablep->GetSchema()) + // schmp = (char*)tablep->GetSchema(); + //else + if (Schema && *Schema) schmp = Schema; if (catp) { @@ -596,9 +607,10 @@ bool TDBJDBC::MakeInsert(PGLOBAL g) if (catp) len += strlen(catp) + 1; - if (tablep->GetSchema()) - schmp = (char*)tablep->GetSchema(); - else if (Schema && *Schema) + //if (tablep->GetSchema()) + // schmp = (char*)tablep->GetSchema(); + //else + if (Schema && *Schema) schmp = Schema; if (schmp) @@ -1788,11 +1800,19 @@ 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..7244ebd3832 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); @@ -53,11 +54,13 @@ protected: PSZ Driver; /* JDBC driver */ PSZ Url; /* JDBC driver URL */ PSZ Tabname; /* External table name */ + PSZ Wrapname; /* Java wrapper name */ PSZ Tabschema; /* External table schema */ PSZ Username; /* User connect name */ 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 */ @@ -131,6 +134,7 @@ protected: JDBCCOL *Cnp; // Points to count(*) column JDBCPARM Ops; // Additional parameters PSTRG Query; // Constructed SQL query + char *WrapName; // Points to Java wrapper name char *TableName; // Points to JDBC table name char *Schema; // Points to JDBC table Schema char *User; // User connect info @@ -317,14 +321,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..f3ffc99ac15 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))) @@ -452,9 +458,14 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt) if (Catalog && *Catalog) catp = Catalog; - if (tablep->GetSchema()) - schmp = (char*)tablep->GetSchema(); - else if (Schema && *Schema) + // Following lines are commented because of MSDEV-10520 + // Indeed the schema in the tablep is the local table database and + // is normally not related to the remote table database. + // TODO: Try to remember why this was done and if it was useful in some case. + //if (tablep->GetSchema()) + // schmp = (char*)tablep->GetSchema(); + //else + if (Schema && *Schema) schmp = Schema; if (catp) { @@ -535,9 +546,10 @@ bool TDBODBC::MakeInsert(PGLOBAL g) if (catp) len += strlen(catp) + 1; - if (tablep->GetSchema()) - schmp = (char*)tablep->GetSchema(); - else if (Schema && *Schema) + //if (tablep->GetSchema()) + // schmp = (char*)tablep->GetSchema(); + //else + if (Schema && *Schema) schmp = Schema; if (schmp) @@ -681,7 +693,7 @@ bool TDBODBC::MakeCommand(PGLOBAL g) } else { sprintf(g->Message, "Cannot use this %s command", (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); - return NULL; + return false; } // endif p Query = new(g) STRING(g, 0, stmt); @@ -1768,6 +1780,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 +1793,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 diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 69aa7e2c20e..56312630278 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -1198,7 +1198,7 @@ bool XINDEX::MapInit(PGLOBAL g) const char *ftype; BYTE *mbase; char fn[_MAX_PATH]; - int *nv, k, n, id = -1; + int *nv, nv0, k, n, id = -1; bool estim; PCOL colp; PXCOL prev = NULL, kcp = NULL; @@ -1288,25 +1288,26 @@ bool XINDEX::MapInit(PGLOBAL g) if (nv[0] >= MAX_INDX) { // New index format Srtd = nv[7] != 0; - nv[0] -= MAX_INDX; + nv0 = nv[0] - MAX_INDX; mbase += NZ * sizeof(int); } else { Srtd = false; mbase += (NZ - 1) * sizeof(int); + nv0 = nv[0]; } // endif nv if (trace) htrc("nv=%d %d %d %d %d %d %d %d\n", - nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd); + nv0, nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd); // The test on ID was suppressed because MariaDB can change an index ID // when other indexes are added or deleted - if (/*nv[0] != ID ||*/ nv[1] != Nk) { + if (/*nv0 != ID ||*/ nv[1] != Nk) { // Not this index sprintf(g->Message, MSG(BAD_INDEX_FILE), fn); if (trace) - htrc("nv[0]=%d ID=%d nv[1]=%d Nk=%d\n", nv[0], ID, nv[1], Nk); + htrc("nv0=%d ID=%d nv[1]=%d Nk=%d\n", nv0, ID, nv[1], Nk); goto err; } // endif nv |