Skip to content
Snippets Groups Projects
Commit 73ec3b1e authored by Andy Kruth's avatar Andy Kruth
Browse files

[jdbc] solidified field ordering

Changes to account for the field ordering. Now correctly inserting and
updating field values so that they can be verified when using
dataintegrity=true.

Fixes #132
parent b7d22498
No related branches found
No related tags found
No related merge requests found
......@@ -83,6 +83,27 @@ public class JdbcDBClient extends DB {
private static final String DEFAULT_PROP = "";
private ConcurrentMap<StatementType, PreparedStatement> cachedStatements;
/**
* Ordered field information for insert and update statements.
*/
private static class OrderedFieldInfo {
private String fieldKeys;
private List<String> fieldValues;
OrderedFieldInfo(String fieldKeys, List<String> fieldValues) {
this.fieldKeys = fieldKeys;
this.fieldValues = fieldValues;
}
String getFieldKeys() {
return fieldKeys;
}
List<String> getFieldValues() {
return fieldValues;
}
}
/**
* The statement type for the prepared statements.
*/
......@@ -109,11 +130,13 @@ public class JdbcDBClient extends DB {
private int shardIndex;
private int numFields;
private String tableName;
private String fieldString;
StatementType(Type type, String tableName, int numFields, int shardIndex) {
StatementType(Type type, String tableName, int numFields, String fieldString, int shardIndex) {
this.type = type;
this.tableName = tableName;
this.numFields = numFields;
this.fieldString = fieldString;
this.shardIndex = shardIndex;
}
......@@ -155,6 +178,9 @@ public class JdbcDBClient extends DB {
if (type != other.type) {
return false;
}
if (!fieldString.equals(other.fieldString)) {
return false;
}
return true;
}
}
......@@ -261,6 +287,7 @@ public class JdbcDBClient extends DB {
private PreparedStatement createAndCacheInsertStatement(StatementType insertType, String key) throws SQLException {
StringBuilder insert = new StringBuilder("INSERT INTO ");
insert.append(insertType.tableName);
insert.append(" (" + PRIMARY_KEY + "," + insertType.fieldString + ")");
insert.append(" VALUES(?");
for (int i = 0; i < insertType.numFields; i++) {
insert.append(",?");
......@@ -304,14 +331,14 @@ public class JdbcDBClient extends DB {
}
private PreparedStatement createAndCacheUpdateStatement(StatementType updateType, String key) throws SQLException {
String[] fieldKeys = updateType.fieldString.split(",");
StringBuilder update = new StringBuilder("UPDATE ");
update.append(updateType.tableName);
update.append(" SET ");
for (int i = 0; i < updateType.numFields; i++) {
update.append(COLUMN_PREFIX);
update.append(i);
for (int i = 0; i < fieldKeys.length; i++) {
update.append(fieldKeys[i]);
update.append("=?");
if (i < updateType.numFields - 1) {
if (i < fieldKeys.length - 1) {
update.append(", ");
}
}
......@@ -349,7 +376,7 @@ public class JdbcDBClient extends DB {
@Override
public Status read(String tableName, String key, Set<String> fields, HashMap<String, ByteIterator> result) {
try {
StatementType type = new StatementType(StatementType.Type.READ, tableName, 1, getShardIndexByKey(key));
StatementType type = new StatementType(StatementType.Type.READ, tableName, 1, "", getShardIndexByKey(key));
PreparedStatement readStatement = cachedStatements.get(type);
if (readStatement == null) {
readStatement = createAndCacheReadStatement(type, key);
......@@ -378,7 +405,7 @@ public class JdbcDBClient extends DB {
public Status scan(String tableName, String startKey, int recordcount, Set<String> fields,
Vector<HashMap<String, ByteIterator>> result) {
try {
StatementType type = new StatementType(StatementType.Type.SCAN, tableName, 1, getShardIndexByKey(startKey));
StatementType type = new StatementType(StatementType.Type.SCAN, tableName, 1, "", getShardIndexByKey(startKey));
PreparedStatement scanStatement = cachedStatements.get(type);
if (scanStatement == null) {
scanStatement = createAndCacheScanStatement(type, startKey);
......@@ -408,14 +435,16 @@ public class JdbcDBClient extends DB {
public Status update(String tableName, String key, HashMap<String, ByteIterator> values) {
try {
int numFields = values.size();
StatementType type = new StatementType(StatementType.Type.UPDATE, tableName, numFields, getShardIndexByKey(key));
OrderedFieldInfo fieldInfo = getFieldInfo(values);
StatementType type = new StatementType(StatementType.Type.UPDATE, tableName,
numFields, fieldInfo.getFieldKeys(), getShardIndexByKey(key));
PreparedStatement updateStatement = cachedStatements.get(type);
if (updateStatement == null) {
updateStatement = createAndCacheUpdateStatement(type, key);
}
int index = 1;
for (Map.Entry<String, ByteIterator> entry : values.entrySet()) {
updateStatement.setString(index++, entry.getValue().toString());
for (String value: fieldInfo.getFieldValues()) {
updateStatement.setString(index++, value);
}
updateStatement.setString(index, key);
int result = updateStatement.executeUpdate();
......@@ -433,16 +462,17 @@ public class JdbcDBClient extends DB {
public Status insert(String tableName, String key, HashMap<String, ByteIterator> values) {
try {
int numFields = values.size();
StatementType type = new StatementType(StatementType.Type.INSERT, tableName, numFields, getShardIndexByKey(key));
OrderedFieldInfo fieldInfo = getFieldInfo(values);
StatementType type = new StatementType(StatementType.Type.INSERT, tableName,
numFields, fieldInfo.getFieldKeys(), getShardIndexByKey(key));
PreparedStatement insertStatement = cachedStatements.get(type);
if (insertStatement == null) {
insertStatement = createAndCacheInsertStatement(type, key);
}
insertStatement.setString(1, key);
int index = 2;
for (Map.Entry<String, ByteIterator> entry : values.entrySet()) {
String field = entry.getValue().toString();
insertStatement.setString(index++, field);
for (String value: fieldInfo.getFieldValues()) {
insertStatement.setString(index++, value);
}
int result = insertStatement.executeUpdate();
if (result == 1) {
......@@ -458,7 +488,7 @@ public class JdbcDBClient extends DB {
@Override
public Status delete(String tableName, String key) {
try {
StatementType type = new StatementType(StatementType.Type.DELETE, tableName, 1, getShardIndexByKey(key));
StatementType type = new StatementType(StatementType.Type.DELETE, tableName, 1, "", getShardIndexByKey(key));
PreparedStatement deleteStatement = cachedStatements.get(type);
if (deleteStatement == null) {
deleteStatement = createAndCacheDeleteStatement(type, key);
......@@ -474,4 +504,20 @@ public class JdbcDBClient extends DB {
return Status.ERROR;
}
}
}
private OrderedFieldInfo getFieldInfo(HashMap<String, ByteIterator> values) {
String fieldKeys = "";
List<String> fieldValues = new ArrayList();
int count = 0;
for (Map.Entry<String, ByteIterator> entry : values.entrySet()) {
fieldKeys += entry.getKey();
if (count < values.size() - 1) {
fieldKeys += ",";
}
fieldValues.add(count, entry.getValue().toString());
count++;
}
return new OrderedFieldInfo(fieldKeys, fieldValues);
}
}
\ No newline at end of file
/**
* Copyright (c) 2015 Yahoo! Inc. All rights reserved.
* Copyright (c) 2015 - 2016 Yahoo! Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
......@@ -30,9 +30,6 @@ import java.util.HashSet;
import java.util.Properties;
import java.util.Vector;
/**
* Created by kruthar on 11/2/15.
*/
public class JdbcDBClientTest {
private static final String TEST_DB_DRIVER = "org.hsqldb.jdbc.JDBCDriver";
private static final String TEST_DB_URL = "jdbc:hsqldb:mem:ycsb";
......@@ -153,7 +150,7 @@ public class JdbcDBClientTest {
public void insertTest() {
try {
String insertKey = "user0";
insertRow(insertKey);
HashMap<String, ByteIterator> insertMap = insertRow(insertKey);
ResultSet resultSet = jdbcConnection.prepareStatement(
String.format("SELECT * FROM %s", TABLE_NAME)
......@@ -164,9 +161,7 @@ public class JdbcDBClientTest {
// Check that all the columns have expected values
assertEquals(resultSet.getString(KEY_FIELD), insertKey);
for (int i = 0; i < 3; i++) {
// TODO: This will fail until the fix is made to insert and update fields in the correct order.
// TODO: Uncomment this assertEquals when the fix is made.
//assertEquals(resultSet.getString(FIELD_PREFIX + i), insertMap.get(FIELD_PREFIX + i));
assertEquals(resultSet.getString(FIELD_PREFIX + i), insertMap.get(FIELD_PREFIX + i).toString());
}
// Check that we do not have any more rows
assertFalse(resultSet.next());
......@@ -224,9 +219,7 @@ public class JdbcDBClientTest {
resultSet.next();
assertEquals(resultSet.getString(KEY_FIELD), "user1");
for (int i = 0; i < 3; i++) {
// TODO: This will fail until the fix is made to insert and update fields in the correct order.
// TODO: Uncomment this assertEquals when the fix is made.
//assertEquals(resultSet.getString(FIELD_PREFIX + i), updateMap.get(FIELD_PREFIX + i));
assertEquals(resultSet.getString(FIELD_PREFIX + i), updateMap.get(FIELD_PREFIX + i).toString());
}
// Ensure that user2 record was not changed
......@@ -245,7 +238,7 @@ public class JdbcDBClientTest {
@Test
public void readTest() {
String insertKey = "user0";
insertRow(insertKey);
HashMap<String, ByteIterator> insertMap = insertRow(insertKey);
HashSet<String> readFields = new HashSet<String>();
HashMap<String, ByteIterator> readResultMap = new HashMap<String, ByteIterator>();
......@@ -254,9 +247,7 @@ public class JdbcDBClientTest {
jdbcDBClient.read(TABLE_NAME, insertKey, readFields, readResultMap);
assertEquals("Assert that result has correct number of fields", readFields.size(), readResultMap.size());
for (String field: readFields) {
// TODO: This will fail until the fix is made to insert and update fields in the correct order.
// TODO: Uncomment this assertEquals when the fix is made.
//assertEquals("Assert " + field + " was read correctly", insertMap.get(field), readResultMap.get(field));
assertEquals("Assert " + field + " was read correctly", insertMap.get(field).toString(), readResultMap.get(field).toString());
}
readResultMap = new HashMap<String, ByteIterator>();
......@@ -267,9 +258,7 @@ public class JdbcDBClientTest {
jdbcDBClient.read(TABLE_NAME, insertKey, readFields, readResultMap);
assertEquals("Assert that result has correct number of fields", readFields.size(), readResultMap.size());
for (String field: readFields) {
// TODO: This will fail until the fix is made to insert and update fields in the correct order.
// TODO: Uncomment this assertEquals when the fix is made.
//assertEquals("Assert " + field + " was read correctly", insertMap.get(field), readResultMap.get(field));
assertEquals("Assert " + field + " was read correctly", insertMap.get(field).toString(), readResultMap.get(field).toString());
}
}
......@@ -325,9 +314,7 @@ public class JdbcDBClientTest {
for (HashMap<String, ByteIterator> result: resultVector) {
assertEquals("Assert that this row has the correct number of fields", fieldSet.size(), result.size());
for (String field: fieldSet) {
// TODO: This will fail until the fix is made to insert and update fields in the correct order.
// TODO: Uncomment this assertEquals when the fix is made.
//assertEquals("Assert this field is correct in this row", keyMap.get(KEY_PREFIX + testIndex).get(field), result.get(field));
assertEquals("Assert this field is correct in this row", keyMap.get(KEY_PREFIX + testIndex).get(field).toString(), result.get(field).toString());
}
testIndex++;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment