Skip to content

Commit

Permalink
Make TimescaleDB available with JDBC syntax #3890
Browse files Browse the repository at this point in the history
The Syntax for the use of a TimescaleDB Testcontainer should be jdbc:tc:timescaledb:///databasename or jdbc:tc:timescaledb:2.1.0-pg13:///databasename if a Tag is given. This should allow the user to use the container without any further configuration.
  • Loading branch information
raynigon committed Mar 17, 2021
1 parent 63692d3 commit 07d5d3b
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/modules/databases/jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database

`jdbc:tc:postgis:9.6:///databasename`

#### Using TimescaleDB

`jdbc:tc:timescaldb:2.1.0-pg13:///databasename`

#### Using Presto

`jdbc:tc:presto:329://localhost/memory/default`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.testcontainers.containers;

import org.testcontainers.jdbc.ConnectionUrl;
import org.testcontainers.utility.DockerImageName;

/**
* Factory for PostGIS containers, which are a special flavour of PostgreSQL.
*/
public class TimescaleDBContainerProvider extends JdbcDatabaseContainerProvider {

private static final String NAME = "timescaledb";
private static final String DEFAULT_TAG = "2.1.0-pg11";
private static final String DEFAULT_IMAGE = "timescale/timescaledb";
public static final String USER_PARAM = "user";
public static final String PASSWORD_PARAM = "password";


@Override
public boolean supports(String databaseType) {
return databaseType.equals(NAME);
}

@Override
public JdbcDatabaseContainer newInstance() {
return newInstance(DEFAULT_TAG);
}

@Override
public JdbcDatabaseContainer newInstance(String tag) {
return new PostgreSQLContainer(DockerImageName.parse(DEFAULT_IMAGE).withTag(DEFAULT_TAG));
}

@Override
public JdbcDatabaseContainer newInstance(ConnectionUrl connectionUrl) {
return newInstanceFromConnectionUrl(connectionUrl, USER_PARAM, PASSWORD_PARAM);
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
org.testcontainers.containers.PostgreSQLContainerProvider
org.testcontainers.containers.PostgisContainerProvider
org.testcontainers.containers.TimescaleDBContainerProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.testcontainers.containers;

import org.junit.Test;
import org.testcontainers.db.AbstractContainerDatabaseTest;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.LogManager;

import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;
import static org.rnorth.visibleassertions.VisibleAssertions.assertNotEquals;

public class TimescaleDBContainerTest extends AbstractContainerDatabaseTest {

@Test
public void testSimple() throws SQLException {
try (JdbcDatabaseContainer<?> postgres = new TimescaleDBContainerProvider().newInstance()) {
postgres.start();

ResultSet resultSet = performQuery(postgres, "SELECT 1");
int resultSetInt = resultSet.getInt(1);
assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
}
}

@Test
public void testCommandOverride() throws SQLException {
try (GenericContainer<?> postgres = new TimescaleDBContainerProvider().newInstance().withCommand("postgres -c max_connections=42")) {
postgres.start();

ResultSet resultSet = performQuery((JdbcDatabaseContainer<?>) postgres, "SELECT current_setting('max_connections')");
String result = resultSet.getString(1);
assertEquals("max_connections should be overriden", "42", result);
}
}

@Test
public void testUnsetCommand() throws SQLException {
try (GenericContainer<?> postgres = new TimescaleDBContainerProvider().newInstance().withCommand("postgres -c max_connections=42").withCommand()) {
postgres.start();

ResultSet resultSet = performQuery((JdbcDatabaseContainer<?>) postgres, "SELECT current_setting('max_connections')");
String result = resultSet.getString(1);
assertNotEquals("max_connections should not be overriden", "42", result);
}
}

@Test
public void testExplicitInitScript() throws SQLException {
try (JdbcDatabaseContainer<?> postgres = new TimescaleDBContainerProvider().newInstance().withInitScript("somepath/init_timescaledb.sql")) {
postgres.start();

ResultSet resultSet = performQuery(postgres, "SELECT foo FROM bar");

String firstColumnValue = resultSet.getString(1);
assertEquals("Value from init script should equal real value", "hello world", firstColumnValue);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.testcontainers.jdbc.timescaledb;

import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.testcontainers.jdbc.AbstractJDBCDriverTest;

import java.util.EnumSet;

import static java.util.Arrays.asList;

@RunWith(Parameterized.class)
public class TimescaleDBJDBCDriverTest extends AbstractJDBCDriverTest {

@Parameterized.Parameters(name = "{index} - {0}")
public static Iterable<Object[]> data() {
return asList(
new Object[][]{
{"jdbc:tc:timescaledb://hostname/databasename?user=someuser&password=somepwd", EnumSet.of(Options.JDBCParams)},
{"jdbc:tc:timescaledb:2.1.0-pg13://hostname/databasename?user=someuser&password=somepwd", EnumSet.of(Options.JDBCParams)},
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- Extend the database with TimescaleDB
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;

CREATE TABLE bar (
foo VARCHAR(255),
time TIMESTAMPTZ NOT NULL
);

SELECT create_hypertable('bar', 'time');

INSERT INTO bar (time, foo) VALUES (CURRENT_TIMESTAMP, 'hello world');

0 comments on commit 07d5d3b

Please sign in to comment.