Java tutorial
/* * Copyright(C) 2011-2012 Alibaba Group Holding Limited * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Authors: * wentong <wentong@taobao.com> */ package com.taobao.tdhs.jdbc; import com.taobao.tdhs.client.TDHSClient; import com.taobao.tdhs.client.common.TDHSCommon; import com.taobao.tdhs.client.easy.Insert; import com.taobao.tdhs.client.easy.Query; import com.taobao.tdhs.client.easy.Where; import com.taobao.tdhs.client.exception.TDHSException; import com.taobao.tdhs.client.response.TDHSMySQLResultSetWrap; import com.taobao.tdhs.client.response.TDHSResponse; import com.taobao.tdhs.client.response.TDHSResponseEnum; import com.taobao.tdhs.client.response.TDHSResultSet; import com.taobao.tdhs.client.statement.BatchStatement; import com.taobao.tdhs.jdbc.exception.TDHSSQLException; import com.taobao.tdhs.jdbc.sqlparser.*; import com.taobao.tdhs.jdbc.util.ConvertUtil; import com.taobao.tdhs.jdbc.util.StringUtil; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.*; import java.util.*; /** * @author <a href="mailto:wentong@taobao.com"></a> * @since 12-3-8 ?9:12 */ public class TDHSStatement implements Statement { private Logger logger = LoggerFactory.getLogger(this.getClass()); private final Connection connection; private final TDHSClient client; private final String db; private boolean close = false; private ResultSet currentResultSet = null; private int updateCount = -1; private BatchStatement batchStatement = null; protected final Map<Integer, byte[]> byteParameters = new HashMap<Integer, byte[]>(); protected final static String BYTE_PARAMETER_PREFIX = "___________________"; public TDHSStatement(Connection connection, TDHSClient client, String db) { this.connection = connection; this.client = client; this.db = db; } public ResultSet executeQuery(String sql) throws SQLException { execute(sql); if (currentResultSet == null) { throw new TDHSSQLException("None ResultSet!", sql); } return currentResultSet; } private void doSelectOrCount(com.taobao.tdhs.client.statement.Statement s, ParseSQL parseSQL, String tableName, String dbName) throws SQLException { Query query = preprocessGet(s, parseSQL, tableName, dbName); List<Entry<String, String>> columns = parseSQL.getColumns(); if (columns == null || columns.isEmpty()) { throw new TDHSSQLException("no columns to select!", parseSQL.getSql()); } String[] field = new String[columns.size()]; String[] alias = new String[columns.size()]; int i = 0; for (Entry<String, String> e : columns) { String f = StringUtil.escapeField(e.getValue()); if (f == null) { throw new TDHSSQLException("error in field[" + e.getValue() + "]", parseSQL.getSql()); } field[i] = f; String a = StringUtil.escapeField(e.getKey()); if (a == null) { throw new TDHSSQLException("error in alias[" + e.getKey() + "]", parseSQL.getSql()); } alias[i++] = a; } if (field.length == 1 && field[0].equalsIgnoreCase("count(*)") && !columns.get(0).getValue().startsWith("`")) { TDHSResponse response = null; try { response = query.count(); } catch (TDHSException e) { throw new SQLException(e); } processResponse(response, alias, false, false); } else { query.select(field); TDHSResponse response = null; try { response = query.get(); } catch (TDHSException e) { throw new SQLException(e); } processResponse(response, alias, false, false); } } private Query preprocessGet(com.taobao.tdhs.client.statement.Statement s, ParseSQL parseSQL, String tableName, String dbName) throws TDHSSQLException { Query query = s.query().use(dbName).from(tableName); List<OperationStruct> operation = parseSQL.getListOperationStructs(); if (StringUtils.isNotBlank(parseSQL.getErrmsg())) { throw new TDHSSQLException(parseSQL.getErrmsg(), parseSQL.getSql()); } if (operation == null || operation.isEmpty()) { throw new TDHSSQLException("must have some where condition!", parseSQL.getSql()); } List<OperationStruct> keys = new ArrayList<OperationStruct>(2); HintStruct hint = parseSQL.getHint(); if (hint != null && StringUtils.isBlank(hint.getErrmsg()) && StringUtils.isNotBlank(hint.getIndexName())) { String index = hint.getIndexName(); List<String> listIndexColumns = hint.getListIndexColumns(); if (listIndexColumns == null || listIndexColumns.isEmpty()) { throw new TDHSSQLException("can't get columns from hint", parseSQL.getSql()); } Map<String, List<OperationStruct>> mapOperationStructs = parseSQL.getMapOperationStructs(); for (String hintKey : listIndexColumns) { List<OperationStruct> k = mapOperationStructs.get(hintKey); if ((k == null || k.isEmpty())) { if (keys.isEmpty()) { throw new TDHSSQLException("don't find key in Index!", parseSQL.getSql()); } else { break; } } if (keys.isEmpty()) { keys.add(k.get(0)); if ("in".equalsIgnoreCase(k.get(0).getOper())) { //in??? break; } } else { if (keys.get(0).getOper().equalsIgnoreCase(k.get(0).getOper())) { keys.add(k.get(0)); } else { break; } } } List<String> orderByColumn = parseSQL.getOrderByColumn(); if (!keys.get(0).getOper().equalsIgnoreCase("=") && ((orderByColumn != null && !orderByColumn.isEmpty()) || parseSQL.getSortMethod() != null)) { throw new TDHSSQLException("can't support this orderBy!", parseSQL.getSql()); } if (orderByColumn != null) { if (orderByColumn.size() > listIndexColumns.size()) { throw new TDHSSQLException("too many orderBy columns for this index!", parseSQL.getSql()); } int j = 0; for (String oc : orderByColumn) { String indexField = listIndexColumns.get(listIndexColumns.size() - orderByColumn.size() + j); if (!indexField.equalsIgnoreCase(oc)) { throw new TDHSSQLException( "can't support this orderBy columns which is not in index or error sort!", parseSQL.getSql()); } } } Where where = query.where().index(index); processKey(parseSQL, keys, where); } else { if (hint != null && StringUtils.isNotBlank(hint.getErrmsg())) { logger.warn("TDHS: JDBC hint error:" + hint.getErrmsg() + " , SQL:" + parseSQL.getSql()); } List<String> orderByColumn = parseSQL.getOrderByColumn(); if ((orderByColumn != null && !orderByColumn.isEmpty()) || parseSQL.getSortMethod() != null) { throw new TDHSSQLException("can't support orderBy without hint!", parseSQL.getSql()); } OperationStruct firstKey = operation.get(0); keys.add(firstKey); String firstField = StringUtil.escapeField(firstKey.getColumnName()); if (firstField == null) { throw new TDHSSQLException("error field [" + firstKey.getColumnName() + "]", parseSQL.getSql()); } Where where = query.where().fields(firstField); processKey(parseSQL, keys, where); } for (OperationStruct o : operation) { if (!keys.contains(o)) { String op = o.getOper(); if ("=".equalsIgnoreCase(op)) { PerprocessFilter perprocessFilter = new PerprocessFilter(parseSQL, o).invoke(); String f = perprocessFilter.getF(); String v = perprocessFilter.getV(); query.and().field(f).equal(v); } else if ("!=".equalsIgnoreCase(op)) { PerprocessFilter perprocessFilter = new PerprocessFilter(parseSQL, o).invoke(); String f = perprocessFilter.getF(); String v = perprocessFilter.getV(); query.and().field(f).not(v); } else if (">".equalsIgnoreCase(op)) { PerprocessFilter perprocessFilter = new PerprocessFilter(parseSQL, o).invoke(); String f = perprocessFilter.getF(); String v = perprocessFilter.getV(); query.and().field(f).greaterThan(v); } else if (">=".equalsIgnoreCase(op)) { PerprocessFilter perprocessFilter = new PerprocessFilter(parseSQL, o).invoke(); String f = perprocessFilter.getF(); String v = perprocessFilter.getV(); query.and().field(f).greaterEqual(v); } else if ("<".equalsIgnoreCase(op)) { PerprocessFilter perprocessFilter = new PerprocessFilter(parseSQL, o).invoke(); String f = perprocessFilter.getF(); String v = perprocessFilter.getV(); query.and().field(f).lessThan(v); } else if ("<=".equalsIgnoreCase(op)) { PerprocessFilter perprocessFilter = new PerprocessFilter(parseSQL, o).invoke(); String f = perprocessFilter.getF(); String v = perprocessFilter.getV(); query.and().field(f).lessEqual(v); } else if ("in".equalsIgnoreCase(op)) { throw new TDHSSQLException("can't support IN in this postion!", parseSQL.getSql()); } else { throw new TDHSSQLException("error operation!", parseSQL.getSql()); } } } int limit = parseSQL.getLimit(); int start = parseSQL.getLimitOffset(); if (limit < 0 || start < 0) { throw new TDHSSQLException("limit can't be negative!", parseSQL.getSql()); } query.limit(start, limit); return query; } private void processKey(ParseSQL parseSQL, List<OperationStruct> keys, Where where) throws TDHSSQLException { String firstKeyOper = keys.get(0).getOper(); if ("=".equalsIgnoreCase(firstKeyOper)) { if (OrderByType.DESC.equals(parseSQL.getSortMethod())) { where.descEqual(parseKeys(parseSQL, keys)); } else { where.equal(parseKeys(parseSQL, keys)); } } else if (">".equalsIgnoreCase(firstKeyOper)) { where.greaterThan(parseKeys(parseSQL, keys)); } else if (">=".equalsIgnoreCase(firstKeyOper)) { where.greaterEqual(parseKeys(parseSQL, keys)); } else if ("<".equalsIgnoreCase(firstKeyOper)) { where.lessThan(parseKeys(parseSQL, keys)); } else if ("<=".equalsIgnoreCase(firstKeyOper)) { where.lessEqual(parseKeys(parseSQL, keys)); } else if ("in".equalsIgnoreCase(firstKeyOper)) { String[] in = StringUtil.escapeIn(keys.get(0).getValue()); if (in == null || in.length == 0) { throw new TDHSSQLException("don't have in values!", parseSQL.getSql()); } String[][] inv = new String[in.length][1]; int i = 0; for (String[] a : inv) { a[0] = in[i++]; } where.in(inv); } else { throw new TDHSSQLException("error operation!", parseSQL.getSql()); } } private String[] parseKeys(ParseSQL parseSQL, List<OperationStruct> keys) throws TDHSSQLException { String kk[] = new String[keys.size()]; int i = 0; for (OperationStruct os : keys) { String s = StringUtil.escapeValue(os.getValue()); if (s == null) { throw new TDHSSQLException("error value in index!", parseSQL.getSql()); } kk[i++] = s; } return kk; } private void doDelete(com.taobao.tdhs.client.statement.Statement s, ParseSQL parseSQL, String tableName, String dbName) throws SQLException { Query query = preprocessGet(s, parseSQL, tableName, dbName); TDHSResponse response = null; try { response = query.delete(); } catch (TDHSException e) { throw new SQLException(e); } processResponse(response, true); } private void doUpdate(com.taobao.tdhs.client.statement.Statement s, ParseSQL parseSQL, String tableName, String dbName) throws SQLException { Query query = preprocessGet(s, parseSQL, tableName, dbName); List<Entry<String, String>> updateEntries = parseSQL.getUpdateEntries(); if (updateEntries == null || updateEntries.isEmpty()) { throw new TDHSSQLException("no value to update!", parseSQL.getSql()); } for (Entry<String, String> e : updateEntries) { if (StringUtils.isBlank(e.getKey()) || StringUtils.isBlank(e.getValue())) { throw new TDHSSQLException("insert column and values can't be empty!", parseSQL.getSql()); } String field = StringUtil.escapeField(StringUtils.trim(e.getKey())); if (field == null) { throw new TDHSSQLException("insert column is error!", parseSQL.getSql()); } String value = StringUtils.trim(e.getValue()); if (StringUtils.equalsIgnoreCase("null", value)) { query.set().field(field).setNull(); } else if (StringUtils.equalsIgnoreCase("now()", value)) { query.set().field(field).setNow(); } else { if (StringUtils.startsWith(value, field)) { value = value.substring(field.length()); value = StringUtils.trim(value); if (StringUtils.startsWith(value, "+")) { value = value.substring(1); value = StringUtils.trim(value); if (StringUtil.isLong(value)) { query.set().field(field).add(Long.valueOf(value)); } else { throw new TDHSSQLException("update value is error ,is not long", parseSQL.getSql()); } } else if (StringUtils.startsWith(value, "-")) { value = value.substring(1); value = StringUtils.trim(value); if (StringUtil.isLong(value)) { query.set().field(field).sub(Long.valueOf(value)); } else { throw new TDHSSQLException("update value is error ,is not long", parseSQL.getSql()); } } else { throw new TDHSSQLException("update value is error maybe can't support!", parseSQL.getSql()); } } else { value = StringUtil.escapeValue(value); if (value == null) { throw new TDHSSQLException("update value is error!", parseSQL.getSql()); } if (StringUtils.startsWith(value, BYTE_PARAMETER_PREFIX)) { int pidx = ConvertUtil .safeConvertInt(StringUtils.substring(value, BYTE_PARAMETER_PREFIX.length()), -1); if (byteParameters.containsKey(pidx)) { query.set().field(field).set(byteParameters.get(pidx)); } else { query.set().field(field).set(value); } } else { query.set().field(field).set(value); } } } } TDHSResponse response = null; try { response = query.update(); } catch (TDHSException e) { throw new SQLException(e); } processResponse(response, true); } private void doInsert(com.taobao.tdhs.client.statement.Statement s, ParseSQL parseSQL, String tableName, String dbName) throws SQLException { Insert insert = s.insert().use(dbName).from(tableName); List<Entry<String, String>> insertEntries = parseSQL.getInsertEntries(); if (insertEntries == null || insertEntries.isEmpty()) { throw new TDHSSQLException("no value to insert!", parseSQL.getSql()); } for (Entry<String, String> e : insertEntries) { if (StringUtils.isBlank(e.getKey()) || StringUtils.isBlank(e.getValue())) { throw new TDHSSQLException("insert column and values can't be empty!", parseSQL.getSql()); } String field = StringUtil.escapeField(StringUtils.trim(e.getKey())); if (field == null) { throw new TDHSSQLException("insert column is error!", parseSQL.getSql()); } String value = StringUtils.trim(e.getValue()); if (StringUtils.equalsIgnoreCase("null", value)) { insert.valueSetNull(field); } else if (StringUtils.equalsIgnoreCase("now()", value)) { insert.valueSetNow(field); } else { value = StringUtil.escapeValue(value); if (value == null) { throw new TDHSSQLException("insert value is error!", parseSQL.getSql()); } if (StringUtils.startsWith(value, BYTE_PARAMETER_PREFIX)) { int pidx = ConvertUtil .safeConvertInt(StringUtils.substring(value, BYTE_PARAMETER_PREFIX.length()), -1); if (byteParameters.containsKey(pidx)) { insert.value(field, byteParameters.get(pidx)); } else { insert.value(field, value); } } else { insert.value(field, value); } } } TDHSResponse response = null; try { response = insert.insert(); } catch (TDHSException e) { throw new SQLException(e); } processResponse(response, null, true, true); } protected void processResponse(TDHSResponse response, boolean isModify) throws SQLException { processResponse(response, null, isModify, false); } protected void processResponse(TDHSResponse response, @Nullable String[] alias, boolean isModify, boolean isInsert) throws SQLException { if (batchStatement != null) { return; } if (response == null) { throw new SQLException("None response!"); } try { if (!TDHSResponseEnum.ClientStatus.OK.equals(response.getStatus())) { if (TDHSResponseEnum.ClientStatus.DB_ERROR.equals(response.getStatus())) { throw new SQLException( "DB Handler return error code [" + response.getMySQLHandlerErrorCode() + "]"); } else { throw new SQLException("return error [" + response.getErrorCode() + "]"); } } else { TDHSResultSet resultSet; if (alias != null) { resultSet = (TDHSResultSet) response.getResultSet(Arrays.asList(alias)); } else { resultSet = (TDHSResultSet) response.getResultSet(); } currentResultSet = resultSet != null ? new TDHSMySQLResultSetWrap(resultSet) : null; if (isModify) { updateCount = isInsert ? 1 : ConvertUtil.safeConvertInt(response.getFieldData().get(0).get(0), -1); } else { updateCount = -1; } } } catch (Exception e) { throw new SQLException(e); } } public int executeUpdate(String sql) throws SQLException { execute(sql); return updateCount; } protected void checkclose() throws SQLException { if (isClosed() || getConnection().isClosed()) { throw new SQLException("This statement is closed!"); } } protected void reset() throws SQLException { currentResultSet = null; updateCount = -1; clearBatch(); } public void close() throws SQLException { close = true; reset(); } public int getMaxFieldSize() throws SQLException { return TDHSCommon.REQUEST_MAX_FIELD_NUM; } public void setMaxFieldSize(int max) throws SQLException { throw new SQLFeatureNotSupportedException(); } public int getMaxRows() throws SQLException { return 0; } public void setMaxRows(int max) throws SQLException { throw new SQLFeatureNotSupportedException(); } public void setEscapeProcessing(boolean enable) throws SQLException { } public int getQueryTimeout() throws SQLException { return Integer.parseInt(connection.getClientInfo(NonRegisteringDriver.TIME_OUT_PROPERTY_KEY)); } public void setQueryTimeout(int seconds) throws SQLException { logger.info("setQueryTimeout will be ignore!"); // throw new SQLFeatureNotSupportedException(); } public void cancel() throws SQLException { throw new SQLFeatureNotSupportedException(); } public SQLWarning getWarnings() throws SQLException { return null; } public void clearWarnings() throws SQLException { } public void setCursorName(String name) throws SQLException { throw new SQLFeatureNotSupportedException(); } public boolean execute(String sql) throws SQLException { checkclose(); reset(); if (StringUtils.isBlank(sql)) { throw new SQLException("sql can't be null!"); } PreproccessSQL preproccessSQL = new PreproccessSQL(sql).invoke(); ParseSQL parseSQL = preproccessSQL.getParseSQL(); String tableName = preproccessSQL.getTableName(); String dbName = preproccessSQL.getDbName(); if (getConnection().isReadOnly() && !SQLType.SELECT.equals(parseSQL.getSqlType())) { throw new TDHSSQLException( "It is readonly, can't executeSelect " + parseSQL.getSqlType().toString() + " !", sql); } com.taobao.tdhs.client.statement.Statement s; HintStruct hint = parseSQL.getHint(); if (hint != null && StringUtils.isBlank(hint.getErrmsg())) { s = client.createStatement(hint.getHash()); } else { s = client; } switch (parseSQL.getSqlType()) { case INSERT: doInsert(s, parseSQL, tableName, dbName); return false; case UPDATE: doUpdate(s, parseSQL, tableName, dbName); return false; case DELETE: doDelete(s, parseSQL, tableName, dbName); return false; case SELECT: doSelectOrCount(s, parseSQL, tableName, dbName); return true; default: throw new TDHSSQLException("can't parse this SQL!", sql); } } public ResultSet getResultSet() throws SQLException { checkclose(); return currentResultSet; } public int getUpdateCount() throws SQLException { checkclose(); return updateCount; } public boolean getMoreResults() throws SQLException { return false; } public void setFetchDirection(int direction) throws SQLException { throw new SQLFeatureNotSupportedException(); } public int getFetchDirection() throws SQLException { return ResultSet.FETCH_FORWARD; } public void setFetchSize(int rows) throws SQLException { throw new SQLFeatureNotSupportedException(); } public int getFetchSize() throws SQLException { throw new SQLFeatureNotSupportedException(); } public int getResultSetConcurrency() throws SQLException { return ResultSet.CONCUR_READ_ONLY; } public int getResultSetType() throws SQLException { return ResultSet.TYPE_FORWARD_ONLY; } public void addBatch(String sql) throws SQLException { checkclose(); if (StringUtils.isBlank(sql)) { throw new SQLException("sql can't be null!"); } if (batchStatement == null) { batchStatement = client.createBatchStatement(); } PreproccessSQL preproccessSQL = new PreproccessSQL(sql).invoke(); ParseSQL parseSQL = preproccessSQL.getParseSQL(); String tableName = preproccessSQL.getTableName(); String dbName = preproccessSQL.getDbName(); switch (parseSQL.getSqlType()) { case INSERT: doInsert(batchStatement, parseSQL, tableName, dbName); break; case UPDATE: doUpdate(batchStatement, parseSQL, tableName, dbName); break; case DELETE: doDelete(batchStatement, parseSQL, tableName, dbName); break; case SELECT: throw new TDHSSQLException("add batch not support select!", sql); default: throw new TDHSSQLException("can't parse this SQL!", sql); } } public void clearBatch() throws SQLException { batchStatement = null; } public int[] executeBatch() throws SQLException { checkclose(); BatchStatement b = batchStatement; reset(); TDHSResponse[] responses = null; try { responses = b.commit(); } catch (TDHSException e) { throw new SQLException(e); } int[] result = new int[responses.length]; StringBuilder expString = new StringBuilder(); boolean success = true; int i = 0; try { for (TDHSResponse r : responses) { if (!r.getStatus().equals(TDHSResponseEnum.ClientStatus.OK)) { success = false; expString.append(r).append("|"); } else { result[i++] = ConvertUtil.safeConvertInt(r.getFieldData().get(0).get(0), -1); } } } catch (TDHSException e) { throw new SQLException(e); } if (!success) { throw new SQLException(expString.toString()); } return result; } public Connection getConnection() throws SQLException { return connection; } public boolean getMoreResults(int current) throws SQLException { checkclose(); return false; } public ResultSet getGeneratedKeys() throws SQLException { throw new SQLFeatureNotSupportedException(); } public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS) { throw new SQLFeatureNotSupportedException(); } return executeUpdate(sql); } public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { if (columnIndexes != null && columnIndexes.length > 0) { throw new SQLFeatureNotSupportedException(); } return executeUpdate(sql); } public int executeUpdate(String sql, String[] columnNames) throws SQLException { if (columnNames != null && columnNames.length > 0) { throw new SQLFeatureNotSupportedException(); } return executeUpdate(sql); } public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS) { throw new SQLFeatureNotSupportedException(); } return execute(sql); } public boolean execute(String sql, int[] columnIndexes) throws SQLException { if (columnIndexes != null && columnIndexes.length > 0) { throw new SQLFeatureNotSupportedException(); } return execute(sql); } public boolean execute(String sql, String[] columnNames) throws SQLException { if (columnNames != null && columnNames.length > 0) { throw new SQLFeatureNotSupportedException(); } return execute(sql); } public int getResultSetHoldability() throws SQLException { return ResultSet.CLOSE_CURSORS_AT_COMMIT; } public boolean isClosed() throws SQLException { return this.close || getConnection().isClosed(); } public void setPoolable(boolean poolable) throws SQLException { throw new SQLFeatureNotSupportedException(); } public boolean isPoolable() throws SQLException { throw new SQLFeatureNotSupportedException(); } public void closeOnCompletion() throws SQLException { throw new SQLFeatureNotSupportedException(); } public boolean isCloseOnCompletion() throws SQLException { throw new SQLFeatureNotSupportedException(); } public <T> T unwrap(Class<T> iface) throws SQLException { try { // This works for classes that aren't actually wrapping // anything return iface.cast(this); } catch (ClassCastException cce) { throw new SQLException(cce); } } public boolean isWrapperFor(Class<?> iface) throws SQLException { return iface.isInstance(this); } protected class PreproccessSQL { private String sql; private ParseSQL parseSQL; private String tableName; private String dbName; public PreproccessSQL(@NotNull String sql) { this.sql = sql; } public ParseSQL getParseSQL() { return parseSQL; } public String getTableName() { return tableName; } public String getDbName() { return dbName; } public PreproccessSQL invoke() throws SQLException { parseSQL = parseSQL(sql); tableName = StringUtil.escapeField(parseSQL.getTableName()); if (tableName == null) { throw new TDHSSQLException("can't parse table name!", sql); } dbName = db; if (StringUtils.contains(tableName, ".")) { String[] strings = StringUtils.split(tableName, "."); if (strings.length == 2) { dbName = strings[0]; tableName = strings[1]; } else if (strings.length == 1) { tableName = strings[0]; } else { throw new TDHSSQLException("can't parse table!", sql); } } if (StringUtils.isBlank(dbName) || StringUtils.isBlank(tableName)) { throw new TDHSSQLException("can't parse table!", sql); } return this; } private ParseSQL parseSQL(@NotNull String sql) throws SQLException { ParseSQL parseSQL = new ParseSQL(sql); parseSQL.sqlDispatch(); if (StringUtils.isNotBlank(parseSQL.getErrmsg())) { throw new TDHSSQLException("message:" + parseSQL.getErrmsg(), sql); } if (StringUtils.isBlank(parseSQL.getTableName())) { throw new TDHSSQLException("don't have table!", sql); } return parseSQL; } } private class PerprocessFilter { private ParseSQL parseSQL; private OperationStruct o; private String f; private String v; public PerprocessFilter(ParseSQL parseSQL, OperationStruct o) { this.parseSQL = parseSQL; this.o = o; } public String getF() { return f; } public String getV() { return v; } public PerprocessFilter invoke() throws TDHSSQLException { f = StringUtil.escapeField(o.getColumnName()); if (f == null) { throw new TDHSSQLException("error column [" + o.getColumnName() + "]", parseSQL.getSql()); } v = StringUtil.escapeValue(o.getValue()); if (v == null) { throw new TDHSSQLException("error value [" + o.getValue() + "]", parseSQL.getSql()); } return this; } } }