提交 a88c87c7 authored 作者: Thomas Mueller's avatar Thomas Mueller

Changes in updatable result sets are now visible even when resetting the result set.

Key values can now be changed in updatable result sets.
上级 449dbd81
...@@ -63,10 +63,21 @@ import org.h2.value.ValueTime; ...@@ -63,10 +63,21 @@ import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp; import org.h2.value.ValueTimestamp;
/** /**
* Represents a result set. Column names are case-insensitive, quotes are not * <p>
* supported. The first column has the column index 1. Result sets are updatable * Represents a result set.
* when the result only contains columns from one table, and if it contains all * </p>
* columns of a unique index (primary key or other) of this table. * <p>
* Column names are case-insensitive, quotes are not supported. The first column
* has the column index 1.
* </p>
* <p>
* Updatable result sets:
* Result sets are updatable when the result only contains columns from one
* table, and if it contains all columns of a unique index (primary key or
* other) of this table. Key columns may not contain NULL (because multiple rows
* with NULL could exist). In updatable result sets, own changes are visible,
* but not own inserts and deletes.
* </p>
*/ */
public class JdbcResultSet extends TraceObject implements ResultSet { public class JdbcResultSet extends TraceObject implements ResultSet {
private final SessionInterface session; private final SessionInterface session;
...@@ -80,6 +91,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -80,6 +91,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
private Value[] insertRow; private Value[] insertRow;
private Value[] updateRow; private Value[] updateRow;
private HashMap columnNameMap; private HashMap columnNameMap;
private HashMap patchedRows;
JdbcResultSet(JdbcConnection conn, JdbcStatement stat, ResultInterface result, int id, JdbcResultSet(JdbcConnection conn, JdbcStatement stat, ResultInterface result, int id,
boolean closeStatement, boolean scrollable) { boolean closeStatement, boolean scrollable) {
...@@ -2821,8 +2833,15 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -2821,8 +2833,15 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
checkOnValidRow(); checkOnValidRow();
if (updateRow != null) { if (updateRow != null) {
UpdatableRow row = getUpdatableRow(); UpdatableRow row = getUpdatableRow();
row.updateRow(result.currentRow(), updateRow); Value[] current = result.currentRow();
row.refreshRow(result.currentRow()); row.updateRow(current, updateRow);
for (int i = 0; i < updateRow.length; i++) {
if (updateRow[i] == null) {
updateRow[i] = current[i];
}
}
Value[] patch = row.readRow(updateRow);
patchCurrentRow(patch);
updateRow = null; updateRow = null;
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -2866,7 +2885,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -2866,7 +2885,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
throw Message.getSQLException(ErrorCode.NO_DATA_AVAILABLE); throw Message.getSQLException(ErrorCode.NO_DATA_AVAILABLE);
} }
checkOnValidRow(); checkOnValidRow();
getUpdatableRow().refreshRow(result.currentRow()); patchCurrentRow(getUpdatableRow().readRow(result.currentRow()));
updateRow = null; updateRow = null;
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
...@@ -2983,7 +3002,15 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -2983,7 +3002,15 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
private Value get(int columnIndex) throws SQLException { private Value get(int columnIndex) throws SQLException {
checkColumnIndex(columnIndex); checkColumnIndex(columnIndex);
checkOnValidRow(); checkOnValidRow();
Value[] list = result.currentRow(); Value[] list;
if (patchedRows == null) {
list = result.currentRow();
} else {
list = (Value[]) patchedRows.get(ObjectUtils.getInteger(result.getRowId()));
if (list == null) {
list = result.currentRow();
}
}
Value value = list[columnIndex - 1]; Value value = list[columnIndex - 1];
wasNull = value == ValueNull.INSTANCE; wasNull = value == ValueNull.INSTANCE;
return value; return value;
...@@ -3474,5 +3501,25 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -3474,5 +3501,25 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
public String toString() { public String toString() {
return getTraceObjectName() + ": " + result; return getTraceObjectName() + ": " + result;
} }
private void patchCurrentRow(Value[] row) throws SQLException {
boolean changed = false;
Value[] current = result.currentRow();
for (int i = 0; i < row.length; i++) {
if (!row[i].compareEqual(current[i])) {
changed = true;
break;
}
}
if (patchedRows == null) {
patchedRows = new HashMap();
}
Integer rowId = ObjectUtils.getInteger(result.getRowId());
if (!changed) {
patchedRows.remove(rowId);
} else {
patchedRows.put(rowId, row);
}
}
} }
...@@ -156,18 +156,6 @@ public class UpdatableRow { ...@@ -156,18 +156,6 @@ public class UpdatableRow {
// return rs.getInt(1) == 0; // return rs.getInt(1) == 0;
// } // }
/**
* Re-reads a row from the database and updates the values in the array.
*
* @param row the values
*/
public void refreshRow(Value[] row) throws SQLException {
Value[] newRow = readRow(row);
for (int i = 0; i < columnCount; i++) {
row[i] = newRow[i];
}
}
private void appendTableName(StringBuffer buff) { private void appendTableName(StringBuffer buff) {
if (schemaName != null && schemaName.length() > 0) { if (schemaName != null && schemaName.length() > 0) {
buff.append(StringUtils.quoteIdentifier(schemaName)); buff.append(StringUtils.quoteIdentifier(schemaName));
...@@ -176,7 +164,13 @@ public class UpdatableRow { ...@@ -176,7 +164,13 @@ public class UpdatableRow {
buff.append(StringUtils.quoteIdentifier(tableName)); buff.append(StringUtils.quoteIdentifier(tableName));
} }
private Value[] readRow(Value[] row) throws SQLException { /**
* Re-reads a row from the database and updates the values in the array.
*
* @param row the values that contain the key
* @return the row
*/
public Value[] readRow(Value[] row) throws SQLException {
StringBuffer buff = new StringBuffer(); StringBuffer buff = new StringBuffer();
buff.append("SELECT "); buff.append("SELECT ");
appendColumnList(buff, false); appendColumnList(buff, false);
......
...@@ -30,6 +30,31 @@ public class TestUpdatableResultSet extends TestBase { ...@@ -30,6 +30,31 @@ public class TestUpdatableResultSet extends TestBase {
testScroll(); testScroll();
testUpdateDeleteInsert(); testUpdateDeleteInsert();
testUpdateDataType(); testUpdateDataType();
testUpdateResetRead();
}
private void testUpdateResetRead() throws Exception {
deleteDb("updatableResultSet");
Connection conn = getConnection("updatableResultSet");
Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
stat.execute("INSERT INTO TEST VALUES(1, 'Hello')");
stat.execute("INSERT INTO TEST VALUES(2, 'World')");
ResultSet rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID");
rs.next();
rs.updateInt(1, 10);
rs.updateRow();
rs.next();
rs.updateString(2, "Welt");
rs.updateRow();
rs.beforeFirst();
rs.next();
assertEquals(10, rs.getInt(1));
assertEquals("Hello", rs.getString(2));
rs.next();
assertEquals(2, rs.getInt(1));
assertEquals("Welt", rs.getString(2));
conn.close();
} }
private void testScroll() throws Exception { private void testScroll() throws Exception {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论