private void testPreparedStatementMetaData(Connection conn) throws SQLException { PreparedStatement prep = conn.prepareStatement("select * from table(x int = ?, name varchar = ?)"); ResultSetMetaData meta = prep.getMetaData(); assertEquals(2, meta.getColumnCount()); assertEquals("INTEGER", meta.getColumnTypeName(1)); assertEquals("VARCHAR", meta.getColumnTypeName(2)); prep = conn.prepareStatement("call 1"); meta = prep.getMetaData(); assertEquals(1, meta.getColumnCount()); assertEquals("INTEGER", meta.getColumnTypeName(1)); }
private void testGetMoreResults(Connection conn) throws SQLException { Statement stat = conn.createStatement(); PreparedStatement prep; ResultSet rs; stat.execute("CREATE TABLE TEST(ID INT)"); stat.execute("INSERT INTO TEST VALUES(1)"); prep = conn.prepareStatement("SELECT * FROM TEST"); // just to check if it doesn't throw an exception - it may be null prep.getMetaData(); assertTrue(prep.execute()); rs = prep.getResultSet(); assertFalse(prep.getMoreResults()); assertEquals(-1, prep.getUpdateCount()); // supposed to be closed now assertThrows(ErrorCode.OBJECT_CLOSED, rs).next(); assertEquals(-1, prep.getUpdateCount()); prep = conn.prepareStatement("UPDATE TEST SET ID = 2"); assertFalse(prep.execute()); assertEquals(1, prep.getUpdateCount()); assertFalse(prep.getMoreResults(Statement.CLOSE_CURRENT_RESULT)); assertEquals(-1, prep.getUpdateCount()); // supposed to be closed now assertThrows(ErrorCode.OBJECT_CLOSED, rs).next(); assertEquals(-1, prep.getUpdateCount()); prep = conn.prepareStatement("DELETE FROM TEST"); prep.executeUpdate(); assertFalse(prep.getMoreResults()); assertEquals(-1, prep.getUpdateCount()); }
/** * PDI-11363. when using getLookup calls there is no need to make attempt to retrieve row set * metadata for every call. That may bring performance penalty depends on jdbc driver * implementation. For some drivers that penalty can be huge (postgres). * * <p>During the execution calling getLookup() method we changing usually only lookup where clause * which will not impact return row structure. * * @throws KettleDatabaseException * @throws SQLException */ @Test public void testGetLookupMetaCalls() throws KettleDatabaseException, SQLException { DatabaseMeta meta = Mockito.mock(DatabaseMeta.class); Mockito.when(meta.getQuotedSchemaTableCombination(Mockito.anyString(), Mockito.anyString())) .thenReturn("a"); Mockito.when(meta.quoteField(Mockito.anyString())).thenReturn("a"); PreparedStatement ps = Mockito.mock(PreparedStatement.class); ResultSet rs = Mockito.mock(ResultSet.class); Mockito.when(ps.executeQuery()).thenReturn(rs); ResultSetMetaData rmeta = Mockito.mock(ResultSetMetaData.class); Mockito.when(rs.getMetaData()).thenReturn(rmeta); Mockito.when(rmeta.getColumnCount()).thenReturn(0); Mockito.when(ps.getMetaData()).thenReturn(rmeta); Database db = new Database(log, meta); Connection conn = Mockito.mock(Connection.class); Mockito.when(conn.prepareStatement(Mockito.anyString())).thenReturn(ps); db.setConnection(conn); String[] name = new String[] {"a"}; db.setLookup("a", name, name, name, name, "a"); for (int i = 0; i < 10; i++) { db.getLookup(); } Mockito.verify(rmeta, Mockito.times(1)).getColumnCount(); }
public ResultSetMetaData getMetaData() throws SQLException { try { return wrapped.getMetaData(); } catch (SQLException e) { throw new UcanaccessSQLException(e); } }
public ResultSetMetaData getMetaData() throws SQLException { String methodCall = "getMetaData()"; try { return (ResultSetMetaData) reportReturn(methodCall, realPreparedStatement.getMetaData()); } catch (SQLException s) { reportException(methodCall, s); throw s; } }
public ResultSetMetaData getMetaData() throws SQLException { checkOpen(); try { return _stmt.getMetaData(); } catch (SQLException e) { handleException(e); return null; } }
public ResultSetMetaData getMetaData() throws SQLException { Profiler profiler = _profilerPoint.start(); try { return _preparedStatement.getMetaData(); } finally { profiler.finish(); } }
public void sqlToBean(String tableName) { // 创建连接 Connection con = null; // 查要生成实体类的表 String sql = "select * from " + tableName; PreparedStatement pStemt = null; try { try { Class.forName(DRIVER); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } con = DriverManager.getConnection(allUrl, name, pass); pStemt = con.prepareStatement(sql); ResultSetMetaData rsmd = pStemt.getMetaData(); int size = rsmd.getColumnCount(); // 统计列 colnames = new String[size]; colTypes = new String[size]; colSizes = new int[size]; for (int i = 0; i < size; i++) { colnames[i] = rsmd.getColumnName(i + 1); colTypes[i] = rsmd.getColumnTypeName(i + 1); if (colTypes[i].equalsIgnoreCase("datetime")) isUtil = true; if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")) isSql = true; colSizes[i] = rsmd.getColumnDisplaySize(i + 1); } String content = parse(colnames, colTypes, colSizes, tableName); try { File directory = new File(""); String outputPath = directory.getAbsolutePath() + "/src/" + this.packageOutPath.replace(".", "/") + "/" + initcap(tableName) + ".java"; FileWriter fw = new FileWriter(outputPath); PrintWriter pw = new PrintWriter(fw); pw.println(content); pw.flush(); pw.close(); } catch (IOException e) { e.printStackTrace(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } }
/** * Tries to execute a method on a logical statement when the underlying physical statement has * been closed without the logical connection knowing. * * @throws SQLException if something goes wrong... */ public void testClosedUnderlyingStatement() throws SQLException { // Initial setup. final String sql = "values 19"; java.sql.PreparedStatement ps = prepareStatement(sql); JDBCStatementCache cache = new JDBCStatementCache(10); insertStatementIntoCache(cache, ps, sql); LogicalStatementEntity logic = createLogicalStatementEntity(sql, false, cache); assertSame(ps, logic.getPhysPs()); assertFalse(logic.isLogicalEntityClosed()); java.sql.PreparedStatement logicalPs = (java.sql.PreparedStatement) logic; assertNotNull(logicalPs.getMetaData()); ps.close(); try { logicalPs.getMetaData(); fail("Getting meta data on a closed connection should fail"); } catch (SQLException sqle) { assertSQLState("XJ012", sqle); } logicalPs.close(); }
/** Returns a table's columns */ public static List<Column> getColumns(DatabaseMetaData metadata, String tableName) throws Exception { List<Column> columns = new ArrayList<Column>(); PreparedStatement stmt = metadata.getConnection().prepareStatement("SELECT * FROM " + tableName); ResultSetMetaData rsmeta = stmt.getMetaData(); for (int i = 1, ii = rsmeta.getColumnCount(); i <= ii; ++i) { columns.add(new Column(rsmeta, i)); } stmt.close(); return columns; }
@Test public void metaData() throws SQLException { PreparedStatement prep = conn.prepareStatement("select ? as col1, ? as col2, ? as delta;"); ResultSetMetaData meta = prep.getMetaData(); assertEquals(3, meta.getColumnCount()); assertEquals("col1", meta.getColumnName(1)); assertEquals("col2", meta.getColumnName(2)); assertEquals("delta", meta.getColumnName(3)); /*assertEquals(Types.INTEGER, meta.getColumnType(1)); assertEquals(Types.INTEGER, meta.getColumnType(2)); assertEquals(Types.INTEGER, meta.getColumnType(3));*/ meta = prep.executeQuery().getMetaData(); assertEquals(3, meta.getColumnCount()); prep.close(); }
public Util() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.2:3306/test", "root", "123456789"); String strsql = "select * from " + tablename; try { PreparedStatement pstmt = conn.prepareStatement(strsql); ResultSetMetaData rsmd = pstmt.getMetaData(); int size = rsmd.getColumnCount(); // 共有多少列 colnames = new String[size]; colTypes = new String[size]; colSizes = new int[size]; for (int i = 0; i < rsmd.getColumnCount(); i++) { colnames[i] = rsmd.getColumnName(i + 1); colTypes[i] = rsmd.getColumnTypeName(i + 1); if (colTypes[i].equalsIgnoreCase("datetime")) { f_util = true; } if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")) { f_sql = true; } colSizes[i] = rsmd.getColumnDisplaySize(i + 1); } String content = parse(colnames, colTypes, colSizes); try { FileWriter fw = new FileWriter(initcap(tablename) + ".java"); PrintWriter pw = new PrintWriter(fw); pw.println(content); pw.flush(); pw.close(); } catch (IOException e) { e.printStackTrace(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
private void checkPrepareBindExecuteFetch(Connection connection) throws SQLException { final String sql = "select cast(? as integer) * 3 as c, 'x' as x\n" + "from (values (1, 'a'))"; final PreparedStatement ps = connection.prepareStatement(sql); final ResultSetMetaData metaData = ps.getMetaData(); assertEquals(2, metaData.getColumnCount()); assertEquals("C", metaData.getColumnName(1)); assertEquals("X", metaData.getColumnName(2)); try { final ResultSet resultSet = ps.executeQuery(); fail("expected error, got " + resultSet); } catch (SQLException e) { assertThat(e.getMessage(), equalTo("exception while executing query: unbound parameter")); } final ParameterMetaData parameterMetaData = ps.getParameterMetaData(); assertThat(parameterMetaData.getParameterCount(), equalTo(1)); ps.setInt(1, 10); final ResultSet resultSet = ps.executeQuery(); assertTrue(resultSet.next()); assertThat(resultSet.getInt(1), equalTo(30)); assertFalse(resultSet.next()); resultSet.close(); ps.setInt(1, 20); final ResultSet resultSet2 = ps.executeQuery(); assertFalse(resultSet2.isClosed()); assertTrue(resultSet2.next()); assertThat(resultSet2.getInt(1), equalTo(60)); assertThat(resultSet2.wasNull(), is(false)); assertFalse(resultSet2.next()); resultSet2.close(); ps.setObject(1, null); final ResultSet resultSet3 = ps.executeQuery(); assertTrue(resultSet3.next()); assertThat(resultSet3.getInt(1), equalTo(0)); assertThat(resultSet3.wasNull(), is(true)); assertFalse(resultSet3.next()); resultSet3.close(); ps.close(); connection.close(); }
/** * Test that for every PreparedStatement passed into lookup signature we do reset and re-create * row meta. * * @throws SQLException * @throws KettleDatabaseException */ @Test public void testGetLookupCallPSpassed() throws SQLException, KettleDatabaseException { DatabaseMeta meta = Mockito.mock(DatabaseMeta.class); PreparedStatement ps = Mockito.mock(PreparedStatement.class); ResultSet rs = Mockito.mock(ResultSet.class); Mockito.when(ps.executeQuery()).thenReturn(rs); ResultSetMetaData rmeta = Mockito.mock(ResultSetMetaData.class); Mockito.when(rs.getMetaData()).thenReturn(rmeta); Mockito.when(rmeta.getColumnCount()).thenReturn(0); Mockito.when(ps.getMetaData()).thenReturn(rmeta); Database db = new Database(log, meta); db.getLookup(ps); Mockito.verify(rmeta, Mockito.times(1)).getColumnCount(); }
public ResultSetMetaData getMetaData() throws SQLException { return statement.getMetaData(); }
@Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { try { Profiles.Profile profile; if (args[0] instanceof CArray) { Map<String, String> data = new HashMap<String, String>(); for (String key : ((CArray) args[0]).keySet()) { data.put(key, ((CArray) args[0]).get(key).val()); } profile = Profiles.getProfile(data); } else { Profiles profiles = environment.getEnv(GlobalEnv.class).getSQLProfiles(); profile = profiles.getProfileById(args[0].val()); } String query = args[1].val(); Construct[] params = new Construct[args.length - 2]; for (int i = 2; i < args.length; i++) { int index = i - 2; params[index] = args[i]; } // Parameters are now all parsed into java objects. Connection conn = DriverManager.getConnection(profile.getConnectionString()); PreparedStatement ps = null; try { ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); for (int i = 0; i < params.length; i++) { int type = ps.getParameterMetaData().getParameterType(i + 1); if (params[i] == null) { if (ps.getParameterMetaData().isNullable(i + 1) == ParameterMetaData.parameterNoNulls) { throw new ConfigRuntimeException( "Parameter " + (i + 1) + " cannot be set to null. Check your parameters and try again.", ExceptionType.SQLException, t); } else { ps.setNull(i + 1, type); continue; } } try { if (params[i] instanceof CInt) { ps.setLong(i + 1, Static.getInt(params[i], t)); } else if (params[i] instanceof CDouble) { ps.setDouble(i + 1, (Double) Static.getDouble(params[i], t)); } else if (params[i] instanceof CString) { ps.setString(i + 1, (String) params[i].val()); } else if (params[i] instanceof CByteArray) { ps.setBytes(i + 1, ((CByteArray) params[i]).asByteArrayCopy()); } else if (params[i] instanceof CBoolean) { ps.setBoolean(i + 1, Static.getBoolean(params[i])); } else { throw new ConfigRuntimeException( "The type " + params[i].getClass().getSimpleName() + " of parameter " + (i + 1) + " is not supported.", ExceptionType.CastException, t); } } catch (ClassCastException ex) { throw new ConfigRuntimeException( "Could not cast parameter " + (i + 1) + " to " + ps.getParameterMetaData().getParameterTypeName(i + 1) + " from " + params[i].getClass().getSimpleName() + ".", ExceptionType.CastException, t, ex); } } boolean isResultSet = ps.execute(); if (isResultSet) { // Result set CArray ret = new CArray(t); ResultSetMetaData md = ps.getMetaData(); ResultSet rs = ps.getResultSet(); while (rs.next()) { CArray row = new CArray(t); for (int i = 1; i <= md.getColumnCount(); i++) { Construct value; int columnType = md.getColumnType(i); if (columnType == Types.INTEGER || columnType == Types.TINYINT || columnType == Types.SMALLINT || columnType == Types.BIGINT) { value = new CInt(rs.getLong(i), t); } else if (columnType == Types.FLOAT || columnType == Types.DOUBLE || columnType == Types.REAL || columnType == Types.DECIMAL || columnType == Types.NUMERIC) { value = new CDouble(rs.getDouble(i), t); } else if (columnType == Types.VARCHAR || columnType == Types.CHAR || columnType == Types.LONGVARCHAR) { value = new CString(rs.getString(i), t); } else if (columnType == Types.BLOB || columnType == Types.BINARY || columnType == Types.VARBINARY || columnType == Types.LONGVARBINARY) { value = CByteArray.wrap(rs.getBytes(i), t); } else if (columnType == Types.DATE || columnType == Types.TIME || columnType == Types.TIMESTAMP) { if (md.getColumnTypeName(i).equals("YEAR")) { value = new CInt(rs.getLong(i), t); } else { value = new CInt(rs.getTimestamp(i).getTime(), t); } } else if (columnType == Types.BOOLEAN || columnType == Types.BIT) { value = new CBoolean(rs.getBoolean(i), t); } else { throw new ConfigRuntimeException( "SQL returned a unhandled column type " + md.getColumnTypeName(i) + " for column " + md.getColumnName(i) + ".", ExceptionType.CastException, t); } row.set(md.getColumnName(i), value, t); } ret.push(row); } return ret; } else { ResultSet rs = ps.getGeneratedKeys(); if (rs.next()) { // This was an insert or something that returned generated keys. So we return // that here. return new CInt(rs.getInt(1), t); } // Update count. Just return null. return new CNull(t); } } finally { if (ps != null) { ps.close(); } if (conn != null) { conn.close(); } } } catch (Profiles.InvalidProfileException ex) { throw new ConfigRuntimeException(ex.getMessage(), ExceptionType.SQLException, t, ex); } catch (SQLException ex) { throw new ConfigRuntimeException(ex.getMessage(), ExceptionType.SQLException, t, ex); } }
public String getColumnName(int column) throws SQLException { if (metaData == null) { metaData = preparedStatement.getMetaData(); } return metaData.getColumnName(column + 1); }
public int getColumnCount() throws SQLException { if (metaData == null) { metaData = preparedStatement.getMetaData(); } return metaData.getColumnCount(); }
public ResultSetMetaData getMetaData() throws SQLException { this.assertPs(); return ps.getMetaData(); }
@Override public ResultSetMetaData getMetaData() throws SQLException { return stmt.getMetaData(); }
/** * @param args * @return */ @JRubyMethod(optional = 1, rest = true) public IRubyObject execute_reader(IRubyObject[] args) { Ruby runtime = getRuntime(); Connection connection_instance = (Connection) api.getInstanceVariable(this, "@connection"); java.sql.Connection conn = connection_instance.getInternalConnection(); checkConnectionNotClosed(conn); RubyClass readerClass = Reader.createReaderClass(runtime, driver); boolean inferTypes = false; int columnCount = 0; PreparedStatement sqlStatement = null; ResultSet resultSet = null; ResultSetMetaData metaData; // instantiate a new reader Reader reader = (Reader) readerClass.newInstance( runtime.getCurrentContext(), new IRubyObject[] {}, Block.NULL_BLOCK); // execute the query try { String doSqlText = api.convertToRubyString(api.getInstanceVariable(this, "@text")).getUnicodeValue(); String sqlText = prepareSqlTextForPs(doSqlText, args); sqlStatement = conn.prepareStatement( sqlText, driver.supportsJdbcScrollableResultSets() ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); prepareStatementFromArgs(sqlText, sqlStatement, args); long startTime = System.currentTimeMillis(); resultSet = sqlStatement.executeQuery(); long endTime = System.currentTimeMillis(); debug(driver.statementToString(sqlStatement), Long.valueOf(endTime - startTime)); metaData = resultSet.getMetaData(); columnCount = metaData.getColumnCount(); // reduce columnCount by 1 if RAW_RNUM_ is present as last column // (generated by DataMapper Oracle adapter to simulate LIMIT and OFFSET) if (metaData.getColumnName(columnCount).equals("RAW_RNUM_")) columnCount--; // pass the response to the Reader reader.resultSet = resultSet; // pass reference to the Statement object and close it later in the Reader reader.statement = sqlStatement; // save the field count in Reader reader.fieldCount = columnCount; // get the field types List<String> fieldNames = new ArrayList<String>(columnCount); // If no types are passed in, infer them if (fieldTypes == null || fieldTypes.isEmpty()) { fieldTypes = new ArrayList<RubyType>(); inferTypes = true; } else if (fieldTypes.size() != columnCount) { // Wrong number of fields passed to set_types. Close the reader // and raise an error. api.callMethod(reader, "close"); throw runtime.newArgumentError( String.format( "Field-count mismatch. Expected %1$d fields, but the query yielded %2$d", fieldTypes.size(), columnCount)); } // for each field for (int i = 0; i < columnCount; i++) { int col = i + 1; // downcase the field name fieldNames.add(metaData.getColumnLabel(col)); if (inferTypes) { // infer the type if no types passed fieldTypes.add( driver.jdbcTypeToRubyType( metaData.getColumnType(col), metaData.getPrecision(col), metaData.getScale(col))); } } // set the reader field names and types (guessed or otherwise) reader.fieldNames = fieldNames; reader.fieldTypes = fieldTypes; } catch (SQLException sqle) { // XXX sqlite3 jdbc driver happily throws an exception if the result set is empty :P // this sets up a minimal empty reader if (sqle.getMessage().equals("query does not return results")) { // pass the response to the Reader reader.resultSet = resultSet; // pass reference to the Statement object and close it later in the Reader reader.statement = sqlStatement; // get the field types List<String> fieldNames = new ArrayList<String>(); // for each field try { metaData = sqlStatement.getMetaData(); for (int i = 0; i < columnCount; i++) { int col = i + 1; // downcase the field name fieldNames.add(metaData.getColumnLabel(col)); // infer the type if no types passed fieldTypes.add( driver.jdbcTypeToRubyType( metaData.getColumnType(col), metaData.getPrecision(col), metaData.getScale(col))); } } catch (SQLException e) { e.printStackTrace(); } // set the reader field names and types (guessed or otherwise) reader.fieldNames = fieldNames; return reader; } api.callMethod(reader, "close"); throw Errors.newQueryError(runtime, driver, sqle, sqlStatement); } // return the reader return reader; }
public ResultSetMetaData getMetaData() throws SQLException { return delegate.getMetaData(); }
private void process() throws IOException { int x; if (initDone) { x = dataInRaw.read(); if (x < 0) { stop = true; return; } } else { x = 0; } int len = dataInRaw.readInt(); len -= 4; byte[] data = DataUtils.newBytes(len); dataInRaw.readFully(data, 0, len); dataIn = new DataInputStream(new ByteArrayInputStream(data, 0, len)); switchBlock: switch (x) { case 0: server.trace("Init"); int version = readInt(); if (version == 80877102) { server.trace("CancelRequest (not supported)"); server.trace(" pid: " + readInt()); server.trace(" key: " + readInt()); } else if (version == 80877103) { server.trace("SSLRequest"); out.write('N'); } else { server.trace("StartupMessage"); server.trace( " version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")"); while (true) { String param = readString(); if (param.length() == 0) { break; } String value = readString(); if ("user".equals(param)) { this.userName = value; } else if ("database".equals(param)) { this.databaseName = value; } else if ("client_encoding".equals(param)) { // UTF8 clientEncoding = value; } else if ("DateStyle".equals(param)) { dateStyle = value; } // extra_float_digits 2 // geqo on (Genetic Query Optimization) server.trace(" param " + param + "=" + value); } sendAuthenticationCleartextPassword(); initDone = true; } break; case 'p': { server.trace("PasswordMessage"); String password = readString(); try { // Properties info = new Properties(); // info.put("MODE", "PostgreSQL"); // info.put("USER", userName); // info.put("PASSWORD", password); // String url = "jdbc:lealone:" + databaseName; // ConnectionInfo ci = new ConnectionInfo(url, info); // String baseDir = server.getBaseDir(); // if (baseDir == null) { // baseDir = SysProperties.getBaseDir(); // } // if (baseDir != null) { // ci.setBaseDir(baseDir); // } // if (server.getIfExists()) { // ci.setProperty("IFEXISTS", "TRUE"); // } // conn = new JdbcConnection(ci, false); conn = createJdbcConnection(password); // can not do this because when called inside // DriverManager.getConnection, a deadlock occurs // conn = DriverManager.getConnection(url, userName, password); initDb(); sendAuthenticationOk(); } catch (Exception e) { e.printStackTrace(); stop = true; } break; } case 'P': { server.trace("Parse"); Prepared p = new Prepared(); p.name = readString(); p.sql = getSQL(readString()); int count = readShort(); p.paramType = new int[count]; for (int i = 0; i < count; i++) { int type = readInt(); server.checkType(type); p.paramType[i] = type; } try { p.prep = (JdbcPreparedStatement) conn.prepareStatement(p.sql); prepared.put(p.name, p); sendParseComplete(); } catch (Exception e) { sendErrorResponse(e); } break; } case 'B': { server.trace("Bind"); Portal portal = new Portal(); portal.name = readString(); String prepName = readString(); Prepared prep = prepared.get(prepName); if (prep == null) { sendErrorResponse("Prepared not found"); break; } portal.prep = prep; portals.put(portal.name, portal); int formatCodeCount = readShort(); int[] formatCodes = new int[formatCodeCount]; for (int i = 0; i < formatCodeCount; i++) { formatCodes[i] = readShort(); } int paramCount = readShort(); for (int i = 0; i < paramCount; i++) { int paramLen = readInt(); byte[] d2 = DataUtils.newBytes(paramLen); readFully(d2); try { setParameter(prep.prep, i, d2, formatCodes); } catch (Exception e) { sendErrorResponse(e); break switchBlock; } } int resultCodeCount = readShort(); portal.resultColumnFormat = new int[resultCodeCount]; for (int i = 0; i < resultCodeCount; i++) { portal.resultColumnFormat[i] = readShort(); } sendBindComplete(); break; } case 'C': { char type = (char) readByte(); String name = readString(); server.trace("Close"); if (type == 'S') { Prepared p = prepared.remove(name); if (p != null) { JdbcUtils.closeSilently(p.prep); } } else if (type == 'P') { portals.remove(name); } else { server.trace("expected S or P, got " + type); sendErrorResponse("expected S or P"); break; } sendCloseComplete(); break; } case 'D': { char type = (char) readByte(); String name = readString(); server.trace("Describe"); if (type == 'S') { Prepared p = prepared.get(name); if (p == null) { sendErrorResponse("Prepared not found: " + name); } else { sendParameterDescription(p); } } else if (type == 'P') { Portal p = portals.get(name); if (p == null) { sendErrorResponse("Portal not found: " + name); } else { PreparedStatement prep = p.prep.prep; try { ResultSetMetaData meta = prep.getMetaData(); sendRowDescription(meta); } catch (Exception e) { sendErrorResponse(e); } } } else { server.trace("expected S or P, got " + type); sendErrorResponse("expected S or P"); } break; } case 'E': { String name = readString(); server.trace("Execute"); Portal p = portals.get(name); if (p == null) { sendErrorResponse("Portal not found: " + name); break; } int maxRows = readShort(); Prepared prepared = p.prep; JdbcPreparedStatement prep = prepared.prep; server.trace(prepared.sql); try { prep.setMaxRows(maxRows); boolean result = prep.execute(); if (result) { try { ResultSet rs = prep.getResultSet(); ResultSetMetaData meta = rs.getMetaData(); sendRowDescription(meta); while (rs.next()) { sendDataRow(rs); } sendCommandComplete(prep, 0); } catch (Exception e) { sendErrorResponse(e); } } else { sendCommandComplete(prep, prep.getUpdateCount()); } } catch (Exception e) { sendErrorResponse(e); } break; } case 'S': { server.trace("Sync"); sendReadyForQuery(); break; } case 'Q': { server.trace("Query"); String query = readString(); ScriptReader reader = new ScriptReader(new StringReader(query)); while (true) { JdbcStatement stat = null; try { String s = reader.readStatement(); if (s == null) { break; } s = getSQL(s); stat = (JdbcStatement) conn.createStatement(); boolean result = stat.execute(s); if (result) { ResultSet rs = stat.getResultSet(); ResultSetMetaData meta = rs.getMetaData(); try { sendRowDescription(meta); while (rs.next()) { sendDataRow(rs); } sendCommandComplete(stat, 0); } catch (Exception e) { sendErrorResponse(e); break; } } else { sendCommandComplete(stat, stat.getUpdateCount()); } } catch (SQLException e) { sendErrorResponse(e); break; } finally { JdbcUtils.closeSilently(stat); } } sendReadyForQuery(); break; } case 'X': { server.trace("Terminate"); close(); break; } default: server.trace("Unsupported: " + x + " (" + (char) x + ")"); break; } }
/** * @param ps the PreparedStatement for which the parameter should be set * @param recv * @param arg a parameter value * @param idx the index of the parameter * @throws java.sql.SQLException */ private static void setPreparedStatementParam( PreparedStatement ps, IRubyObject recv, IRubyObject arg, int idx) throws SQLException { Integer jdbcTypeId = null; try { jdbcTypeId = ps.getMetaData().getColumnType(idx); } catch (Exception ex) { } String rubyTypeName = arg.getType().getName(); if ("Fixnum".equals(rubyTypeName)) { ps.setInt(idx, Integer.parseInt(arg.toString())); } else if ("Bignum".equals(rubyTypeName)) { ps.setLong(idx, ((RubyBignum) arg).getLongValue()); } else if ("Float".equals(rubyTypeName)) { ps.setDouble(idx, RubyNumeric.num2dbl(arg)); } else if ("BigDecimal".equals(rubyTypeName)) { ps.setBigDecimal(idx, ((RubyBigDecimal) arg).getValue()); } else if ("NilClass".equals(rubyTypeName)) { // XXX In fact this should looks like ps.setNull(idx, Types.YYY); // where YYY is a JDBC type of column i.e. Types.VARCHAR // but this code works for MySQL :) ps.setNull(idx, Types.NULL); } else if ("TrueClass".equals(rubyTypeName) || "FalseClass".equals(rubyTypeName)) { ps.setBoolean(idx, arg.toString().equals("true")); } else if ("Class".equals(rubyTypeName)) { ps.setString(idx, arg.toString()); } else if ("Extlib::ByteArray".equals(rubyTypeName)) { ps.setBytes(idx, ((RubyString) arg).getBytes()); // TODO: add support for ps.setBlob(); } else if ("Date".equals(rubyTypeName)) { ps.setDate(idx, java.sql.Date.valueOf(arg.toString())); } else if ("Time".equals(rubyTypeName)) { RubyTime rubyTime = (RubyTime) arg; java.util.Date date = rubyTime.getJavaDate(); GregorianCalendar cal = new GregorianCalendar(); cal.setTime(date); cal.setTimeZone( TimeZone.getTimeZone("UTC")); // XXX works only if driver suports Calendars in PS java.sql.Timestamp ts; if (driver.supportsCalendarsInJDBCPreparedStatement() == true) { ts = new java.sql.Timestamp(cal.getTime().getTime()); ts.setNanos(cal.get(GregorianCalendar.MILLISECOND) * 100000); } else { // XXX ugly workaround for MySQL and Hsqldb ts = new Timestamp( cal.get(GregorianCalendar.YEAR) - 1900, cal.get(GregorianCalendar.MONTH), cal.get(GregorianCalendar.DAY_OF_MONTH), cal.get(GregorianCalendar.HOUR_OF_DAY), cal.get(GregorianCalendar.MINUTE), cal.get(GregorianCalendar.SECOND), cal.get(GregorianCalendar.MILLISECOND) * 100000); } ps.setTimestamp(idx, ts, cal); } else if ("DateTime".equals(rubyTypeName)) { ps.setTimestamp( idx, java.sql.Timestamp.valueOf( arg.toString().replace('T', ' ').replaceFirst("[-+]..:..$", ""))); } else if (arg.toString().indexOf("-") != -1 && arg.toString().indexOf(":") != -1) { // TODO: improve the above string pattern checking // Handle date patterns in strings java.util.Date parsedDate; try { parsedDate = FORMAT.parse(arg.asJavaString().replace('T', ' ')); java.sql.Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime()); ps.setTimestamp(idx, timestamp); } catch (ParseException ex) { ps.setString(idx, api.convertToRubyString(arg).getUnicodeValue()); } } else if (arg.toString().indexOf(":") != -1 && arg.toString().length() == 8) { // Handle time patterns in strings ps.setTime(idx, java.sql.Time.valueOf(arg.asJavaString())); } else { if (jdbcTypeId == null) { ps.setString(idx, api.convertToRubyString(arg).getUnicodeValue()); } else { // TODO: Here comes conversions like '.execute_reader("2")' // It definitly needs to be refactored... try { if (jdbcTypeId == Types.VARCHAR) { ps.setString(idx, api.convertToRubyString(arg).getUnicodeValue()); } else if (jdbcTypeId == Types.INTEGER) { ps.setObject(idx, Integer.valueOf(arg.toString()), jdbcTypeId); } else { // I'm not sure is it correct in 100% ps.setString(idx, api.convertToRubyString(arg).getUnicodeValue()); } } catch (NumberFormatException ex) { // i.e Integer.valueOf ps.setString(idx, api.convertToRubyString(arg).getUnicodeValue()); } } } }