This commit is contained in:
Madhavan Sridharan 2023-02-03 17:02:21 -05:00
parent 2ce57971b6
commit d92c73b8cf
14 changed files with 382 additions and 193 deletions

View File

@ -16,7 +16,9 @@
package io.nosqlbench.adapter.jdbc;
import io.nosqlbench.adapter.jdbc.opdispensers.JDBCDDLOpDispenser;
import io.nosqlbench.adapter.jdbc.opdispensers.JDBCExecuteOpDispenser;
import io.nosqlbench.adapter.jdbc.opdispensers.JDBCExecuteQueryOpDispenser;
import io.nosqlbench.adapter.jdbc.opdispensers.JDBCExecuteUpdateOpDispenser;
import io.nosqlbench.adapter.jdbc.optypes.JDBCOp;
import io.nosqlbench.api.config.standard.NBConfiguration;
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
@ -48,20 +50,19 @@ public class JDBCOpMapper implements OpMapper<JDBCOp> {
public OpDispenser<? extends JDBCOp> apply(ParsedOp op) {
LongFunction<String> spaceNameF = op.getAsFunctionOr("space", "default");
LongFunction<JDBCSpace> spaceFunc = l -> spaceCache.get(spaceNameF.apply(l));
// Since the only needed thing in the JDBCSpace is the session, we can short-circuit
// Since the only needed thing in the JDBCSpace is the connection, we can short-circuit
// to it here instead of stepping down from the cycle to the space to the connection.
LongFunction<Connection> connectionLongFunc = l -> spaceCache.get(spaceNameF.apply(l)).getConnection();
// CREATE|DROP TABLE|VIEW uses execute (as opposed to executeQuery which returns a ResultSet)
// https://jdbc.postgresql.org/documentation/query/#example54dropping-a-table-in-jdbc
//return new JDBCQueryOpDispenser(adapter, spaceFunc, op);working
//return new JDBCExecuteQueryOpDispenser(adapter, spaceFunc, op);working
/*
* If the user provides a body element, then they want to provide the JSON or
* a data structure that can be converted into JSON, bypassing any further
* specialized type-checking or op-type specific features
*/
if (op.isDefined("body")) {
throw new RuntimeException("This mode is reserved for later. Do not use the 'body' op field.");
}
@ -70,16 +71,20 @@ public class JDBCOpMapper implements OpMapper<JDBCOp> {
logger.info(() -> "Using " + opType.enumId + " statement form for '" + op.getName());
//return new JDBCQueryOpDispenser(adapter, spaceFunc, op/*, opType.targetFunction*/);
//return new JDBCExecuteQueryOpDispenser(adapter, spaceFunc, op/*, opType.targetFunction*/);
return switch (opType.enumId) {
// CREATE|DROP TABLE|VIEW uses execute (as opposed to executeQuery which returns a ResultSet)
// https://jdbc.postgresql.org/documentation/query/#example54dropping-a-table-in-jdbc
case select -> null;
case update -> null;
case create, drop, ddl -> new JDBCDDLOpDispenser(adapter, connectionLongFunc, op, opType.targetFunction)/*.apply(op)*/;
// SELECT uses 'executeQuery' and returns a 'ResultSet'
// https://jdbc.postgresql.org/documentation/query/#example51processing-a-simple-query-in-jdbc
case executeQuery, select -> new JDBCExecuteQueryOpDispenser(adapter, connectionLongFunc, op, opType.targetFunction);
// INSERT|UPDATE|DELETE uses 'executeUpdate' and returns an 'int'
// https://jdbc.postgresql.org/documentation/query/#performing-updates
case dml, executeUpdate, update, insert, delete -> new JDBCExecuteUpdateOpDispenser(adapter, connectionLongFunc, op, opType.targetFunction);
// CREATE|DROP TABLE|VIEW uses 'execute' (as opposed to 'executeQuery' which returns a 'ResultSet')
// https://jdbc.postgresql.org/documentation/query/#example54dropping-a-table-in-jdbc
case ddl, create, drop, execute -> new JDBCExecuteOpDispenser(adapter, connectionLongFunc, op, opType.targetFunction)/*.apply(op)*/;
};
}
}

View File

@ -24,9 +24,15 @@ package io.nosqlbench.adapter.jdbc;
*/
public enum JDBCOpType {
//See https://jdbc.postgresql.org/documentation/query/
select, // used for SELECT operation matches executeQuery
update, // used for performing updates such as INSERT/UPDATE/DELETE matches executeUpdate
ddl, // used for creating/modifying database objects matches execute
create, // used for CREATE operation matches execute
drop, // used for DROP operation matches execute
executeQuery, // used for SELECT operation matches executeQuery
executeUpdate, // used for performing updates such as INSERT/UPDATE/DELETE matches executeUpdate
execute, // used for creating/modifying database objects matches execute
create, // used for DDL - CREATE operation using 'execute'
drop, // used for DDL - DROP operation using 'execute'
insert, // used for DML - INSERT operation using 'executeUpdate'
update, // used for DML - UPDATE operation using 'executeUpdate'
delete, // used for DML - DELETE operation using 'executeUpdate'
select, // used for DML - SELECT operation using 'executeQuery'
dml, // used for DML operations like SELECT|INSERT|UPDATE|DELETE leveraging `executeUpdate` & `executeQuery`
ddl, // used for DDL operations like CREATE|DROP DATABASE|TABLE leveraging `execute`
}

View File

@ -221,8 +221,9 @@ public class JDBCSpace implements AutoCloseable {
public void close() {
try {
this.getConnection().close();
this.getHikariDataSource().close();
} catch (Exception e) {
logger.warn("auto-closeable jdbc connection threw exception in jdbc space(" + this.spaceName + "): " + e);
logger.error("auto-closeable jdbc connection threw exception in jdbc space(" + this.spaceName + "): " + e);
throw new RuntimeException(e);
}
}

View File

@ -17,6 +17,7 @@
package io.nosqlbench.adapter.jdbc.opdispensers;
import io.nosqlbench.adapter.jdbc.JDBCSpace;
import io.nosqlbench.adapter.jdbc.optypes.JDBCExecuteOp;
import io.nosqlbench.adapter.jdbc.optypes.JDBCOp;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter;
@ -29,13 +30,13 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.function.LongFunction;
public class JDBCDDLOpDispenser extends BaseOpDispenser<JDBCOp, JDBCSpace> {
private static final Logger logger = LogManager.getLogger(JDBCDDLOpDispenser.class);
public class JDBCExecuteOpDispenser extends BaseOpDispenser<JDBCOp, JDBCSpace> {
private static final Logger logger = LogManager.getLogger(JDBCExecuteOpDispenser.class);
private final LongFunction<String> targetFunction;
private final LongFunction<Connection> connectionLongFunction;
private final LongFunction<Statement> statementLongFunction;
public JDBCDDLOpDispenser(DriverAdapter<JDBCOp, JDBCSpace> adapter, LongFunction<Connection> connectionLongFunc, ParsedOp op, LongFunction<String> targetFunction) {
public JDBCExecuteOpDispenser(DriverAdapter<JDBCOp, JDBCSpace> adapter, LongFunction<Connection> connectionLongFunc, ParsedOp op, LongFunction<String> targetFunction) {
super(adapter, op);
this.connectionLongFunction = connectionLongFunc;
@ -61,7 +62,7 @@ public class JDBCDDLOpDispenser extends BaseOpDispenser<JDBCOp, JDBCSpace> {
}
@Override
public JDBCOp apply(long cycle) {
return new JDBCOp(this.connectionLongFunction.apply(cycle), this.statementLongFunction.apply(cycle), targetFunction.apply(cycle));
public JDBCExecuteOp apply(long cycle) {
return new JDBCExecuteOp(this.connectionLongFunction.apply(cycle), this.statementLongFunction.apply(cycle), targetFunction.apply(cycle));
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.opdispensers;
import io.nosqlbench.adapter.jdbc.JDBCSpace;
import io.nosqlbench.adapter.jdbc.optypes.JDBCExecuteQueryOp;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.engine.api.templating.ParsedOp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.function.LongFunction;
public class JDBCExecuteQueryOpDispenser extends BaseOpDispenser<JDBCExecuteQueryOp, JDBCSpace> {
private static final Logger logger = LogManager.getLogger(JDBCExecuteQueryOpDispenser.class);
private final LongFunction<String> targetFunction;
private final LongFunction<Connection> connectionLongFunction;
private final LongFunction<Statement> statementLongFunction;
public JDBCExecuteQueryOpDispenser(DriverAdapter adapter, LongFunction<Connection> connectionLongFunc, ParsedOp op, LongFunction<String> targetFunction) {
super(adapter, op);
this.connectionLongFunction = connectionLongFunc;
this.targetFunction = targetFunction;
this.statementLongFunction = createStmtFunc(op);
}
protected LongFunction<Statement> createStmtFunc(ParsedOp cmd) {
try {
LongFunction<Statement> basefunc = l -> {
try {
return this.connectionLongFunction.apply(l).createStatement();
} catch (SQLException e) {
String err_msg = "Exception occurred while attempting to construct the statement";
logger.error(err_msg, e);
throw new RuntimeException(err_msg, e);
}
};
return basefunc;
} catch (Exception ex) {
String err_msg = "Error while attempting to create the jdbc statement from the connection";
logger.error(err_msg, ex);
throw new RuntimeException(err_msg, ex);
}
}
@Override
public JDBCExecuteQueryOp apply(long cycle) {
return new JDBCExecuteQueryOp(this.connectionLongFunction.apply(cycle), this.statementLongFunction.apply(cycle), targetFunction.apply(cycle));
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.opdispensers;
import io.nosqlbench.adapter.jdbc.JDBCSpace;
import io.nosqlbench.adapter.jdbc.optypes.JDBCExecuteUpdateOp;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.engine.api.templating.ParsedOp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.function.LongFunction;
public class JDBCExecuteUpdateOpDispenser extends BaseOpDispenser<JDBCExecuteUpdateOp, JDBCSpace> {
private static final Logger logger = LogManager.getLogger(JDBCExecuteUpdateOpDispenser.class);
private final LongFunction<String> targetFunction;
private final LongFunction<Connection> connectionLongFunction;
private final LongFunction<Statement> statementLongFunction;
public JDBCExecuteUpdateOpDispenser(DriverAdapter adapter, LongFunction<Connection> connectionLongFunc, ParsedOp op, LongFunction<String> targetFunction) {
super(adapter, op);
this.connectionLongFunction = connectionLongFunc;
this.targetFunction = targetFunction;
this.statementLongFunction = createStmtFunc(op);
}
protected LongFunction<Statement> createStmtFunc(ParsedOp cmd) {
try {
LongFunction<Statement> basefunc = l -> {
try {
return this.connectionLongFunction.apply(l).createStatement();
} catch (SQLException e) {
String err_msg = "Exception occurred while attempting to construct the statement";
logger.error(err_msg, e);
throw new RuntimeException(err_msg, e);
}
};
return basefunc;
} catch (Exception ex) {
String err_msg = "Error while attempting to create the jdbc statement from the connection";
logger.error(err_msg, ex);
throw new RuntimeException(err_msg, ex);
}
}
@Override
public JDBCExecuteUpdateOp apply(long cycle) {
return new JDBCExecuteUpdateOp(this.connectionLongFunction.apply(cycle), this.statementLongFunction.apply(cycle), targetFunction.apply(cycle));
}
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.opdispensers;
import io.nosqlbench.adapter.jdbc.JDBCSpace;
import io.nosqlbench.adapter.jdbc.optypes.JDBCOp;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.engine.api.templating.ParsedOp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.sql.DataSource;
import java.sql.Statement;
import java.util.function.LongFunction;
public class JDBCQueryOpDispenser extends BaseOpDispenser<JDBCOp, JDBCSpace> {
private final static Logger logger = LogManager.getLogger(JDBCQueryOpDispenser.class);
private final DataSource dataSource;
private final LongFunction<JDBCOp> jdbcOpLongFunction;
// private final LongFunction<String> tableNameFunc;
//private final LongFunction<String> targetFunction;
public JDBCQueryOpDispenser(DriverAdapter adapter, LongFunction<JDBCSpace> jdbcSpaceLongFunction, ParsedOp op/*, LongFunction<String> targetFunction*/) {
super(adapter, op);
this.jdbcOpLongFunction = getOpFunc(jdbcSpaceLongFunction, op);
//this.targetFunction = targetFunction;
//TODO -- implement this
dataSource = null;
}
public JDBCQueryOpDispenser(DriverAdapter<JDBCOp, JDBCSpace> adapter, ParsedOp op) {
super(adapter, op);
//TODO -- implement this
this.jdbcOpLongFunction = null;
this.dataSource = null;
//this.targetFunction = null;
}
protected LongFunction<Statement> createStmtFunc(ParsedOp cmd) {
LongFunction<Statement> basefunc = l -> null;//targetFunction.apply(l));
return null;
}
private LongFunction<JDBCOp> getOpFunc(LongFunction<JDBCSpace> jdbcSpaceLongFunction, ParsedOp op) {
//return null;
LongFunction<JDBCOp> jdbcOpLongFunction = cycle -> new JDBCOp(jdbcSpaceLongFunction.apply(cycle), "DUMMY_STRINGcycle");
return jdbcOpLongFunction;
}
@Override
public JDBCOp apply(long value) {
JDBCOp op = this.jdbcOpLongFunction.apply(value);
return op;
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.optypes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCExecuteOp extends JDBCOp {
private final static Logger logger = LogManager.getLogger(JDBCExecuteOp.class);
public JDBCExecuteOp(Connection connection, Statement statement, String queryString) {
super(connection, statement, queryString);
}
@Override
public void run() {
logger.info(() -> "Executing JDBCExecuteOp for the given cycle.");
try {
this.getConnection().setAutoCommit(false);
if(logger.isDebugEnabled()) {
logger.debug(() -> "JDBC Query is: " + this.getQueryString());
}
boolean isResultSet = this.getStatement().execute(this.getQueryString());
if(isResultSet) {
logger.info(() -> ">>>>>>>>>>Executed a SELECT operation [" + this.getQueryString() + "]<<<<<<<<<<");
} else if(!isResultSet) {
logger.info(() -> {
try {
return ">>>>>>>>>>Executed a normal DDL/DML (non-SELECT) operation [" + this.getStatement().getUpdateCount() + "]<<<<<<<<<<";
} catch (SQLException e) {
String err_msg = "Exception occurred while attempting to fetch the update count of the query operation";
logger.error(err_msg, e);
throw new RuntimeException(err_msg, e);
}
});
} else if (logger.isDebugEnabled()) {
int countResults = 0;
ResultSet rs = this.getStatement().getResultSet();
countResults += rs.getRow();
while(!this.getStatement().getMoreResults() && 0 < this.getStatement().getUpdateCount()) {
rs = this.getStatement().getResultSet();
countResults += rs.getRow();
//rs.close(); Optional as getMoreResults() will already close it.
}
int finalCountResults = countResults;
logger.debug(() -> ">>>>>>>>>>Total number of rows processed is [" + finalCountResults + "]<<<<<<<<<<");
}
this.getConnection().commit();
logger.info(() -> "Executed the JDBC statement & committed the connection successfully");
} catch (SQLException sqlException) {
logger.error("ERROR: { state => {}, cause => {}, message => {} }\n",
sqlException.getSQLState(), sqlException.getCause(), sqlException.getMessage(), sqlException);
throw new RuntimeException(sqlException);
} catch (Exception ex) {
String exMsg = String.format("Exception while attempting to run the jdbc statement %s", getStatement());
logger.error(exMsg, ex);
throw new RuntimeException(exMsg, ex);
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.optypes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCExecuteQueryOp extends JDBCOp {
private final static Logger logger = LogManager.getLogger(JDBCExecuteQueryOp.class);
public JDBCExecuteQueryOp(Connection connection, Statement statement, String queryString) {
super(connection, statement, queryString);
}
@Override
public void run() {
logger.debug(() -> "Executing JDBCExecuteQueryOp for the given cycle.");
try {
this.getConnection().setAutoCommit(false);
logger.debug(() -> "JDBC Query is: " + this.getQueryString());
ResultSet resultSet = this.getStatement().executeQuery(this.getQueryString());
this.getConnection().commit();
logger.debug(() -> "Executed the JDBC statement & committed the connection successfully fetching a total of "+ resultSet.toString() + " records.");
} catch (SQLException sqlException) {
logger.error("JDBCExecuteQueryOp ERROR: { state => {}, cause => {}, message => {} }\n",
sqlException.getSQLState(), sqlException.getCause(), sqlException.getMessage(), sqlException);
throw new RuntimeException(sqlException);
} catch (Exception ex) {
String exMsg = String.format("Exception while attempting to run the jdbc statement %s", getStatement());
logger.error(exMsg, ex);
throw new RuntimeException(exMsg, ex);
}
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.optypes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCExecuteUpdateOp extends JDBCOp {
private final static Logger logger = LogManager.getLogger(JDBCExecuteUpdateOp.class);
public JDBCExecuteUpdateOp(Connection connection, Statement statement, String queryString) {
super(connection, statement, queryString);
}
@Override
public void run() {
logger.debug(() -> "Executing JDBCExecuteUpdateOp for the given cycle.");
try {
this.getConnection().setAutoCommit(false);
logger.debug(() -> "JDBC Query is: " + this.getQueryString());
int rowsAffected = this.getStatement().executeUpdate(this.getQueryString());
this.getConnection().commit();
logger.debug(() -> "Executed the JDBC statement & committed the connection successfully impacting a total of "+ rowsAffected + " records.");
} catch (SQLException sqlException) {
logger.error("JDBCExecuteUpdateOp ERROR: { state => {}, cause => {}, message => {} }\n",
sqlException.getSQLState(), sqlException.getCause(), sqlException.getMessage(), sqlException);
throw new RuntimeException(sqlException);
} catch (Exception ex) {
String exMsg = String.format("Exception while attempting to run the jdbc statement %s", getStatement());
logger.error(exMsg, ex);
throw new RuntimeException(exMsg, ex);
}
}
}

View File

@ -16,36 +16,34 @@
package io.nosqlbench.adapter.jdbc.optypes;
import io.nosqlbench.adapter.jdbc.JDBCSpace;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.RunnableOp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
/*
/**
* References:
* https://docs.oracle.com/javase/tutorial/jdbc/basics/gettingstarted.html
* https://docs.oracle.com/javase/17/docs/api/java/sql/package-summary.html
* https://docs.oracle.com/en/java/javase/17/docs/api/java.sql/java/sql/package-summary.html
* https://jdbc.postgresql.org/documentation/query/
* https://www.cockroachlabs.com/docs/v22.2/connection-pooling.html
* https://www.cockroachlabs.com/docs/v22.2/connection-parameters#supported-options-parameters
* https://www.cockroachlabs.com/docs/v22.2/sql-statements.html#query-management-statements
* https://docs.yugabyte.com/preview/drivers-orms/java/yugabyte-jdbc/
* @see <a href="https://github.com/brettwooldridge/HikariCP">HikariCP connection pooling</a> for details.
*/
public /*abstract*/ class JDBCOp implements RunnableOp/*CycleOp<Object>*/ {
public abstract class JDBCOp implements RunnableOp/*CycleOp<Object>*/ {
private final static Logger logger = LogManager.getLogger(JDBCOp.class);
protected DataSource dataSource;
private final JDBCSpace jdbcSpace;
public String getTargetStatement() {
return targetStatement;
}
private final Connection connection;
private final Statement statement;
private final String queryString;
private final String targetStatement;
public DataSource getDataSource() {
return dataSource;
}
public JDBCSpace getJdbcSpace() {
return jdbcSpace;
public String getQueryString() {
return queryString;
}
public Connection getConnection() {
@ -56,55 +54,15 @@ public /*abstract*/ class JDBCOp implements RunnableOp/*CycleOp<Object>*/ {
return statement;
}
private final Connection connection;
private final Statement statement;
/**
* Unused.
* @param jdbcSpace
* @param targetStatement
*/
public JDBCOp(JDBCSpace jdbcSpace, String targetStatement) {
//TODO - implement code
//this.dataSource = new HikariDataSource();
this.jdbcSpace = jdbcSpace;
this.targetStatement = targetStatement;
this.connection = null;
this.statement = null;
}
/**
*
* @param connection
* @param statement
* @param targetStatement
* @param queryString
*/
public JDBCOp(Connection connection, Statement statement, String targetStatement) {
public JDBCOp(Connection connection, Statement statement, String queryString) {
this.connection = connection;
this.statement = statement;
this.targetStatement = targetStatement;
this.jdbcSpace = null;
}
@Override
public void run() {
logger.info(() -> "Executing JDBCOp for the given cycle.");
try {
this.getConnection().setAutoCommit(false);
if(logger.isDebugEnabled()) {
logger.debug(() -> "JDBC Query is: " + this.getTargetStatement());
}
this.getStatement().execute(this.getTargetStatement());
this.getConnection().commit();
logger.info(() -> "Executed the JDBC statement & committed the connection successfully");
} catch (SQLException sqlException) {
logger.error("JDBCOp ERROR: { state => %s, cause => %s, message => %s }\n",
sqlException.getSQLState(), sqlException.getCause(), sqlException.getMessage(), sqlException);
throw new RuntimeException(sqlException);
} catch (Exception ex) {
String exMsg = String.format("Exception while attempting to run the jdbc statement %s", getStatement());
logger.error(exMsg, ex);
throw new RuntimeException(exMsg, ex);
}
this.queryString = queryString;
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.adapter.jdbc.optypes;
import io.nosqlbench.adapter.jdbc.JDBCSpace;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.RunnableOp;
public class SelectJDBCOp implements RunnableOp {
public SelectJDBCOp(JDBCSpace jdbcSpace, long cycle) {
super();
}
public SelectJDBCOp() {
}
@Override
public void run() {
}
}

View File

@ -4,7 +4,7 @@ title: jdbc
---
# JDBC driver
This JDBC driver leverages HikariCP for connection pool and works with PostgreSQL. This leverages NoSQLBench based workload generation and performance testing against any PostgreSQL-compatible database cluster. Example: CockroachDB or YugabyteDB (YSQL API).
This JDBC driver leverages [Hikari Connection Pool](https://github.com/brettwooldridge/HikariCP/wiki) for connection pool and works with PostgreSQL®. This leverages NoSQLBench based workload generation and performance testing against any PostgreSQL-compatible database cluster. Example: CockroachDB® or YugabyteDB® (YSQL API).
# Executing JDBC Workload
The following is an example of invoking a JDBC workload.
@ -23,7 +23,11 @@ Other NB engine parameters are straight forward:
* `*.yaml`: the NB jdbc scenario definition workload yaml file
# Configuration
There are three main configuration with which we could issue a query and process the results back based on the [PostgreSQL® Query](https://jdbc.postgresql.org/documentation/query/) pattern.
## Config Sources
* `execute`: This is to issue any DDL statements such `CREATE DATABASE|TABLE` or `DROP DATABASE|TABLE` operations which returns nothing.
* `executeUpdate`: This is to issue DML statements such as `INSERT|UPDATE|DELETE` operations that will return how many number of rows were affected by that operation.
* `executeQuery`: This is to issue DML statement such as `SELECT` operation which would return a `ResultSet` object to process.
### Examples

View File

@ -186,7 +186,7 @@
</developer>
<developer>
<name>Madhavan S.</name>
<email>madhavan_5k@yahoo.com</email>
<url>https://github.com/msmygit</url>
<organization>nosqlbench.io</organization>
<organizationUrl>http://nosqlbench.io/</organizationUrl>
</developer>