diff --git a/jdbc/pom.xml b/jdbc/pom.xml index 46df3483a45c58d46bdc8c540a2395703a993f63..39588bf133ecda26830007dd6b4eb8388a16d803 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -54,4 +54,28 @@ LICENSE file. <scope>test</scope> </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>2.15</version> + <configuration> + <consoleOutput>true</consoleOutput> + <configLocation>../checkstyle.xml</configLocation> + <failOnViolation>true</failOnViolation> + <failsOnError>true</failsOnError> + </configuration> + <executions> + <execution> + <id>validate</id> + <phase>validate</phase> + <goals> + <goal>checkstyle</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCli.java b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCli.java index d736eaf85f63dbec8e95dee4b45300fb7bdff363..4ca4f96c22006af9b672fc57e91fe769aab44d62 100644 --- a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCli.java +++ b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCli.java @@ -1,17 +1,17 @@ /** - * Copyright (c) 2010 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 - * 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. See accompanying + * Copyright (c) 2010 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 + * 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. See accompanying * LICENSE file. */ package com.yahoo.ycsb.db; @@ -29,32 +29,31 @@ import java.util.Properties; * Execute a JDBC command line. * * @author sudipto - * */ -public class JdbcDBCli implements JdbcDBClientConstants { - +public final class JdbcDBCli { + private static void usageMessage() { System.out.println("JdbcCli. Options:"); System.out.println(" -p key=value properties defined."); System.out.println(" -P location of the properties file to load."); System.out.println(" -c SQL command to execute."); } - + private static void executeCommand(Properties props, String sql) - throws SQLException { - String driver = props.getProperty(DRIVER_CLASS); - String username = props.getProperty(CONNECTION_USER); - String password = props.getProperty(CONNECTION_PASSWD, ""); - String url = props.getProperty(CONNECTION_URL); + throws SQLException { + String driver = props.getProperty(JdbcDBClient.DRIVER_CLASS); + String username = props.getProperty(JdbcDBClient.CONNECTION_USER); + String password = props.getProperty(JdbcDBClient.CONNECTION_PASSWD, ""); + String url = props.getProperty(JdbcDBClient.CONNECTION_URL); if (driver == null || username == null || url == null) { throw new SQLException("Missing connection information."); } - + Connection conn = null; - + try { Class.forName(driver); - + conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); stmt.execute(sql); @@ -73,12 +72,12 @@ public class JdbcDBCli implements JdbcDBClientConstants { * @param args */ public static void main(String[] args) { - + if (args.length == 0) { usageMessage(); System.exit(0); } - + Properties props = new Properties(); Properties fileprops = new Properties(); String sql = null; @@ -160,13 +159,13 @@ public class JdbcDBCli implements JdbcDBClientConstants { fileprops.setProperty(prop, props.getProperty(prop)); } - + if (sql == null) { System.err.println("Missing command."); usageMessage(); System.exit(1); } - + try { executeCommand(fileprops, sql); } catch (SQLException e) { @@ -175,4 +174,10 @@ public class JdbcDBCli implements JdbcDBClientConstants { } } + /** + * Hidden constructor. + */ + private JdbcDBCli() { + super(); + } } diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java index 7da1d5ecbb2ffef390fdf6a494e2235c89f46c28..f5a858fde781ed8a7af1ce4d2673b62f438cec85 100644 --- a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java +++ b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java @@ -1,20 +1,19 @@ /** - * Copyright (c) 2010 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 - * 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. See accompanying + * Copyright (c) 2010 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 + * 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. See accompanying * LICENSE file. */ - package com.yahoo.ycsb.db; import com.yahoo.ycsb.DB; @@ -29,17 +28,21 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** - * A class that wraps a JDBC compliant database to allow it to be interfaced with YCSB. - * This class extends {@link DB} and implements the database interface used by YCSB client. + * A class that wraps a JDBC compliant database to allow it to be interfaced + * with YCSB. This class extends {@link DB} and implements the database + * interface used by YCSB client. * - * <br> Each client will have its own instance of this class. This client is - * not thread safe. + * <br> + * Each client will have its own instance of this class. This client is not + * thread safe. * - * <br> This interface expects a schema <key> <field1> <field2> <field3> ... - * All attributes are of type VARCHAR. All accesses are through the primary key. Therefore, - * only one index on the primary key is needed. + * <br> + * This interface expects a schema <key> <field1> <field2> <field3> ... All + * attributes are of type VARCHAR. All accesses are through the primary key. + * Therefore, only one index on the primary key is needed. * - * <p> The following options must be passed when using this database client. + * <p> + * The following options must be passed when using this database client. * * <ul> * <li><b>db.driver</b> The JDBC driver class to use.</li> @@ -47,36 +50,66 @@ import java.util.concurrent.ConcurrentMap; * <li><b>db.user</b> User name for the connection.</li> * <li><b>db.passwd</b> Password for the connection.</li> * </ul> - * + * * @author sudipto * */ -public class JdbcDBClient extends DB implements JdbcDBClientConstants { - +public class JdbcDBClient extends DB { + + /** The class to use as the jdbc driver. */ + public static final String DRIVER_CLASS = "db.driver"; + + /** The URL to connect to the database. */ + public static final String CONNECTION_URL = "db.url"; + + /** The user name to use to connect to the database. */ + public static final String CONNECTION_USER = "db.user"; + + /** The password to use for establishing the connection. */ + public static final String CONNECTION_PASSWD = "db.passwd"; + + /** The JDBC fetch size hinted to the driver. */ + public static final String JDBC_FETCH_SIZE = "jdbc.fetchsize"; + + /** The JDBC connection auto-commit property for the driver. */ + public static final String JDBC_AUTO_COMMIT = "jdbc.autocommit"; + + /** The name of the property for the number of fields in a record. */ + public static final String FIELD_COUNT_PROPERTY = "fieldcount"; + + /** Default number of fields in a record. */ + public static final String FIELD_COUNT_PROPERTY_DEFAULT = "10"; + + /** Representing a NULL value. */ + public static final String NULL_VALUE = "NULL"; + + /** The primary key in the user table. */ + public static final String PRIMARY_KEY = "YCSB_KEY"; + + /** The field name prefix in the table. */ + public static final String COLUMN_PREFIX = "FIELD"; + private ArrayList<Connection> conns; private boolean initialized = false; private Properties props; private Integer jdbcFetchSize; private static final String DEFAULT_PROP = ""; private ConcurrentMap<StatementType, PreparedStatement> cachedStatements; - + /** * The statement type for the prepared statements. */ private static class StatementType { - + enum Type { - INSERT(1), - DELETE(2), - READ(3), - UPDATE(4), - SCAN(5), - ; - int internalType; + INSERT(1), DELETE(2), READ(3), UPDATE(4), SCAN(5); + + private final int internalType; + private Type(int type) { internalType = type; } - + int getHashCode() { final int prime = 31; int result = 1; @@ -84,17 +117,17 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { return result; } } - - Type type; - int shardIndex; - int numFields; - String tableName; - - StatementType(Type type, String tableName, int numFields, int _shardIndex) { + + private Type type; + private int shardIndex; + private int numFields; + private String tableName; + + StatementType(Type type, String tableName, int numFields, int shardIndex) { this.type = type; this.tableName = tableName; this.numFields = numFields; - this.shardIndex = _shardIndex; + this.shardIndex = shardIndex; } @Override @@ -102,185 +135,210 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { final int prime = 31; int result = 1; result = prime * result + numFields + 100 * shardIndex; - result = prime * result - + ((tableName == null) ? 0 : tableName.hashCode()); + result = + prime * result + ((tableName == null) ? 0 : tableName.hashCode()); result = prime * result + ((type == null) ? 0 : type.getHashCode()); return result; } @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } StatementType other = (StatementType) obj; - if (numFields != other.numFields) + if (numFields != other.numFields) { return false; - if (shardIndex != other.shardIndex) + } + if (shardIndex != other.shardIndex) { return false; + } if (tableName == null) { - if (other.tableName != null) + if (other.tableName != null) { return false; - } else if (!tableName.equals(other.tableName)) + } + } else if (!tableName.equals(other.tableName)) { return false; - if (type != other.type) + } + if (type != other.type) { return false; + } return true; } } - /** - * For the given key, returns what shard contains data for this key - * - * @param key Data key to do operation on - * @return Shard index - */ - private int getShardIndexByKey(String key) { - int ret = Math.abs(key.hashCode()) % conns.size(); - //System.out.println(conns.size() + ": Shard instance for "+ key + " (hash " + key.hashCode()+ " ) " + " is " + ret); - return ret; - } + /** + * For the given key, returns what shard contains data for this key. + * + * @param key + * Data key to do operation on + * @return Shard index + */ + private int getShardIndexByKey(String key) { + int ret = Math.abs(key.hashCode()) % conns.size(); + // System.out.println(conns.size() + ": Shard instance for "+ key + " (hash + // " + key.hashCode()+ " ) " + " is " + ret); + return ret; + } - /** - * For the given key, returns Connection object that holds connection - * to the shard that contains this key - * - * @param key Data key to get information for - * @return Connection object - */ - private Connection getShardConnectionByKey(String key) { - return conns.get(getShardIndexByKey(key)); - } + /** + * For the given key, returns Connection object that holds connection to the + * shard that contains this key. + * + * @param key + * Data key to get information for + * @return Connection object + */ + private Connection getShardConnectionByKey(String key) { + return conns.get(getShardIndexByKey(key)); + } - private void cleanupAllConnections() throws SQLException { - for(Connection conn: conns) { - conn.close(); - } + private void cleanupAllConnections() throws SQLException { + for (Connection conn : conns) { + conn.close(); } - + } + /** - * Initialize the database connection and set it up for sending requests to the database. - * This must be called once per client. - * @throws + * Initialize the database connection and set it up for sending requests to + * the database. This must be called once per client. @throws */ @Override - public void init() throws DBException { - if (initialized) { - System.err.println("Client connection already initialized."); - return; - } - props = getProperties(); - String urls = props.getProperty(CONNECTION_URL, DEFAULT_PROP); - String user = props.getProperty(CONNECTION_USER, DEFAULT_PROP); - String passwd = props.getProperty(CONNECTION_PASSWD, DEFAULT_PROP); - String driver = props.getProperty(DRIVER_CLASS); - - String jdbcFetchSizeStr = props.getProperty(JDBC_FETCH_SIZE); - if (jdbcFetchSizeStr != null) { - try { - this.jdbcFetchSize = Integer.parseInt(jdbcFetchSizeStr); - } catch (NumberFormatException nfe) { - System.err.println("Invalid JDBC fetch size specified: " + jdbcFetchSizeStr); - throw new DBException(nfe); - } + public void init() throws DBException { + if (initialized) { + System.err.println("Client connection already initialized."); + return; + } + props = getProperties(); + String urls = props.getProperty(CONNECTION_URL, DEFAULT_PROP); + String user = props.getProperty(CONNECTION_USER, DEFAULT_PROP); + String passwd = props.getProperty(CONNECTION_PASSWD, DEFAULT_PROP); + String driver = props.getProperty(DRIVER_CLASS); + + String jdbcFetchSizeStr = props.getProperty(JDBC_FETCH_SIZE); + if (jdbcFetchSizeStr != null) { + try { + this.jdbcFetchSize = Integer.parseInt(jdbcFetchSizeStr); + } catch (NumberFormatException nfe) { + System.err + .println("Invalid JDBC fetch size specified: " + jdbcFetchSizeStr); + throw new DBException(nfe); } + } - String autoCommitStr = props.getProperty(JDBC_AUTO_COMMIT, Boolean.TRUE.toString()); - Boolean autoCommit = Boolean.parseBoolean(autoCommitStr); + String autoCommitStr = + props.getProperty(JDBC_AUTO_COMMIT, Boolean.TRUE.toString()); + Boolean autoCommit = Boolean.parseBoolean(autoCommitStr); - try { - if (driver != null) { - Class.forName(driver); - } - int shardCount = 0; - conns = new ArrayList<Connection>(3); - for (String url: urls.split(",")) { - System.out.println("Adding shard node URL: " + url); - Connection conn = DriverManager.getConnection(url, user, passwd); - - // Since there is no explicit commit method in the DB interface, all - // operations should auto commit, except when explicitly told not to - // (this is necessary in cases such as for PostgreSQL when running a - // scan workload with fetchSize) - conn.setAutoCommit(autoCommit); - - shardCount++; - conns.add(conn); - } + try { + if (driver != null) { + Class.forName(driver); + } + int shardCount = 0; + conns = new ArrayList<Connection>(3); + for (String url : urls.split(",")) { + System.out.println("Adding shard node URL: " + url); + Connection conn = DriverManager.getConnection(url, user, passwd); - System.out.println("Using " + shardCount + " shards"); + // Since there is no explicit commit method in the DB interface, all + // operations should auto commit, except when explicitly told not to + // (this is necessary in cases such as for PostgreSQL when running a + // scan workload with fetchSize) + conn.setAutoCommit(autoCommit); - cachedStatements = new ConcurrentHashMap<StatementType, PreparedStatement>(); - } catch (ClassNotFoundException e) { - System.err.println("Error in initializing the JDBS driver: " + e); - throw new DBException(e); - } catch (SQLException e) { - System.err.println("Error in database operation: " + e); + shardCount++; + conns.add(conn); + } + + System.out.println("Using " + shardCount + " shards"); + + cachedStatements = + new ConcurrentHashMap<StatementType, PreparedStatement>(); + } catch (ClassNotFoundException e) { + System.err.println("Error in initializing the JDBS driver: " + e); + throw new DBException(e); + } catch (SQLException e) { + System.err.println("Error in database operation: " + e); throw new DBException(e); } catch (NumberFormatException e) { System.err.println("Invalid value for fieldcount property. " + e); throw new DBException(e); } - initialized = true; - } - + initialized = true; + } + @Override - public void cleanup() throws DBException { - try { + public void cleanup() throws DBException { + try { cleanupAllConnections(); } catch (SQLException e) { System.err.println("Error in closing the connection. " + e); throw new DBException(e); } - } - - private PreparedStatement createAndCacheInsertStatement(StatementType insertType, String key) - throws SQLException { - StringBuilder insert = new StringBuilder("INSERT INTO "); - insert.append(insertType.tableName); - insert.append(" VALUES(?"); + } + + private PreparedStatement createAndCacheInsertStatement( + StatementType insertType, String key) throws SQLException { + StringBuilder insert = new StringBuilder("INSERT INTO "); + insert.append(insertType.tableName); + insert.append(" VALUES(?"); for (int i = 0; i < insertType.numFields; i++) { insert.append(",?"); } insert.append(")"); - PreparedStatement insertStatement = getShardConnectionByKey(key).prepareStatement(insert.toString()); - PreparedStatement stmt = cachedStatements.putIfAbsent(insertType, insertStatement); - if (stmt == null) return insertStatement; - else return stmt; - } - - private PreparedStatement createAndCacheReadStatement(StatementType readType, String key) - throws SQLException { + PreparedStatement insertStatement = + getShardConnectionByKey(key).prepareStatement(insert.toString()); + PreparedStatement stmt = + cachedStatements.putIfAbsent(insertType, insertStatement); + if (stmt == null) { + return insertStatement; + } + return stmt; + } + + private PreparedStatement createAndCacheReadStatement(StatementType readType, + String key) throws SQLException { StringBuilder read = new StringBuilder("SELECT * FROM "); read.append(readType.tableName); read.append(" WHERE "); read.append(PRIMARY_KEY); read.append(" = "); read.append("?"); - PreparedStatement readStatement = getShardConnectionByKey(key).prepareStatement(read.toString()); - PreparedStatement stmt = cachedStatements.putIfAbsent(readType, readStatement); - if (stmt == null) return readStatement; - else return stmt; + PreparedStatement readStatement = + getShardConnectionByKey(key).prepareStatement(read.toString()); + PreparedStatement stmt = + cachedStatements.putIfAbsent(readType, readStatement); + if (stmt == null) { + return readStatement; + } + return stmt; } - - private PreparedStatement createAndCacheDeleteStatement(StatementType deleteType, String key) - throws SQLException { + + private PreparedStatement createAndCacheDeleteStatement( + StatementType deleteType, String key) throws SQLException { StringBuilder delete = new StringBuilder("DELETE FROM "); delete.append(deleteType.tableName); delete.append(" WHERE "); delete.append(PRIMARY_KEY); delete.append(" = ?"); - PreparedStatement deleteStatement = getShardConnectionByKey(key).prepareStatement(delete.toString()); - PreparedStatement stmt = cachedStatements.putIfAbsent(deleteType, deleteStatement); - if (stmt == null) return deleteStatement; - else return stmt; + PreparedStatement deleteStatement = + getShardConnectionByKey(key).prepareStatement(delete.toString()); + PreparedStatement stmt = + cachedStatements.putIfAbsent(deleteType, deleteStatement); + if (stmt == null) { + return deleteStatement; + } + return stmt; } - - private PreparedStatement createAndCacheUpdateStatement(StatementType updateType, String key) - throws SQLException { + + private PreparedStatement createAndCacheUpdateStatement( + StatementType updateType, String key) throws SQLException { StringBuilder update = new StringBuilder("UPDATE "); update.append(updateType.tableName); update.append(" SET "); @@ -288,20 +346,26 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { update.append(COLUMN_PREFIX); update.append(i); update.append("=?"); - if (i < updateType.numFields - 1) update.append(", "); + if (i < updateType.numFields - 1) { + update.append(", "); + } } update.append(" WHERE "); update.append(PRIMARY_KEY); update.append(" = ?"); - PreparedStatement insertStatement = getShardConnectionByKey(key).prepareStatement(update.toString()); - PreparedStatement stmt = cachedStatements.putIfAbsent(updateType, insertStatement); - if (stmt == null) return insertStatement; - else return stmt; + PreparedStatement insertStatement = + getShardConnectionByKey(key).prepareStatement(update.toString()); + PreparedStatement stmt = + cachedStatements.putIfAbsent(updateType, insertStatement); + if (stmt == null) { + return insertStatement; + } + return stmt; } - - private PreparedStatement createAndCacheScanStatement(StatementType scanType, String key) - throws SQLException { - StringBuilder select = new StringBuilder("SELECT * FROM "); + + private PreparedStatement createAndCacheScanStatement(StatementType scanType, + String key) throws SQLException { + StringBuilder select = new StringBuilder("SELECT * FROM "); select.append(scanType.tableName); select.append(" WHERE "); select.append(PRIMARY_KEY); @@ -309,18 +373,25 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { select.append(" ORDER BY "); select.append(PRIMARY_KEY); select.append(" LIMIT ?"); - PreparedStatement scanStatement = getShardConnectionByKey(key).prepareStatement(select.toString()); - if (this.jdbcFetchSize != null) scanStatement.setFetchSize(this.jdbcFetchSize); - PreparedStatement stmt = cachedStatements.putIfAbsent(scanType, scanStatement); - if (stmt == null) return scanStatement; - else return stmt; + PreparedStatement scanStatement = + getShardConnectionByKey(key).prepareStatement(select.toString()); + if (this.jdbcFetchSize != null) { + scanStatement.setFetchSize(this.jdbcFetchSize); + } + PreparedStatement stmt = + cachedStatements.putIfAbsent(scanType, scanStatement); + if (stmt == null) { + return scanStatement; + } + return stmt; } - @Override - public Status read(String tableName, String key, Set<String> fields, - HashMap<String, ByteIterator> result) { + @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); @@ -340,16 +411,18 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { resultSet.close(); return Status.OK; } catch (SQLException e) { - System.err.println("Error in processing read of table " + tableName + ": "+e); + System.err + .println("Error in processing read of table " + tableName + ": " + e); return Status.ERROR; } - } + } - @Override - public Status scan(String tableName, String startKey, int recordcount, - Set<String> fields, Vector<HashMap<String, ByteIterator>> result) { + @Override + 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); @@ -359,7 +432,8 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { ResultSet resultSet = scanStatement.executeQuery(); for (int i = 0; i < recordcount && resultSet.next(); i++) { if (result != null && fields != null) { - HashMap<String, ByteIterator> values = new HashMap<String, ByteIterator>(); + HashMap<String, ByteIterator> values = + new HashMap<String, ByteIterator>(); for (String field : fields) { String value = resultSet.getString(field); values.put(field, new StringByteIterator(value)); @@ -373,13 +447,15 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { System.err.println("Error in processing scan of table: " + tableName + e); return Status.ERROR; } - } + } - @Override - public Status update(String tableName, String key, HashMap<String, ByteIterator> values) { + @Override + 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)); + StatementType type = new StatementType(StatementType.Type.UPDATE, + tableName, numFields, getShardIndexByKey(key)); PreparedStatement updateStatement = cachedStatements.get(type); if (updateStatement == null) { updateStatement = createAndCacheUpdateStatement(type, key); @@ -390,23 +466,28 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { } updateStatement.setString(index, key); int result = updateStatement.executeUpdate(); - if (result == 1) return Status.OK; - else return Status.UNEXPECTED_STATE; + if (result == 1) { + return Status.OK; + } + return Status.UNEXPECTED_STATE; } catch (SQLException e) { - System.err.println("Error in processing update to table: " + tableName + e); + System.err + .println("Error in processing update to table: " + tableName + e); return Status.ERROR; } - } - - @Override - 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)); - PreparedStatement insertStatement = cachedStatements.get(type); - if (insertStatement == null) { - insertStatement = createAndCacheInsertStatement(type, key); - } + } + + @Override + 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)); + 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()) { @@ -414,29 +495,36 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants { insertStatement.setString(index++, field); } int result = insertStatement.executeUpdate(); - if (result == 1) return Status.OK; - else return Status.UNEXPECTED_STATE; + if (result == 1) { + return Status.OK; + } + return Status.UNEXPECTED_STATE; } catch (SQLException e) { - System.err.println("Error in processing insert to table: " + tableName + e); + System.err + .println("Error in processing insert to table: " + tableName + e); return Status.ERROR; } - } + } - @Override - public Status delete(String tableName, String key) { + @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); } deleteStatement.setString(1, key); int result = deleteStatement.executeUpdate(); - if (result == 1) return Status.OK; - else return Status.UNEXPECTED_STATE; + if (result == 1) { + return Status.OK; + } + return Status.UNEXPECTED_STATE; } catch (SQLException e) { - System.err.println("Error in processing delete to table: " + tableName + e); + System.err + .println("Error in processing delete to table: " + tableName + e); return Status.ERROR; } - } + } } diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java deleted file mode 100644 index 4d396ac13c8787cbc7398b651cc10098197a32b8..0000000000000000000000000000000000000000 --- a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2010 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 - * 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. See accompanying - * LICENSE file. - */ -package com.yahoo.ycsb.db; - - -/** - * Constants used by the JDBC client. - * - * @author sudipto - * - */ -public interface JdbcDBClientConstants { - - /** The class to use as the jdbc driver. */ - public static final String DRIVER_CLASS = "db.driver"; - - /** The URL to connect to the database. */ - public static final String CONNECTION_URL = "db.url"; - - /** The user name to use to connect to the database. */ - public static final String CONNECTION_USER = "db.user"; - - /** The password to use for establishing the connection. */ - public static final String CONNECTION_PASSWD = "db.passwd"; - - /** The JDBC fetch size hinted to the driver. */ - public static final String JDBC_FETCH_SIZE = "jdbc.fetchsize"; - - /** The JDBC connection auto-commit property for the driver. */ - public static final String JDBC_AUTO_COMMIT = "jdbc.autocommit"; - - /** The name of the property for the number of fields in a record. */ - public static final String FIELD_COUNT_PROPERTY="fieldcount"; - - /** Default number of fields in a record. */ - public static final String FIELD_COUNT_PROPERTY_DEFAULT="10"; - - /** Representing a NULL value. */ - public static final String NULL_VALUE = "NULL"; - - /** The primary key in the user table.*/ - public static String PRIMARY_KEY = "YCSB_KEY"; - - /** The field name prefix in the table.*/ - public static String COLUMN_PREFIX = "FIELD"; -} diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCreateTable.java b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCreateTable.java index 7416d05a4f1abb5cf8cf6c09f47561818da862f8..5de54ac7d1bd97c1343af519c82d658f0a18ebfa 100644 --- a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCreateTable.java +++ b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBCreateTable.java @@ -1,17 +1,17 @@ /** - * Copyright (c) 2010 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 - * 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. See accompanying + * Copyright (c) 2010 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 + * 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. See accompanying * LICENSE file. */ package com.yahoo.ycsb.db; @@ -29,9 +29,8 @@ import java.util.Properties; * Utility class to create the table to be used by the benchmark. * * @author sudipto - * */ -public class JdbcDBCreateTable implements JdbcDBClientConstants { +public final class JdbcDBCreateTable { private static void usageMessage() { System.out.println("Create Table Client. Options:"); @@ -40,47 +39,48 @@ public class JdbcDBCreateTable implements JdbcDBClientConstants { System.out.println(" -n name of the table."); System.out.println(" -f number of fields (default 10)."); } - + private static void createTable(Properties props, String tablename) - throws SQLException { - String driver = props.getProperty(DRIVER_CLASS); - String username = props.getProperty(CONNECTION_USER); - String password = props.getProperty(CONNECTION_PASSWD, ""); - String url = props.getProperty(CONNECTION_URL); - int fieldcount = Integer.parseInt(props.getProperty(FIELD_COUNT_PROPERTY, - FIELD_COUNT_PROPERTY_DEFAULT)); - + throws SQLException { + String driver = props.getProperty(JdbcDBClient.DRIVER_CLASS); + String username = props.getProperty(JdbcDBClient.CONNECTION_USER); + String password = props.getProperty(JdbcDBClient.CONNECTION_PASSWD, ""); + String url = props.getProperty(JdbcDBClient.CONNECTION_URL); + int fieldcount = + Integer.parseInt(props.getProperty(JdbcDBClient.FIELD_COUNT_PROPERTY, + JdbcDBClient.FIELD_COUNT_PROPERTY_DEFAULT)); + if (driver == null || username == null || url == null) { throw new SQLException("Missing connection information."); } - + Connection conn = null; - + try { Class.forName(driver); - + conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); - + StringBuilder sql = new StringBuilder("DROP TABLE IF EXISTS "); sql.append(tablename); sql.append(";"); - + stmt.execute(sql.toString()); - + sql = new StringBuilder("CREATE TABLE "); sql.append(tablename); sql.append(" (KEY VARCHAR PRIMARY KEY"); - + for (int idx = 0; idx < fieldcount; idx++) { sql.append(", FIELD"); sql.append(idx); sql.append(" VARCHAR"); } sql.append(");"); - + stmt.execute(sql.toString()); - + System.out.println("Table " + tablename + " created.."); } catch (ClassNotFoundException e) { throw new SQLException("JDBC Driver class not found."); @@ -91,17 +91,17 @@ public class JdbcDBCreateTable implements JdbcDBClientConstants { } } } - + /** * @param args */ public static void main(String[] args) { - + if (args.length == 0) { usageMessage(); System.exit(0); } - + String tablename = null; int fieldcount = -1; Properties props = new Properties(); @@ -199,17 +199,18 @@ public class JdbcDBCreateTable implements JdbcDBClientConstants { } props = fileprops; - + if (tablename == null) { System.err.println("table name missing."); usageMessage(); System.exit(1); } - + if (fieldcount > 0) { - props.setProperty(FIELD_COUNT_PROPERTY, String.valueOf(fieldcount)); + props.setProperty(JdbcDBClient.FIELD_COUNT_PROPERTY, + String.valueOf(fieldcount)); } - + try { createTable(props, tablename); } catch (SQLException e) { @@ -217,4 +218,11 @@ public class JdbcDBCreateTable implements JdbcDBClientConstants { System.exit(1); } } + + /** + * Hidden constructor. + */ + private JdbcDBCreateTable() { + super(); + } } diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/package-info.java b/jdbc/src/main/java/com/yahoo/ycsb/db/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..bd7cefaedfcc75b9cae29a3ea995e60f68716c93 --- /dev/null +++ b/jdbc/src/main/java/com/yahoo/ycsb/db/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2014, 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 + * 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. See accompanying + * LICENSE file. + */ + +/** + * The YCSB binding for stores that can be accessed via JDBC. + */ +package com.yahoo.ycsb.db; + diff --git a/jdbc/src/test/java/com/yahoo/ycsb/db/JdbcDBClientTest.java b/jdbc/src/test/java/com/yahoo/ycsb/db/JdbcDBClientTest.java index 754ba640c76a2ec6c160f4bec59d658035234b01..aa3d2fe4d9aff74e73bdb0ce4c15eae14c4c7389 100644 --- a/jdbc/src/test/java/com/yahoo/ycsb/db/JdbcDBClientTest.java +++ b/jdbc/src/test/java/com/yahoo/ycsb/db/JdbcDBClientTest.java @@ -54,9 +54,9 @@ public class JdbcDBClientTest { jdbcDBClient = new JdbcDBClient(); Properties p = new Properties(); - p.setProperty(JdbcDBClientConstants.CONNECTION_URL, TEST_DB_URL); - p.setProperty(JdbcDBClientConstants.DRIVER_CLASS, TEST_DB_DRIVER); - p.setProperty(JdbcDBClientConstants.CONNECTION_USER, TEST_DB_USER); + p.setProperty(JdbcDBClient.CONNECTION_URL, TEST_DB_URL); + p.setProperty(JdbcDBClient.DRIVER_CLASS, TEST_DB_DRIVER); + p.setProperty(JdbcDBClient.CONNECTION_USER, TEST_DB_USER); jdbcDBClient.setProperties(p); jdbcDBClient.init();