From df089031395feaeda75ac6712718a72459a1af94 Mon Sep 17 00:00:00 2001 From: gaohongtao Date: Fri, 11 Nov 2016 16:51:19 +0800 Subject: [PATCH] fix #163 in the way of jdbc to get generated id --- .../sharding/jdbc/GeneratedKeysResultSet.java | 254 ++++++++++++++++++ .../jdbc/GeneratedKeysResultSetMetaData.java | 191 +++++++++++++ .../jdbc/ShardingPreparedStatement.java | 5 + .../rdb/sharding/jdbc/ShardingStatement.java | 68 +++++ .../adapter/AbstractStatementAdapter.java | 2 +- ...ractUnsupportedGeneratedKeysResultSet.java | 231 ++++++++++++++++ .../parser/result/GeneratedKeyContext.java | 83 ++++++ .../parser/result/SQLParsedResult.java | 9 +- .../parser/result/router/RouteContext.java | 3 - .../basic/mysql/MySQLInsertVisitor.java | 5 +- .../sharding/router/PreparedSQLRouter.java | 8 +- .../rdb/sharding/router/SQLRouteEngine.java | 2 +- .../rdb/sharding/router/SQLRouteResult.java | 9 +- .../rdb/sharding/jdbc/AllJDBCTests.java | 6 +- .../GeneratedKeysResultSetMetaDataTest.java | 183 +++++++++++++ .../jdbc/GeneratedKeysResultSetTest.java | 194 +++++++++++++ .../jdbc/ShardingPreparedStatementTest.java | 13 +- .../sharding/jdbc/ShardingStatementTest.java | 41 ++- .../jdbc/adapter/StatementAdapterTest.java | 4 +- ...UnsupportedGeneratedKeysResultSetTest.java | 218 +++++++++++++++ .../parser/result/SQLParsedResultTest.java | 3 +- 21 files changed, 1505 insertions(+), 27 deletions(-) create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSet.java create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaData.java create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSet.java create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/GeneratedKeyContext.java create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaDataTest.java create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetTest.java create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSetTest.java diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSet.java new file mode 100644 index 00000000000000..5bf318918b17a4 --- /dev/null +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSet.java @@ -0,0 +1,254 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.jdbc; + +import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import com.google.common.base.Preconditions; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import lombok.RequiredArgsConstructor; + +import java.math.BigDecimal; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; + +/** + * 生成键结果集. + * + * @author gaohongtao. + */ +@RequiredArgsConstructor +public class GeneratedKeysResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final Table valueTable; + + private final Map columnNameToIndexMap; + + private final Statement statement; + + private boolean isClosed; + + private int rowIndex = -1; + + public GeneratedKeysResultSet() { + valueTable = TreeBasedTable.create(); + columnNameToIndexMap = new HashMap<>(); + statement = null; + isClosed = true; + } + + @Override + public boolean isClosed() throws SQLException { + return isClosed; + } + + @Override + public boolean next() throws SQLException { + if (isClosed()) { + return false; + } + rowIndex++; + return rowIndex + 1 <= valueTable.rowKeySet().size(); + } + + @Override + public void close() throws SQLException { + isClosed = true; + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + checkState(); + return new GeneratedKeysResultSetMetaData(valueTable, columnNameToIndexMap); + } + + @Override + public boolean wasNull() throws SQLException { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) throws SQLException { + checkState(); + return valueTable.get(rowIndex, columnIndex - 1).toString(); + } + + @Override + public String getString(final String columnLabel) throws SQLException { + checkState(); + return valueTable.get(rowIndex, findColumn(columnLabel)).toString(); + } + + @Override + public byte getByte(final int columnIndex) throws SQLException { + checkState(); + return getNumberValue(columnIndex - 1).byteValue(); + } + + @Override + public byte getByte(final String columnLabel) throws SQLException { + checkState(); + return getNumberValue(findColumn(columnLabel)).byteValue(); + } + + @Override + public short getShort(final int columnIndex) throws SQLException { + checkState(); + return getNumberValue(columnIndex - 1).shortValue(); + } + + @Override + public short getShort(final String columnLabel) throws SQLException { + checkState(); + return getNumberValue(findColumn(columnLabel)).shortValue(); + } + + @Override + public int getInt(final int columnIndex) throws SQLException { + checkState(); + return getNumberValue(columnIndex - 1).intValue(); + } + + @Override + public int getInt(final String columnLabel) throws SQLException { + checkState(); + return getNumberValue(findColumn(columnLabel)).intValue(); + } + + @Override + public long getLong(final int columnIndex) throws SQLException { + checkState(); + return getNumberValue(columnIndex - 1).longValue(); + } + + @Override + public long getLong(final String columnLabel) throws SQLException { + checkState(); + return getNumberValue(findColumn(columnLabel)).longValue(); + } + + @Override + public float getFloat(final int columnIndex) throws SQLException { + checkState(); + return getNumberValue(columnIndex - 1).floatValue(); + } + + @Override + public float getFloat(final String columnLabel) throws SQLException { + checkState(); + return getNumberValue(findColumn(columnLabel)).floatValue(); + } + + @Override + public double getDouble(final int columnIndex) throws SQLException { + checkState(); + return getNumberValue(columnIndex - 1).doubleValue(); + } + + @Override + public double getDouble(final String columnLabel) throws SQLException { + checkState(); + return getNumberValue(findColumn(columnLabel)).doubleValue(); + } + + @Override + public BigDecimal getBigDecimal(final int columnIndex, final int scale) throws SQLException { + checkState(); + return new BigDecimal(getNumberValue(columnIndex - 1).longValue()).setScale(scale, BigDecimal.ROUND_HALF_UP); + } + + @Override + public BigDecimal getBigDecimal(final String columnLabel, final int scale) throws SQLException { + checkState(); + return new BigDecimal(getNumberValue(findColumn(columnLabel)).longValue()).setScale(scale, BigDecimal.ROUND_HALF_UP); + } + + @Override + public BigDecimal getBigDecimal(final int columnIndex) throws SQLException { + checkState(); + return new BigDecimal(getNumberValue(columnIndex - 1).longValue()); + } + + @Override + public BigDecimal getBigDecimal(final String columnLabel) throws SQLException { + checkState(); + return new BigDecimal(getNumberValue(findColumn(columnLabel)).longValue()); + } + + private Number getNumberValue(final int columnIndex) { + Object value = valueTable.get(rowIndex, columnIndex); + Preconditions.checkState(value instanceof Number); + return (Number) value; + } + + @Override + public byte[] getBytes(final int columnIndex) throws SQLException { + checkState(); + return getString(columnIndex).getBytes(); + } + + @Override + public byte[] getBytes(final String columnLabel) throws SQLException { + checkState(); + return getString(columnLabel).getBytes(); + } + + @Override + public Object getObject(final int columnIndex) throws SQLException { + checkState(); + return valueTable.get(rowIndex, columnIndex - 1); + } + + @Override + public Object getObject(final String columnLabel) throws SQLException { + checkState(); + return valueTable.get(rowIndex, findColumn(columnLabel)); + } + + @Override + public int findColumn(final String columnLabel) throws SQLException { + checkState(); + return columnNameToIndexMap.get(columnLabel); + } + + @Override + public int getType() throws SQLException { + checkState(); + return TYPE_FORWARD_ONLY; + } + + @Override + public int getConcurrency() throws SQLException { + checkState(); + return CONCUR_READ_ONLY; + } + + @Override + public Statement getStatement() throws SQLException { + checkState(); + return statement; + } + + private void checkState() throws SQLException { + Preconditions.checkState(!isClosed(), "ResultSet has closed"); + } +} diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaData.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaData.java new file mode 100644 index 00000000000000..41d92f547896ae --- /dev/null +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaData.java @@ -0,0 +1,191 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.jdbc; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Table; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import java.util.HashMap; +import java.util.Map; + +/** + * 生成键结果集元数据. + * + * @author gaohongtao + */ +class GeneratedKeysResultSetMetaData implements ResultSetMetaData { + + private final Map indexToColumnNameMap = new HashMap<>(); + + private final Table autoIncrementValueTable; + + GeneratedKeysResultSetMetaData(final Table autoIncrementValueTable, final Map autoIncrementColumnNameToIndexMap) { + this.autoIncrementValueTable = autoIncrementValueTable; + for (Map.Entry each : autoIncrementColumnNameToIndexMap.entrySet()) { + indexToColumnNameMap.put(each.getValue(), each.getKey()); + } + } + + @Override + public int getColumnCount() throws SQLException { + return indexToColumnNameMap.size(); + } + + @Override + public boolean isAutoIncrement(final int column) throws SQLException { + checkIndex(column); + return true; + } + + @Override + public boolean isCaseSensitive(final int column) throws SQLException { + checkIndex(column); + return true; + } + + @Override + public boolean isSearchable(final int column) throws SQLException { + checkIndex(column); + return false; + } + + @Override + public boolean isCurrency(final int column) throws SQLException { + checkIndex(column); + return false; + } + + @Override + public int isNullable(final int column) throws SQLException { + checkIndex(column); + return columnNoNulls; + } + + @Override + public boolean isSigned(final int column) throws SQLException { + checkIndex(column); + return true; + } + + @Override + public int getColumnDisplaySize(final int column) throws SQLException { + checkIndex(column); + return 0; + } + + @Override + public String getColumnLabel(final int column) throws SQLException { + checkIndex(column); + return indexToColumnNameMap.get(column - 1); + } + + @Override + public String getColumnName(final int column) throws SQLException { + checkIndex(column); + return indexToColumnNameMap.get(column - 1); + } + + @Override + public String getSchemaName(final int column) throws SQLException { + checkIndex(column); + return ""; + } + + @Override + public int getPrecision(final int column) throws SQLException { + checkIndex(column); + return 0; + } + + @Override + public int getScale(final int column) throws SQLException { + checkIndex(column); + return 0; + } + + @Override + public String getTableName(final int column) throws SQLException { + checkIndex(column); + return ""; + } + + @Override + public String getCatalogName(final int column) throws SQLException { + checkIndex(column); + return ""; + } + + @Override + public int getColumnType(final int column) throws SQLException { + checkIndex(column); + Object value = autoIncrementValueTable.get(0, column - 1); + return value instanceof Number ? Types.BIGINT : Types.VARCHAR; + } + + @Override + public String getColumnTypeName(final int column) throws SQLException { + checkIndex(column); + return ""; + } + + @Override + public boolean isReadOnly(final int column) throws SQLException { + checkIndex(column); + return true; + } + + @Override + public boolean isWritable(final int column) throws SQLException { + checkIndex(column); + return false; + } + + @Override + public boolean isDefinitelyWritable(final int column) throws SQLException { + checkIndex(column); + return false; + } + + @Override + public String getColumnClassName(final int column) throws SQLException { + checkIndex(column); + Object value = autoIncrementValueTable.get(0, column - 1); + return value.getClass().getName(); + } + + @Override + @SuppressWarnings("unchecked") + public T unwrap(final Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T) this; + } + throw new SQLException(String.format("[%s] cannot be unwrapped as [%s]", getClass().getName(), iface.getName())); + } + + @Override + public boolean isWrapperFor(final Class iface) throws SQLException { + return iface.isInstance(this); + } + + private void checkIndex(final int column) { + Preconditions.checkArgument(column >= 1 && column <= indexToColumnNameMap.size()); + } +} diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java index a3655cad207d3d..ffded697be40a2 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java @@ -136,6 +136,7 @@ public void addBatch() throws SQLException { wrapper.getDmlExecutionEvents().add(each.getDMLExecutionEvent().get()); } } + getGeneratedKeyContext().addRow(); } finally { clearRouteContext(); } @@ -162,6 +163,7 @@ private List routeSQL() throws SQLException { SQLRouteResult sqlRouteResult = preparedSQLRouter.route(getParameters()); MergeContext mergeContext = sqlRouteResult.getMergeContext(); setMergeContext(mergeContext); + setGeneratedKeyContext(sqlRouteResult.getGeneratedKeyContext()); for (SQLExecutionUnit each : sqlRouteResult.getExecutionUnits()) { PreparedStatement preparedStatement = (PreparedStatement) getStatement(getShardingConnection().getConnection(each.getDataSource(), sqlRouteResult.getSqlStatementType()), each.getSql()); replayMethodsInvocation(preparedStatement); @@ -173,12 +175,15 @@ private List routeSQL() throws SQLException { protected PreparedStatement generateStatement(final Connection conn, final String shardingSql) throws SQLException { if (null != autoGeneratedKeys) { + getGeneratedKeyContext().setAutoGeneratedKeys(autoGeneratedKeys); return conn.prepareStatement(shardingSql, autoGeneratedKeys); } if (null != columnIndexes) { + getGeneratedKeyContext().setColumnIndexes(columnIndexes); return conn.prepareStatement(shardingSql, columnIndexes); } if (null != columnNames) { + getGeneratedKeyContext().setColumnNames(columnNames); return conn.prepareStatement(shardingSql, columnNames); } if (0 != getResultSetHoldability()) { diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java index d3a3c6842e120f..094b6f71ddac40 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java @@ -21,11 +21,14 @@ import com.dangdang.ddframe.rdb.sharding.executor.wrapper.StatementExecutorWrapper; import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractStatementAdapter; import com.dangdang.ddframe.rdb.sharding.merger.ResultSetFactory; +import com.dangdang.ddframe.rdb.sharding.parser.result.GeneratedKeyContext; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext; import com.dangdang.ddframe.rdb.sharding.router.SQLExecutionUnit; import com.dangdang.ddframe.rdb.sharding.router.SQLRouteResult; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -40,6 +43,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; /** * 支持分片的静态语句对象. @@ -70,6 +74,12 @@ public class ShardingStatement extends AbstractStatementAdapter { @Setter(AccessLevel.PROTECTED) private ResultSet currentResultSet; + @Getter(AccessLevel.PROTECTED) + @Setter(AccessLevel.PROTECTED) + private GeneratedKeyContext generatedKeyContext; + + private ResultSet generatedKeyResultSet; + ShardingStatement(final ShardingConnection shardingConnection) { this(shardingConnection, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } @@ -119,6 +129,7 @@ public int executeUpdate(final String sql, final int autoGeneratedKeys) throws S try { return generateExecutor(sql).executeUpdate(autoGeneratedKeys); } finally { + generatedKeyContext.setAutoGeneratedKeys(autoGeneratedKeys); clearRouteContext(); } } @@ -128,6 +139,7 @@ public int executeUpdate(final String sql, final int[] columnIndexes) throws SQL try { return generateExecutor(sql).executeUpdate(columnIndexes); } finally { + generatedKeyContext.setColumnIndexes(columnIndexes); clearRouteContext(); } } @@ -137,6 +149,7 @@ public int executeUpdate(final String sql, final String[] columnNames) throws SQ try { return generateExecutor(sql).executeUpdate(columnNames); } finally { + generatedKeyContext.setColumnNames(columnNames); clearRouteContext(); } } @@ -155,6 +168,7 @@ public boolean execute(final String sql, final int autoGeneratedKeys) throws SQL try { return generateExecutor(sql).execute(autoGeneratedKeys); } finally { + generatedKeyContext.setAutoGeneratedKeys(autoGeneratedKeys); clearRouteContext(); } } @@ -164,6 +178,7 @@ public boolean execute(final String sql, final int[] columnIndexes) throws SQLEx try { return generateExecutor(sql).execute(columnIndexes); } finally { + generatedKeyContext.setColumnIndexes(columnIndexes); clearRouteContext(); } } @@ -173,21 +188,74 @@ public boolean execute(final String sql, final String[] columnNames) throws SQLE try { return generateExecutor(sql).execute(columnNames); } finally { + generatedKeyContext.setColumnNames(columnNames); clearRouteContext(); } } + @Override + public final ResultSet getGeneratedKeys() throws SQLException { + if (null != generatedKeyResultSet) { + return generatedKeyResultSet; + } + if (null == generatedKeyContext || generatedKeyContext.getColumnNameToIndexMap().isEmpty()) { + Collection routedStatements = getRoutedStatements(); + if (1 == routedStatements.size()) { + return generatedKeyResultSet = routedStatements.iterator().next().getGeneratedKeys(); + } + } + if (Statement.RETURN_GENERATED_KEYS != generatedKeyContext.getAutoGeneratedKeys() && null == generatedKeyContext.getColumnIndexes() + && null == generatedKeyContext.getColumnNames()) { + + return generatedKeyResultSet = new GeneratedKeysResultSet(); + } + return generatedKeyResultSet = new GeneratedKeysResultSet(generateAutoIncrementTable(), generatedKeyContext.getColumnNameToIndexMap(), this); + } + + private Table generateAutoIncrementTable() { + if (null != generatedKeyContext.getColumnIndexes()) { + return subTable(generatedKeyContext.getColumnIndexes()); + } else if (null != generatedKeyContext.getColumnNames()) { + List columnIndexes = new ArrayList<>(generatedKeyContext.getColumnNames().length); + for (String each : generatedKeyContext.getColumnNames()) { + if (!generatedKeyContext.getColumnNameToIndexMap().containsKey(each)) { + continue; + } + columnIndexes.add(generatedKeyContext.getColumnNameToIndexMap().get(each) + 1); + } + int[] parameter = new int[columnIndexes.size()]; + int index = 0; + for (Integer each : columnIndexes) { + parameter[index++] = each; + } + return subTable(parameter); + } + return generatedKeyContext.getValueTable(); + } + + private Table subTable(final int[] columnIndexes) { + Table result = TreeBasedTable.create(); + for (int each : columnIndexes) { + for (Map.Entry eachEntry : generatedKeyContext.getValueTable().column(each - 1).entrySet()) { + result.put(eachEntry.getKey(), each - 1, eachEntry.getValue()); + } + } + return result; + } + protected void clearRouteContext() throws SQLException { setCurrentResultSet(null); List firstList = cachedRoutedStatements.pollFirst(); cachedRoutedStatements.getFirst().addAll(firstList); firstList.clear(); cachedRoutedStatements.addLast(firstList); + generatedKeyResultSet = null; } private StatementExecutor generateExecutor(final String sql) throws SQLException { StatementExecutor result = new StatementExecutor(shardingConnection.getShardingContext().getExecutorEngine()); SQLRouteResult sqlRouteResult = shardingConnection.getShardingContext().getSqlRouteEngine().route(sql); + generatedKeyContext = sqlRouteResult.getGeneratedKeyContext(); mergeContext = sqlRouteResult.getMergeContext(); for (SQLExecutionUnit each : sqlRouteResult.getExecutionUnits()) { Statement statement = getStatement(shardingConnection.getConnection(each.getDataSource(), sqlRouteResult.getSqlStatementType()), each.getSql()); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java index 7b65bd8d6931c1..31085c120aef81 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java @@ -209,7 +209,7 @@ public final void setQueryTimeout(final int seconds) throws SQLException { } @Override - public final ResultSet getGeneratedKeys() throws SQLException { + public ResultSet getGeneratedKeys() throws SQLException { if (1 == getRoutedStatements().size()) { return getRoutedStatements().iterator().next().getGeneratedKeys(); } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSet.java new file mode 100644 index 00000000000000..295f3cb686f95b --- /dev/null +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSet.java @@ -0,0 +1,231 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported; + +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; + +/** + * 生成键结果集不支持的方法. + * + * @author gaohongtao + */ +public abstract class AbstractUnsupportedGeneratedKeysResultSet extends AbstractUnsupportedOperationResultSet { + + @Override + public boolean getBoolean(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getBoolean"); + } + + @Override + public boolean getBoolean(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getBoolean"); + } + + @Override + public Date getDate(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getDate"); + } + + @Override + public Date getDate(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getDate"); + } + + @Override + public Date getDate(final int columnIndex, final Calendar cal) throws SQLException { + throw new SQLFeatureNotSupportedException("getDate"); + } + + @Override + public Date getDate(final String columnLabel, final Calendar cal) throws SQLException { + throw new SQLFeatureNotSupportedException("getDate"); + } + + @Override + public Time getTime(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getTime"); + } + + @Override + public Time getTime(final int columnIndex, final Calendar cal) throws SQLException { + throw new SQLFeatureNotSupportedException("getTime"); + } + + @Override + public Time getTime(final String columnLabel, final Calendar cal) throws SQLException { + throw new SQLFeatureNotSupportedException("getTime"); + } + + @Override + public Time getTime(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getTime"); + } + + @Override + public Timestamp getTimestamp(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getTimestamp"); + } + + @Override + public Timestamp getTimestamp(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getTimestamp"); + } + + @Override + public Timestamp getTimestamp(final int columnIndex, final Calendar cal) throws SQLException { + throw new SQLFeatureNotSupportedException("getTimestamp"); + } + + @Override + public Timestamp getTimestamp(final String columnLabel, final Calendar cal) throws SQLException { + throw new SQLFeatureNotSupportedException("getTimestamp"); + } + + @Override + public InputStream getAsciiStream(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getAsciiStream"); + } + + @Override + public InputStream getAsciiStream(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getAsciiStream"); + } + + @Override + public InputStream getUnicodeStream(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getUnicodeStream"); + } + + @Override + public InputStream getUnicodeStream(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getUnicodeStream"); + } + + @Override + public InputStream getBinaryStream(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getBinaryStream"); + } + + @Override + public InputStream getBinaryStream(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getBinaryStream"); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throw new SQLFeatureNotSupportedException("getWarnings"); + } + + @Override + public void clearWarnings() throws SQLException { + throw new SQLFeatureNotSupportedException("clearWarnings"); + } + + @Override + public Reader getCharacterStream(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getCharacterStream"); + } + + @Override + public Reader getCharacterStream(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getCharacterStream"); + } + + @Override + public void setFetchDirection(final int direction) throws SQLException { + throw new SQLFeatureNotSupportedException("setFetchDirection"); + } + + @Override + public int getFetchDirection() throws SQLException { + throw new SQLFeatureNotSupportedException("getFetchDirection"); + } + + @Override + public void setFetchSize(final int rows) throws SQLException { + throw new SQLFeatureNotSupportedException("setFetchSize"); + } + + @Override + public int getFetchSize() throws SQLException { + throw new SQLFeatureNotSupportedException("getFetchSize"); + } + + @Override + public Object getObject(final int columnIndex, final Map> map) throws SQLException { + throw new SQLFeatureNotSupportedException("getObject"); + } + + @Override + public Object getObject(final String columnLabel, final Map> map) throws SQLException { + throw new SQLFeatureNotSupportedException("getObject"); + } + + @Override + public Blob getBlob(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getBlob"); + } + + @Override + public Blob getBlob(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getBlob"); + } + + @Override + public Clob getClob(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getClob"); + } + + @Override + public Clob getClob(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getClob"); + } + + @Override + public URL getURL(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getURL"); + } + + @Override + public URL getURL(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getURL"); + } + + @Override + public SQLXML getSQLXML(final int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException("getSQLXML"); + } + + @Override + public SQLXML getSQLXML(final String columnLabel) throws SQLException { + throw new SQLFeatureNotSupportedException("getSQLXML"); + } +} diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/GeneratedKeyContext.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/GeneratedKeyContext.java new file mode 100644 index 00000000000000..caa24ba1cd3611 --- /dev/null +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/GeneratedKeyContext.java @@ -0,0 +1,83 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.parser.result; + +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * 自动生成键上下文. + * + * @author gaohongtao. + */ +@ToString +public class GeneratedKeyContext { + + @Getter + private final List columns = new LinkedList<>(); + + @Getter + private final Map columnNameToIndexMap = new HashMap<>(); + + @Getter + private final Table valueTable = TreeBasedTable.create(); + + private int rowIndex; + + private int columnIndex; + + @Setter + @Getter + private int autoGeneratedKeys; + + @Setter + @Getter + private int[] columnIndexes; + + @Setter + @Getter + private String[] columnNames; + + /** + * 放入生成的键值. + * + * @param columnName 列名称 + * @param value 键值 + */ + public void putValue(final String columnName, final Object value) { + valueTable.put(rowIndex, columnIndex, value); + columnNameToIndexMap.put(columnName, columnIndex); + columnIndex++; + } + + /** + * 结果集增加一行. + */ + public void addRow() { + rowIndex++; + columnIndex = 0; + } +} diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java index a95372a09c56f1..0fd74a3e8f0aa1 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java @@ -17,16 +17,15 @@ package com.dangdang.ddframe.rdb.sharding.parser.result; -import java.util.ArrayList; -import java.util.List; - import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext; import com.dangdang.ddframe.rdb.sharding.parser.result.router.ConditionContext; import com.dangdang.ddframe.rdb.sharding.parser.result.router.RouteContext; - import lombok.Getter; import lombok.ToString; +import java.util.ArrayList; +import java.util.List; + /** * SQL解析结果. * @@ -39,6 +38,8 @@ public final class SQLParsedResult { private final RouteContext routeContext = new RouteContext(); + private final GeneratedKeyContext generatedKeyContext = new GeneratedKeyContext(); + private final List conditionContexts = new ArrayList<>(); private final MergeContext mergeContext = new MergeContext(); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/RouteContext.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/RouteContext.java index f8ae3b351ea469..56f46fed04582a 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/RouteContext.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/RouteContext.java @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.LinkedHashSet; -import java.util.LinkedList; /** * SQL路由上下文. @@ -42,6 +41,4 @@ public final class RouteContext { private SQLStatementType sqlStatementType; private SQLBuilder sqlBuilder; - - private Collection autoIncrementColumns = new LinkedList<>(); } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLInsertVisitor.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLInsertVisitor.java index f243f6c0c99287..5283f4a174071f 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLInsertVisitor.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLInsertVisitor.java @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule; +import com.dangdang.ddframe.rdb.sharding.parser.result.GeneratedKeyContext; import com.dangdang.ddframe.rdb.sharding.parser.result.router.Condition.BinaryOperator; import com.dangdang.ddframe.rdb.sharding.util.SQLUtil; import com.google.common.base.Optional; @@ -65,13 +66,15 @@ public boolean visit(final MySqlInsertStatement x) { private void supplyAutoIncrementColumn(final Collection autoIncrementColumns, final String tableName, final List columns, final List values) { boolean isPreparedStatement = !getParameters().isEmpty(); + GeneratedKeyContext generatedKeyContext = getParseContext().getParsedResult().getGeneratedKeyContext(); if (isPreparedStatement) { - getParseContext().getParsedResult().getRouteContext().getAutoIncrementColumns().addAll(autoIncrementColumns); + generatedKeyContext.getColumns().addAll(autoIncrementColumns); } TableRule tableRule = getParseContext().getShardingRule().findTableRule(tableName); for (String each : autoIncrementColumns) { SQLExpr sqlExpr; Object id = tableRule.generateId(each); + generatedKeyContext.putValue(each, id); if (isPreparedStatement) { sqlExpr = new SQLVariantRefExpr("?"); getParameters().add(id); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/PreparedSQLRouter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/PreparedSQLRouter.java index f864d7a326dba4..c8c837b0bd99d9 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/PreparedSQLRouter.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/PreparedSQLRouter.java @@ -19,6 +19,7 @@ import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule; import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule; +import com.dangdang.ddframe.rdb.sharding.parser.result.GeneratedKeyContext; import com.dangdang.ddframe.rdb.sharding.parser.result.SQLParsedResult; import com.dangdang.ddframe.rdb.sharding.parser.result.router.ConditionContext; import lombok.RequiredArgsConstructor; @@ -55,8 +56,11 @@ public SQLRouteResult route(final List parameters) { sqlParsedResult = engine.parseSQL(logicSql, parameters); tableRule = shardingRule.findTableRule(sqlParsedResult.getRouteContext().getTables().iterator().next().getName()); } else { - for (String each : sqlParsedResult.getRouteContext().getAutoIncrementColumns()) { - parameters.add(tableRule.generateId(each)); + GeneratedKeyContext generatedKeyContext = sqlParsedResult.getGeneratedKeyContext(); + for (String each : generatedKeyContext.getColumns()) { + Object id = tableRule.generateId(each); + parameters.add(id); + generatedKeyContext.putValue(each, id); } engine.setParameters(parameters); for (ConditionContext each : sqlParsedResult.getConditionContexts()) { diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteEngine.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteEngine.java index 669d8defb60ed0..c7a75111e18d5f 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteEngine.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteEngine.java @@ -93,7 +93,7 @@ SQLParsedResult parseSQL(final String logicSql, final List parameters) { SQLRouteResult routeSQL(final SQLParsedResult parsedResult) { Context context = MetricsContext.start("Route SQL"); - SQLRouteResult result = new SQLRouteResult(parsedResult.getRouteContext().getSqlStatementType(), parsedResult.getMergeContext()); + SQLRouteResult result = new SQLRouteResult(parsedResult.getRouteContext().getSqlStatementType(), parsedResult.getMergeContext(), parsedResult.getGeneratedKeyContext()); for (ConditionContext each : parsedResult.getConditionContexts()) { RoutingResult routingResult = routeSQL(each, parsedResult); result.getExecutionUnits().addAll(routingResult.getSQLExecutionUnits(parsedResult.getRouteContext().getSqlBuilder())); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteResult.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteResult.java index 6a8dc1867ce24c..62865f947199d5 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteResult.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteResult.java @@ -17,14 +17,15 @@ package com.dangdang.ddframe.rdb.sharding.router; -import java.util.HashSet; -import java.util.Set; - +import com.dangdang.ddframe.rdb.sharding.parser.result.GeneratedKeyContext; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext; import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.HashSet; +import java.util.Set; + /** * SQL路由结果. * @@ -38,5 +39,7 @@ public final class SQLRouteResult { private final MergeContext mergeContext; + private final GeneratedKeyContext generatedKeyContext; + private final Set executionUnits = new HashSet<>(); } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java index 2cb74da215d6c1..a76a093622276b 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java @@ -24,6 +24,7 @@ import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.ResultSetAdapterTest; import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.ResultSetGetterAdapterTest; import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.StatementAdapterTest; +import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSetTest; import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.UnsupportedOperationConnectionTest; import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.UnsupportedOperationDataSourceTest; import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.UnsupportedOperationPreparedStatementTest; @@ -45,7 +46,8 @@ UnsupportedOperationStatementTest.class, UnsupportedOperationPreparedStatementTest.class, UnsupportedOperationResultSetTest.class, - UnsupportedUpdateOperationResultSetTest.class, + UnsupportedUpdateOperationResultSetTest.class, + AbstractUnsupportedGeneratedKeysResultSetTest.class, DataSourceAdapterTest.class, ConnectionAdapterTest.class, StatementAdapterTest.class, @@ -58,6 +60,8 @@ AbstractPreparedStatementAdapterTest.class, ShardingConnectionTest.class, ShardingPreparedStatementTableOnlyTest.class, + GeneratedKeysResultSetTest.class, + GeneratedKeysResultSetMetaDataTest.class, }) public class AllJDBCTests { } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaDataTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaDataTest.java new file mode 100644 index 00000000000000..9ebf64c34145ee --- /dev/null +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetMetaDataTest.java @@ -0,0 +1,183 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.jdbc; + +import org.junit.Before; +import org.junit.Test; + +import javax.sql.rowset.RowSetMetaDataImpl; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class GeneratedKeysResultSetMetaDataTest { + + private ResultSetMetaData acutalMetaData; + + @Before + public void init() throws SQLException { + acutalMetaData = GeneratedKeysResultSetTest.createMock().getMetaData(); + } + + @Test + public void getColumnCount() throws Exception { + assertThat(acutalMetaData.getColumnCount(), is(2)); + } + + @Test + public void isAutoIncrement() throws Exception { + assertTrue(acutalMetaData.isAutoIncrement(1)); + assertTrue(acutalMetaData.isAutoIncrement(2)); + } + + @Test + public void isCaseSensitive() throws Exception { + assertTrue(acutalMetaData.isCaseSensitive(1)); + assertTrue(acutalMetaData.isCaseSensitive(2)); + } + + @Test + public void isSearchable() throws Exception { + assertFalse(acutalMetaData.isSearchable(1)); + assertFalse(acutalMetaData.isSearchable(2)); + } + + @Test + public void isCurrency() throws Exception { + assertFalse(acutalMetaData.isCurrency(1)); + assertFalse(acutalMetaData.isCurrency(2)); + } + + @Test + public void isNullable() throws Exception { + assertEquals(acutalMetaData.isNullable(1), ResultSetMetaData.columnNoNulls); + assertEquals(acutalMetaData.isNullable(2), ResultSetMetaData.columnNoNulls); + } + + @Test + public void isSigned() throws Exception { + assertTrue(acutalMetaData.isSigned(1)); + assertTrue(acutalMetaData.isSigned(2)); + } + + @Test + public void getColumnDisplaySize() throws Exception { + assertEquals(acutalMetaData.getColumnDisplaySize(1), 0); + assertEquals(acutalMetaData.getColumnDisplaySize(2), 0); + } + + @Test + public void getColumnLabel() throws Exception { + assertThat(acutalMetaData.getColumnLabel(1), is("order_id")); + assertThat(acutalMetaData.getColumnLabel(2), is("order_no")); + } + + @Test + public void getColumnName() throws Exception { + assertThat(acutalMetaData.getColumnName(1), is("order_id")); + assertThat(acutalMetaData.getColumnName(2), is("order_no")); + } + + @Test + public void getSchemaName() throws Exception { + assertThat(acutalMetaData.getSchemaName(1), is("")); + assertThat(acutalMetaData.getSchemaName(2), is("")); + } + + @Test + public void getPrecision() throws Exception { + assertEquals(acutalMetaData.getPrecision(1), 0); + assertEquals(acutalMetaData.getPrecision(2), 0); + } + + @Test + public void getScale() throws Exception { + assertEquals(acutalMetaData.getScale(1), 0); + assertEquals(acutalMetaData.getScale(2), 0); + } + + @Test + public void getTableName() throws Exception { + assertThat(acutalMetaData.getTableName(1), is("")); + assertThat(acutalMetaData.getTableName(2), is("")); + } + + @Test + public void getCatalogName() throws Exception { + assertThat(acutalMetaData.getCatalogName(1), is("")); + assertThat(acutalMetaData.getCatalogName(2), is("")); + } + + @Test + public void getColumnType() throws Exception { + assertEquals(acutalMetaData.getColumnType(1), Types.BIGINT); + assertEquals(acutalMetaData.getColumnType(2), Types.VARCHAR); + } + + @Test + public void getColumnTypeName() throws Exception { + assertThat(acutalMetaData.getColumnTypeName(1), is("")); + assertThat(acutalMetaData.getColumnTypeName(2), is("")); + } + + @Test + public void isReadOnly() throws Exception { + assertTrue(acutalMetaData.isReadOnly(1)); + assertTrue(acutalMetaData.isReadOnly(2)); + } + + @Test + public void isWritable() throws Exception { + assertFalse(acutalMetaData.isWritable(1)); + assertFalse(acutalMetaData.isWritable(2)); + } + + @Test + public void isDefinitelyWritable() throws Exception { + assertFalse(acutalMetaData.isDefinitelyWritable(1)); + assertFalse(acutalMetaData.isDefinitelyWritable(2)); + } + + @Test + public void getColumnClassName() throws Exception { + assertThat(acutalMetaData.getColumnClassName(1), is("java.lang.Long")); + assertThat(acutalMetaData.getColumnClassName(2), is("java.lang.String")); + } + + @Test + public void unwrap() throws Exception { + assertThat(acutalMetaData.unwrap(GeneratedKeysResultSetMetaData.class), is(((GeneratedKeysResultSetMetaData) acutalMetaData))); + } + + @Test(expected = SQLException.class) + public void unwrapError() throws Exception { + acutalMetaData.unwrap(RowSetMetaDataImpl.class); + } + + @Test + public void isWrapperFor() throws Exception { + assertTrue(acutalMetaData.isWrapperFor(GeneratedKeysResultSetMetaData.class)); + } + +} \ No newline at end of file diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetTest.java new file mode 100644 index 00000000000000..92f54b03a95a1b --- /dev/null +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/GeneratedKeysResultSetTest.java @@ -0,0 +1,194 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.jdbc; + +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + + +public class GeneratedKeysResultSetTest { + + private GeneratedKeysResultSet actualResultSet; + + private static final Statement statement = Mockito.mock(Statement.class); + + public static GeneratedKeysResultSet createMock() { + Map columnMap = new HashMap<>(); + columnMap.put("order_id", 0); + columnMap.put("order_no", 1); + Table valueTable = TreeBasedTable.create(); + valueTable.put(0, 0, 1L); + valueTable.put(0, 1, "OL_1"); + valueTable.put(1, 0, 2L); + valueTable.put(1, 1, "OL_2"); + return new GeneratedKeysResultSet(valueTable, columnMap, statement); + } + + @Before + public void init() { + actualResultSet = createMock(); + } + + @Test + public void next() throws Exception { + assertTrue(actualResultSet.next()); + assertTrue(actualResultSet.next()); + assertFalse(actualResultSet.next()); + } + + @Test + public void assertClose() throws Exception { + actualResultSet.close(); + assertTrue(actualResultSet.isClosed()); + GeneratedKeysResultSet actual = new GeneratedKeysResultSet(); + assertTrue(actual.isClosed()); + assertFalse(actual.next()); + } + + @Test(expected = IllegalStateException.class) + public void throwExceptionWhenInvokeClosedResultSet() throws Exception { + new GeneratedKeysResultSet().getType(); + } + + @Test + public void wasNull() throws Exception { + assertFalse(actualResultSet.wasNull()); + } + + @Test + public void getString() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getString(2), is("OL_1")); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getString("order_no"), is("OL_2")); + assertFalse(actualResultSet.next()); + } + + @Test + public void getByte() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getByte(1), is((byte)1L)); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getByte("order_id"), is((byte)2L)); + assertFalse(actualResultSet.next()); + } + + @Test + public void getShort() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getShort(1), is((short)1L)); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getShort("order_id"), is((short)2L)); + assertFalse(actualResultSet.next()); + } + + @Test + public void getInt() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getInt(1), is(1)); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getInt("order_id"), is(2)); + assertFalse(actualResultSet.next()); + } + + @Test + public void getLong() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getLong(1), is(1L)); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getLong("order_id"), is(2L)); + assertFalse(actualResultSet.next()); + } + + @Test + public void getFloat() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getFloat(1), is(1F)); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getFloat("order_id"), is(2F)); + assertFalse(actualResultSet.next()); + } + + @Test + public void getDouble() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getDouble(1), is(1D)); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getDouble("order_id"), is(2D)); + assertFalse(actualResultSet.next()); + } + + @Test + public void getBigDecimal() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getBigDecimal(1), is(new BigDecimal("1"))); + assertThat(actualResultSet.getBigDecimal(1, 2), is(new BigDecimal("1").setScale(BigDecimal.ROUND_CEILING, BigDecimal.ROUND_HALF_UP))); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getBigDecimal("order_id"), is(new BigDecimal("2"))); + assertThat(actualResultSet.getBigDecimal("order_id", 2), is(new BigDecimal("2").setScale(BigDecimal.ROUND_CEILING, BigDecimal.ROUND_HALF_UP))); + assertFalse(actualResultSet.next()); + } + + @Test + public void getBytes() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getBytes(2), is("OL_1".getBytes())); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getBytes("order_no"), is("OL_2".getBytes())); + assertFalse(actualResultSet.next()); + } + + @Test + public void getObject() throws Exception { + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getObject(2), is((Object)"OL_1")); + assertTrue(actualResultSet.next()); + assertThat(actualResultSet.getObject("order_no"), is((Object)"OL_2")); + assertFalse(actualResultSet.next()); + } + + @Test + public void getType() throws Exception { + assertThat(actualResultSet.getType(), is(ResultSet.TYPE_FORWARD_ONLY)); + } + + @Test + public void getConcurrency() throws Exception { + assertThat(actualResultSet.getConcurrency(), is(ResultSet.CONCUR_READ_ONLY)); + } + + @Test + public void getStatement() throws Exception { + assertThat(actualResultSet.getStatement(), is(statement)); + } + +} \ No newline at end of file diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatementTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatementTest.java index 5464a165083836..06e2558ba84d16 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatementTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatementTest.java @@ -28,6 +28,7 @@ import java.sql.Statement; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -252,7 +253,7 @@ public void assertAddBatchWithAutoIncrementColumn() throws SQLException { String sql = "INSERT INTO `t_order`(`order_id`, `status`) VALUES (?,?)"; try ( Connection connection = shardingDataSource.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement(sql); + PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); java.sql.Statement queryStatement = connection.createStatement()) { preparedStatement.setInt(1, 11); preparedStatement.setString(2, "BATCH"); @@ -270,6 +271,16 @@ public void assertAddBatchWithAutoIncrementColumn() throws SQLException { for (int each : result) { assertThat(each, is(1)); } + assertTrue(preparedStatement.getGeneratedKeys().next()); + assertEquals(preparedStatement.getGeneratedKeys().getLong(1), 1); + assertTrue(preparedStatement.getGeneratedKeys().next()); + assertEquals(preparedStatement.getGeneratedKeys().getLong(1), 2); + assertTrue(preparedStatement.getGeneratedKeys().next()); + assertEquals(preparedStatement.getGeneratedKeys().getLong(1), 3); + assertTrue(preparedStatement.getGeneratedKeys().next()); + assertEquals(preparedStatement.getGeneratedKeys().getLong(1), 4); + assertFalse(preparedStatement.getGeneratedKeys().next()); + try(ResultSet rs = queryStatement.executeQuery("SELECT `order_id` from `t_order` where `user_id` = 1")) { assertThat(rs.next(), is(true)); assertThat(rs.getInt(1), is(11)); diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatementTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatementTest.java index d4b08d1a6dd108..5f876a6e5f4c29 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatementTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatementTest.java @@ -17,19 +17,20 @@ package com.dangdang.ddframe.rdb.sharding.jdbc; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import com.dangdang.ddframe.rdb.integrate.db.AbstractShardingDataBasesOnlyDBUnitTest; +import org.junit.Before; +import org.junit.Test; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import org.junit.Before; -import org.junit.Test; - -import com.dangdang.ddframe.rdb.integrate.db.AbstractShardingDataBasesOnlyDBUnitTest; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; public final class ShardingStatementTest extends AbstractShardingDataBasesOnlyDBUnitTest { @@ -184,4 +185,30 @@ public void assertGetConnection() throws SQLException { assertThat(stmt.getConnection(), is(connection)); } } + + @Test + public void assertAutoIncrement() throws SQLException { + String sql = "INSERT INTO `t_order`(`order_id`, `status`) VALUES (%d,'%s')"; + try ( + Connection connection = shardingDataSource.getConnection(); + Statement stmt = connection.createStatement()) { + assertFalse(stmt.execute(String.format(sql, 1, "init"))); + assertFalse(stmt.getGeneratedKeys().next()); + assertFalse(stmt.execute(String.format(sql, 1, "init"), Statement.NO_GENERATED_KEYS)); + assertFalse(stmt.getGeneratedKeys().next()); + assertFalse(stmt.execute(String.format(sql, 1, "init"), Statement.RETURN_GENERATED_KEYS)); + assertTrue(stmt.getGeneratedKeys().next()); + assertEquals(stmt.getGeneratedKeys().getLong(1), 3); + assertFalse(stmt.execute(String.format(sql, 1, "init"), new int[]{1})); + assertTrue(stmt.getGeneratedKeys().next()); + assertEquals(stmt.getGeneratedKeys().getLong(1), 4); + assertFalse(stmt.execute(String.format(sql, 1, "init"), new String[]{"user_id"})); + assertTrue(stmt.getGeneratedKeys().next()); + assertEquals(stmt.getGeneratedKeys().getLong(1), 5); + assertFalse(stmt.execute(String.format(sql, 1, "init"), new int[]{2})); + assertFalse(stmt.getGeneratedKeys().next()); + assertFalse(stmt.execute(String.format(sql, 1, "init"), new String[]{"no"})); + assertFalse(stmt.getGeneratedKeys().next()); + } + } } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/StatementAdapterTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/StatementAdapterTest.java index 3151ccd7afe9d6..18b62ceb56e083 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/StatementAdapterTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/StatementAdapterTest.java @@ -318,9 +318,9 @@ public void assertGetGeneratedKeysForSingleRoutedStatement() throws SQLException assertTrue(generatedKeysResult.getInt(1) > 0); } - @Test(expected = IllegalStateException.class) + @Test public void assertGetGeneratedKeysForMultipleRoutedStatement() throws SQLException { actual.executeQuery("SELECT user_id AS `uid` FROM `t_order` WHERE `order_id` IN 1, 2"); - actual.getGeneratedKeys(); + assertThat(actual.getGeneratedKeys().next(), is(false)); } } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSetTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSetTest.java new file mode 100644 index 00000000000000..c630c8ac444839 --- /dev/null +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedGeneratedKeysResultSetTest.java @@ -0,0 +1,218 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported; + +import com.dangdang.ddframe.rdb.sharding.jdbc.GeneratedKeysResultSet; +import org.junit.Test; + +import java.sql.SQLFeatureNotSupportedException; +import java.util.HashMap; + +public class AbstractUnsupportedGeneratedKeysResultSetTest { + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getBoolean() throws Exception { + new GeneratedKeysResultSet().getBoolean(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getBoolean1() throws Exception { + new GeneratedKeysResultSet().getBoolean(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getDate() throws Exception { + new GeneratedKeysResultSet().getDate(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getDate1() throws Exception { + new GeneratedKeysResultSet().getDate(1, null); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getDate2() throws Exception { + new GeneratedKeysResultSet().getDate(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getDate3() throws Exception { + new GeneratedKeysResultSet().getDate("", null); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTime() throws Exception { + new GeneratedKeysResultSet().getTime(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTime1() throws Exception { + new GeneratedKeysResultSet().getTime(1, null); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTime2() throws Exception { + new GeneratedKeysResultSet().getTime(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTime3() throws Exception { + new GeneratedKeysResultSet().getTime("", null); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTimestamp() throws Exception { + new GeneratedKeysResultSet().getTimestamp(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTimestamp1() throws Exception { + new GeneratedKeysResultSet().getTimestamp(1, null); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTimestamp2() throws Exception { + new GeneratedKeysResultSet().getTimestamp(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getTimestamp3() throws Exception { + new GeneratedKeysResultSet().getTimestamp("", null); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getAsciiStream() throws Exception { + new GeneratedKeysResultSet().getAsciiStream(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getAsciiStream1() throws Exception { + new GeneratedKeysResultSet().getAsciiStream(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getUnicodeStream() throws Exception { + new GeneratedKeysResultSet().getUnicodeStream(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getUnicodeStream1() throws Exception { + new GeneratedKeysResultSet().getUnicodeStream(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getBinaryStream() throws Exception { + new GeneratedKeysResultSet().getBinaryStream(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getBinaryStream1() throws Exception { + new GeneratedKeysResultSet().getBinaryStream(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getWarnings() throws Exception { + new GeneratedKeysResultSet().getWarnings(); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void clearWarnings() throws Exception { + new GeneratedKeysResultSet().clearWarnings(); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getCharacterStream() throws Exception { + new GeneratedKeysResultSet().getCharacterStream(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getCharacterStream1() throws Exception { + new GeneratedKeysResultSet().getCharacterStream(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void setFetchDirection() throws Exception { + new GeneratedKeysResultSet().setFetchDirection(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getFetchDirection() throws Exception { + new GeneratedKeysResultSet().getFetchDirection(); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void setFetchSize() throws Exception { + new GeneratedKeysResultSet().setFetchSize(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getFetchSize() throws Exception { + new GeneratedKeysResultSet().getFetchSize(); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getObject() throws Exception { + new GeneratedKeysResultSet().getObject(1, new HashMap>()); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getObject1() throws Exception { + new GeneratedKeysResultSet().getObject("", new HashMap>()); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getBlob() throws Exception { + new GeneratedKeysResultSet().getBlob(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getBlob1() throws Exception { + new GeneratedKeysResultSet().getBlob(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getClob() throws Exception { + new GeneratedKeysResultSet().getClob(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getClob1() throws Exception { + new GeneratedKeysResultSet().getClob(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getURL() throws Exception { + new GeneratedKeysResultSet().getURL(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getURL1() throws Exception { + new GeneratedKeysResultSet().getURL(""); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getSQLXML() throws Exception { + new GeneratedKeysResultSet().getSQLXML(1); + } + + @Test(expected = SQLFeatureNotSupportedException.class) + public void getSQLXML1() throws Exception { + new GeneratedKeysResultSet().getSQLXML(""); + } + +} \ No newline at end of file diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResultTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResultTest.java index 96749dd669c7a0..5256a431f19b84 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResultTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResultTest.java @@ -52,7 +52,8 @@ public void assertToString() throws IOException { + "routeContext=RouteContext(" + "tables=[Table(name=order, alias=Optional.of(o)), Table(name=order_item, alias=Optional.absent())], " + "sqlStatementType=null, " - + "sqlBuilder=SELECT * FROM [Token(order)], autoIncrementColumns=[]), " + + "sqlBuilder=SELECT * FROM [Token(order)]), " + + "generatedKeyContext=GeneratedKeyContext(columns=[], columnNameToIndexMap={}, valueTable={}, rowIndex=0, columnIndex=0, autoGeneratedKeys=0, columnIndexes=null, columnNames=null), " + "conditionContexts=[ConditionContext(conditions={Condition.Column(columnName=id, tableName=order)=Condition(column=Condition.Column(columnName=id, tableName=order), " + "operator=IN, values=[1, 2, 3], valueIndices=[])})], " + "mergeContext=MergeContext("