package marubinotto.h2.fulltext; import java.io.IOException; import java.io.Reader; import java.sql.Clob; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.List; import org.h2.command.Parser; import org.h2.engine.Session; import org.h2.expression.Comparison; import org.h2.expression.ConditionAndOr; import org.h2.expression.Expression; import org.h2.expression.ExpressionColumn; import org.h2.expression.ValueExpression; import org.h2.jdbc.JdbcConnection; import org.h2.message.DbException; import org.h2.util.IOUtils; import org.h2.util.New; import org.h2.util.StringUtils; import org.h2.value.DataType; class InternalUtils { public static SQLException throwException(String message) throws SQLException { throw new SQLException(message, "FULLTEXT"); } public static String getIndexPath(Connection conn) throws SQLException { Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery("CALL IFNULL(DATABASE_PATH(), 'MEM:' || DATABASE())"); rs.next(); String path = rs.getString(1); rs.close(); return path; } public static String toString(Object value, int type) throws SQLException { if (value == null) return ""; switch (type) { case Types.BIT: case DataType.TYPE_BOOLEAN: case Types.INTEGER: case Types.BIGINT: case Types.DECIMAL: case Types.DOUBLE: case Types.FLOAT: case Types.NUMERIC: case Types.REAL: case Types.SMALLINT: case Types.TINYINT: case Types.DATE: case Types.TIME: case Types.TIMESTAMP: case Types.LONGVARCHAR: case Types.CHAR: case Types.VARCHAR: return value.toString(); case Types.CLOB: try { if (value instanceof Clob) { value = ((Clob) value).getCharacterStream(); } return IOUtils.readStringAndClose((Reader)value, -1); } catch (IOException e) { throw DbException.toSQLException(e); } case Types.VARBINARY: case Types.LONGVARBINARY: case Types.BINARY: case Types.JAVA_OBJECT: case Types.OTHER: case Types.BLOB: case Types.STRUCT: case Types.REF: case Types.NULL: case Types.ARRAY: case DataType.TYPE_DATALINK: case Types.DISTINCT: throw throwException("Unsupported column data type: " + type); default: return ""; } } public static String quoteSQL(Object value, int type) throws SQLException { if (value == null) { return "NULL"; } switch (type) { case Types.BIT: case DataType.TYPE_BOOLEAN: case Types.INTEGER: case Types.BIGINT: case Types.DECIMAL: case Types.DOUBLE: case Types.FLOAT: case Types.NUMERIC: case Types.REAL: case Types.SMALLINT: case Types.TINYINT: return value.toString(); case Types.DATE: case Types.TIME: case Types.TIMESTAMP: case Types.LONGVARCHAR: case Types.CHAR: case Types.VARCHAR: return quoteString(value.toString()); case Types.VARBINARY: case Types.LONGVARBINARY: case Types.BINARY: return "'" + StringUtils.convertBytesToString((byte[]) value) + "'"; case Types.CLOB: case Types.JAVA_OBJECT: case Types.OTHER: case Types.BLOB: case Types.STRUCT: case Types.REF: case Types.NULL: case Types.ARRAY: case DataType.TYPE_DATALINK: case Types.DISTINCT: throw throwException("Unsupported key data type: " + type); default: return ""; } } public static String quoteString(String value) { if (value.indexOf('\'') < 0) { return "'" + value + "'"; } int len = value.length(); StringBuilder buff = new StringBuilder(len + 2); buff.append('\''); for (int i = 0; i < len; i++) { char ch = value.charAt(i); if (ch == '\'') { buff.append(ch); } buff.append(ch); } buff.append('\''); return buff.toString(); } public static Object[][] parseConditionSqlToColumnsAndValues(String conditionSql, JdbcConnection conn) { List<String> columns = New.arrayList(); List<String> values = New.arrayList(); Expression expr = new Parser((Session)conn.getSession()).parseExpression(conditionSql); addColumnAndValue(expr, columns, values); return new Object[][] { columns.toArray(new Object[columns.size()]), values.toArray(new Object[columns.size()]) }; } private static void addColumnAndValue(Expression expr, List<String> columns, List<String> values) { if (expr instanceof ConditionAndOr) { ConditionAndOr and = (ConditionAndOr)expr; Expression left = and.getExpression(true); Expression right = and.getExpression(false); addColumnAndValue(left, columns, values); addColumnAndValue(right, columns, values); } else { Comparison comp = (Comparison)expr; ExpressionColumn ec = (ExpressionColumn)comp.getExpression(true); ValueExpression ev = (ValueExpression)comp.getExpression(false); String columnName = ec.getColumnName(); columns.add(columnName); if (ev == null) { values.add(null); } else { values.add(ev.getValue(null).getString()); } } } }