Skip to content

Commit

Permalink
#38 - Add Cockroach DB detection
Browse files Browse the repository at this point in the history
Refactor extract method ensuring we close resources
  • Loading branch information
rbygrave committed Mar 7, 2018
1 parent 4dacec2 commit 058fa83
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 17 deletions.
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down
53 changes: 36 additions & 17 deletions src/main/java/io/ebean/migration/DbNameUtil.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package io.ebean.migration;

import io.ebean.migration.util.JdbcClose;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* Derive well known database platform names from JDBC MetaData.
*/
class DbNameUtil implements DbPlatformNames {

private static final Logger log = LoggerFactory.getLogger(DbNameUtil.class);

/**
* Normalise the database product/platform name.
*
Expand All @@ -18,23 +26,7 @@ static String normalise(Connection connection) {
try {
final String productName = connection.getMetaData().getDatabaseProductName().toLowerCase();
if (productName.contains(POSTGRES)) {
// PostgreSQL driver use a non-trustable hardcoded product name.
// The following block try to retrieve DBMS version to determine
// if used DBMS is PostgreSQL or Cockroach.
try {
final String productVersion = connection
.prepareStatement("SELECT version() AS \"version\"")
.executeQuery()
.getString("version")
.toLowerCase();
if (productVersion.contains("cockroach")) {
return COCKROACH;
}
} catch (final java.sql.SQLException ignore) {
}

// Real PostgreSQL DB
return POSTGRES;
return readPostgres(connection);
} else if (productName.contains(MYSQL)) {
return MYSQL;
} else if (productName.contains(ORACLE)) {
Expand All @@ -58,4 +50,31 @@ static String normalise(Connection connection) {
return "";
}
}

private static String readPostgres(Connection connection) {
// PostgreSQL driver use a non-trustable hardcoded product name.
// The following block try to retrieve DBMS version to determine
// if used DBMS is PostgreSQL or Cockroach.
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
statement = connection.prepareStatement("SELECT version() AS \"version\"");
resultSet = statement.executeQuery();
if (resultSet.next()) {
String productVersion = resultSet.getString("version").toLowerCase();
if (productVersion.contains("cockroach")) {
return COCKROACH;
}
}
} catch (SQLException e) {
log.warn("Error running detection query on Postgres", e);

} finally {
JdbcClose.close(resultSet);
JdbcClose.close(statement);
}

// Real PostgreSQL DB
return POSTGRES;
}
}
62 changes: 62 additions & 0 deletions src/test/java/io/ebean/migration/DbNameUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.ebean.migration;

import jdk.nashorn.internal.ir.annotations.Ignore;
import org.testng.annotations.Test;

import java.sql.Connection;
import java.sql.SQLException;

import static org.assertj.core.api.Assertions.assertThat;

public class DbNameUtilTest {

/**
* Run manually against Postgres database.
*/
@Ignore
@Test
public void normalise_when_realPostgres() throws SQLException {

MigrationConfig config = createConfig();
// assumes DB unit exists on our local postgres database
config.setDbUrl("jdbc:postgresql://127.0.0.1:5432/unit");

try (Connection connection = config.createConnection()) {
String platformName = DbNameUtil.normalise(connection);

assertThat(platformName).isEqualTo("postgres");
} catch (SQLException e) {
throw e;
}
}

/**
* Run manually against cockroach database.
*/
@Ignore
@Test
public void normalise_when_cockroach() throws SQLException {

MigrationConfig config = createConfig();
// assumes DB unit exists on our local cockroach database
config.setDbUrl("jdbc:postgresql://127.0.0.1:26257/unit");

try (Connection connection = config.createConnection()) {
String platformName = DbNameUtil.normalise(connection);
assertThat(platformName).isEqualTo("cockroach");
} catch (SQLException e) {
throw e;
}
}

/**
* Assumes a DB user unit exists on the databases.
*/
private MigrationConfig createConfig() {
MigrationConfig config = new MigrationConfig();
config.setDbUsername("unit");
config.setDbPassword("unit");
config.setDbDriver("org.postgresql.Driver");
return config;
}
}

0 comments on commit 058fa83

Please sign in to comment.