Exposed
Exposed copied to clipboard
Support for Testcontainers in JDBC URL
Is it possible to use a testcontainers-targeted JDBC URL? That is, a URL that uses "jdbc:tc:" as the URL scheme/prefix. Also supporting the container target version after the dialect.
For example:
jdbc:tc:postgresql:15.1-alpine:///databasename
I wasn't able to find any docs or issues related to this. Nor could I find any examples of its use with Exposed.
A quick look at the Exposed code seems to indicate it would NOT support this. But I may not have looked close enough.
TIA.
I'm using TC with exposed as the following:
val mysqlContainer = MySQLContainer(DockerImageName.parse("mysql:5.7.34"))
.withDatabaseName("test")
.withUsername("root")
.withPassword("root")
.also { it.start() }
val database = HikariConfig().apply {
it.driverClassName = "org.mariadb.jdbc.Driver"
it.username = this.username
it.password = password
it.jdbcUrl ="jdbc:mariadb://${mysqlContainer.host}:${mysqlContainer.firstMappedPort}/${mysqlContainer.databaseName}"
}.let {
Database.connect(HikariDataSource(it))
}
Yeah. That's one of the ways we did it with the PG container class but required us to know DB type ahead of time.
We ended up using a HikariDataSource directly with:
jdbcUrl = "jdbc:tc:.."
driverClassName = "org.testcontainers.jdbc.ContainerDatabaseDriver"
to give us an auto-detected container type for our needs.
However, having Exposed detect this style of jdbc URL and doing it would be a bonus as we would not need to intercept it to construct things directly. Especially since the ':tc:' URL's are so well defined.
This is more of a wish for an enhancement than anything else.
Hi @ntr-ross , Could you elaborate a bit more on how you'd like that feature to work in general?
Would you invoke something like:
Database.connect(
"jdbc:tc:postgresql:15.1-alpine:///databasename",
user = ...,
password = ...
)
That was the sort of usage we were looking at. Basically the ability to switch to a test container simply by altering the jdbc URL supplied in a config setup.
I don't know the implications but since TC is also an 'interceptor'-style URL (and well-defined) that you could use the presence of 'jdbc:tc:' to determine the need for the TC driver (if it hasn't been specified already) and then use the prefix without the ':tc:' or the version to determine dialect. But that may be over-complicating things.
It was the error when using both the 'jdbc:tc:...' URL and the TC driver
name in the connect()
call that confounded us the most.
As I say in my previous post we got around it by forcing HikariDataSource all the time. But others may trip across this same issue in the future.
@lns-ross Thank you. Would be helpful if you'd take a look at https://github.com/JetBrains/Exposed/pull/1680 and let me know if that solves your issues, as currently I don't have a TestContainers setup.
@AlexeySoshin Thx, that seems like it will work. It is obviously limited to just those two dialects (see below ***).
Not sure if this is what you meant about 'not having a setup', but if you have docker available (local or remote) attached is a minimal gradle project ( test-exposed-tc.zip) that should allow you to test using TC. It tries both the indirect-thru-Hikari mode (which works) and the direct URL mode (which fails).
*** Here's a list of the currently supported containers. Interesting quirk, TC doesn't recognize the 'pgsql' dialect via URL (testcontainers/testcontainers-java#6424) but is quite happy to launch one manually with the appropriate driver using the PostgeSQLContainer
. Go figure.