package jeql.command.db.driver; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; import jeql.api.error.ExecutionException; import jeql.api.row.BasicRow; import jeql.api.row.Row; import jeql.api.row.RowSchema; import jeql.engine.ConfigurationException; public class JdbcRowMapper implements RowMapper { public RowSchema getSchema(ResultSet rs) throws SQLException { ResultSetMetaData rm = rs.getMetaData(); int ncols = rm.getColumnCount(); String[] names = new String[ncols]; Class[] types = new Class[ncols]; for (int i = 0; i < ncols; i++) { names[i] = rm.getColumnName(i+1); types[i] = mapColumnType(rm, i+1); if (types[i] == null) { throw new ExecutionException("SQL type " + rm.getColumnTypeName(i) + " is not currently handled"); } } RowSchema schema = new RowSchema(names, types); return schema; } public Row createRow(RowSchema schema, ResultSet rs) throws Exception { BasicRow row = new BasicRow(schema.size()); for (int i = 0; i < schema.size(); i++) { row.setValue(i, mapColumnValue(rs, i+1, schema.getType(i))); } return row; } /** * * @param rm * @param colIndex * @return null if the column type is not handled * @throws SQLException */ protected Class mapColumnType(ResultSetMetaData rsm, int columnIndex) throws SQLException { return mapJDBCColumnType(rsm.getColumnType(columnIndex)); } public static Class mapJDBCColumnType(int jdbcTypeCode) { switch (jdbcTypeCode) { case Types.TINYINT: case Types.INTEGER: case Types.SMALLINT: return Integer.class; case Types.BIGINT: case Types.NUMERIC: case Types.DECIMAL: case Types.FLOAT: case Types.DOUBLE: case Types.REAL: return Double.class; case Types.BIT: case Types.BOOLEAN: return Boolean.class; case Types.CHAR: case Types.VARCHAR: case Types.CLOB: //case Types.LONGNVARCHAR: //case Types.NVARCHAR: default: return String.class; } // return null; // signifies this type is not handled } protected Object mapColumnValue(ResultSet rs, int columnIndex, Class destType) throws Exception { if (destType == String.class) { return rs.getString(columnIndex); } if (destType == Integer.class) { return new Integer(rs.getInt(columnIndex)); } if (destType == Double.class) { return new Double(rs.getDouble(columnIndex)); } if (destType == Boolean.class) { return new Boolean(rs.getBoolean(columnIndex)); } throw new ConfigurationException("Unhandled SQL value mapping for class " + destType.getName()); } }