Skip to content

Commit

Permalink
feat: make JDBC connection URL delimiter configurable
Browse files Browse the repository at this point in the history
Make the JDBC connection URL delimiter configurable. The current
delimiter is semicolon ';', which breaks JDBC drivers that use
semicolons in the actual connection URL. The default delimiter remains
semicolon for all databases, except a list of databases that are known
to use semicolons in the connection URL. Users can always specifiy a
custom delimiter to work around any issues with the default delimiter.

Fixes brianfrankcooper#1458
  • Loading branch information
olavloite committed May 10, 2023
1 parent ce3eb9c commit 1d29925
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
12 changes: 12 additions & 0 deletions jdbc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ db.user=admin
db.passwd=admin
```

You can specify a custom delimiter for multiple connection URLs by setting `db.urldelimiter` if your connection URL might contain a `;`.
The default delimiter is `,` for Google Cloud Spanner, SQLServer, H2, and Apache Phoenix. It is `;` for all
other databases.

```sh
db.driver=com.google.cloud.spanner.jdbc.JdbcDriver
db.url=jdbc:cloudspanner:/projects/my-project/instances/my-instance/databass/my-database;minSessions=1000;maxSessions=1000;numChannels=20
db.urldelimiter=,
db.user=
db.passwd=
```

You can add these to your workload configuration or a separate properties file and specify it with ```-P``` or you can add the properties individually to your ycsb command with ```-p```.

### 5. Add your JDBC Driver to the classpath
Expand Down
14 changes: 13 additions & 1 deletion jdbc/src/main/java/site/ycsb/db/JdbcDBClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public class JdbcDBClient extends DB {
/** The URL to connect to the database. */
public static final String CONNECTION_URL = "db.url";

/** The delimiter that is used to split multiple JDBC connection URLs. */
public static final String CONNECTION_URL_DELIMITER = "db.urldelimiter";

/** The user name to use to connect to the database. */
public static final String CONNECTION_USER = "db.user";

Expand Down Expand Up @@ -188,6 +191,15 @@ public void init() throws DBException {
String passwd = props.getProperty(CONNECTION_PASSWD, DEFAULT_PROP);
String driver = props.getProperty(DRIVER_CLASS);

String defaultDelimiter = ";";
if (driver != null) {
if (driver.contains("spanner") || driver.contains("sqlserver")
|| driver.contains("org.h2.") || driver.contains("phoenix")) {
defaultDelimiter = ",";
}
}
String urlDelimiter = props.getProperty(CONNECTION_URL_DELIMITER, defaultDelimiter);

this.jdbcFetchSize = getIntProperty(props, JDBC_FETCH_SIZE);
this.batchSize = getIntProperty(props, DB_BATCH_SIZE);

Expand Down Expand Up @@ -220,7 +232,7 @@ public void init() throws DBException {
// for a longer explanation see the README.md
// semicolons aren't present in JDBC urls, so we use them to delimit
// multiple JDBC connections to shard across.
final String[] urlArr = urls.split(";");
final String[] urlArr = urls.split(urlDelimiter);
for (String url : urlArr) {
System.out.println("Adding shard node URL: " + url);
Connection conn = DriverManager.getConnection(url, user, passwd);
Expand Down
5 changes: 4 additions & 1 deletion jdbc/src/test/java/site/ycsb/db/JdbcDBClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@

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";
// The 'key=value' part in the connection URL is ignored by hsql. It is added to the URL to
// verify that URLs containing a semicolon work if a custom URL delimiter is set.
private static final String TEST_DB_URL = "jdbc:hsqldb:mem:ycsb;key=value";
private static final String TEST_DB_USER = "sa";
private static final String TABLE_NAME = "USERTABLE";
private static final int FIELD_LENGTH = 32;
Expand Down Expand Up @@ -63,6 +65,7 @@ public static void setupWithBatch(int batchSize, boolean autoCommit) {
p.setProperty(JdbcDBClient.DB_BATCH_SIZE, Integer.toString(batchSize));
p.setProperty(JdbcDBClient.JDBC_BATCH_UPDATES, "true");
p.setProperty(JdbcDBClient.JDBC_AUTO_COMMIT, Boolean.toString(autoCommit));
p.setProperty(JdbcDBClient.CONNECTION_URL_DELIMITER, ",");

jdbcDBClient.setProperties(p);
jdbcDBClient.init();
Expand Down

0 comments on commit 1d29925

Please sign in to comment.