Skip to content

Commit bdc601b

Browse files
Merge pull request #54 from david-ch/duckdb_support
DuckDB support
2 parents 6391e82 + 946b7df commit bdc601b

File tree

17 files changed

+861
-0
lines changed

17 files changed

+861
-0
lines changed

flyway-database-duckdb/pom.xml

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright (C) Red Gate Software Ltd 2010-2024
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0"
20+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22+
<modelVersion>4.0.0</modelVersion>
23+
<parent>
24+
<groupId>org.flywaydb</groupId>
25+
<artifactId>flyway-community-db-support</artifactId>
26+
<version>10.16.0</version>
27+
</parent>
28+
29+
<artifactId>flyway-database-duckdb</artifactId>
30+
<name>${project.artifactId}</name>
31+
32+
<dependencyManagement>
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.junit</groupId>
36+
<artifactId>junit-bom</artifactId>
37+
<version>5.11.0</version>
38+
<type>pom</type>
39+
<scope>import</scope>
40+
</dependency>
41+
</dependencies>
42+
</dependencyManagement>
43+
44+
<dependencies>
45+
<dependency>
46+
<groupId>${project.groupId}</groupId>
47+
<artifactId>flyway-core</artifactId>
48+
</dependency>
49+
50+
<dependency>
51+
<groupId>org.junit.jupiter</groupId>
52+
<artifactId>junit-jupiter</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.duckdb</groupId>
57+
<artifactId>duckdb_jdbc</artifactId>
58+
<version>1.0.0</version>
59+
<scope>test</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.assertj</groupId>
63+
<artifactId>assertj-core</artifactId>
64+
<version>3.26.3</version>
65+
<scope>test</scope>
66+
</dependency>
67+
</dependencies>
68+
69+
<build>
70+
<resources>
71+
<resource>
72+
<directory>src/main/resources</directory>
73+
<filtering>true</filtering>
74+
</resource>
75+
</resources>
76+
<plugins>
77+
<plugin>
78+
<artifactId>maven-resources-plugin</artifactId>
79+
</plugin>
80+
<plugin>
81+
<artifactId>maven-jar-plugin</artifactId>
82+
</plugin>
83+
<plugin>
84+
<artifactId>maven-surefire-plugin</artifactId>
85+
<version>3.3.1</version>
86+
</plugin>
87+
</plugins>
88+
</build>
89+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*-
2+
* ========================LICENSE_START=================================
3+
* flyway-database-duckdb
4+
* ========================================================================
5+
* Copyright (C) 2010 - 2025 Red Gate Software Ltd
6+
* ========================================================================
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* =========================LICENSE_END==================================
19+
*/
20+
package org.flywaydb.community.database;
21+
22+
import org.flywaydb.core.api.FlywayException;
23+
import org.flywaydb.core.extensibility.PluginMetadata;
24+
import org.flywaydb.core.internal.util.FileUtils;
25+
26+
import java.io.IOException;
27+
import java.nio.charset.StandardCharsets;
28+
29+
public class DuckDBDatabaseExtension implements PluginMetadata {
30+
31+
public String getDescription() {
32+
return "Community-contributed DuckDB database support extension " + readVersion() + " by Redgate";
33+
}
34+
35+
public static String readVersion() {
36+
try {
37+
return FileUtils.copyToString(
38+
DuckDBDatabaseExtension.class.getClassLoader().getResourceAsStream("org/flywaydb/community/database/duckdb/version.txt"),
39+
StandardCharsets.UTF_8);
40+
} catch (IOException e) {
41+
throw new FlywayException("Unable to read extension version: " + e.getMessage(), e);
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*-
2+
* ========================LICENSE_START=================================
3+
* flyway-database-duckdb
4+
* ========================================================================
5+
* Copyright (C) 2010 - 2025 Red Gate Software Ltd
6+
* ========================================================================
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* =========================LICENSE_END==================================
19+
*/
20+
package org.flywaydb.community.database.duckdb;
21+
22+
import org.flywaydb.core.internal.database.base.Connection;
23+
24+
import java.sql.SQLException;
25+
26+
public class DuckDBConnection extends Connection<DuckDBDatabase> {
27+
28+
protected DuckDBConnection(DuckDBDatabase database, java.sql.Connection connection) {
29+
super(database, connection);
30+
}
31+
32+
@Override
33+
protected String getCurrentSchemaNameOrSearchPath() throws SQLException {
34+
return jdbcTemplate.queryForString("SELECT current_schema()");
35+
}
36+
37+
@Override
38+
public void doChangeCurrentSchemaOrSearchPathTo(String schema) throws SQLException {
39+
final var sql = "USE %s;".formatted(schema);
40+
jdbcTemplate.execute(sql);
41+
}
42+
43+
@Override
44+
public DuckDBSchema getSchema(String name) {
45+
return new DuckDBSchema(jdbcTemplate, database, name);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*-
2+
* ========================LICENSE_START=================================
3+
* flyway-database-duckdb
4+
* ========================================================================
5+
* Copyright (C) 2010 - 2025 Red Gate Software Ltd
6+
* ========================================================================
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* =========================LICENSE_END==================================
19+
*/
20+
package org.flywaydb.community.database.duckdb;
21+
22+
import org.flywaydb.core.api.configuration.Configuration;
23+
import org.flywaydb.core.internal.database.base.Database;
24+
import org.flywaydb.core.internal.database.base.Table;
25+
import org.flywaydb.core.internal.jdbc.JdbcConnectionFactory;
26+
import org.flywaydb.core.internal.jdbc.StatementInterceptor;
27+
28+
public class DuckDBDatabase extends Database<DuckDBConnection> {
29+
30+
public DuckDBDatabase(Configuration configuration, JdbcConnectionFactory jdbcConnectionFactory, StatementInterceptor statementInterceptor) {
31+
super(configuration, jdbcConnectionFactory, statementInterceptor);
32+
}
33+
34+
@Override
35+
protected DuckDBConnection doGetConnection(java.sql.Connection connection) {
36+
return new DuckDBConnection(this, connection);
37+
}
38+
39+
@Override
40+
public void ensureSupported(Configuration configuration) {
41+
}
42+
43+
@Override
44+
public boolean supportsDdlTransactions() {
45+
return true;
46+
}
47+
48+
@Override
49+
public String getBooleanTrue() {
50+
return "true";
51+
}
52+
53+
@Override
54+
public String getBooleanFalse() {
55+
return "false";
56+
}
57+
58+
@Override
59+
public boolean catalogIsSchema() {
60+
return false;
61+
}
62+
63+
@Override
64+
public String getRawCreateScript(Table table, boolean baseline) {
65+
final var createTable = """
66+
CREATE TABLE %s (
67+
installed_rank INTEGER NOT NULL,
68+
version VARCHAR,
69+
description VARCHAR NOT NULL,
70+
type VARCHAR NOT NULL,
71+
script VARCHAR NOT NULL,
72+
checksum INTEGER,
73+
installed_by VARCHAR NOT NULL,
74+
installed_on TIMESTAMP NOT NULL DEFAULT now(),
75+
execution_time INTEGER NOT NULL,
76+
success BOOLEAN NOT NULL
77+
);
78+
""".formatted(table);
79+
final var baselineStatement = baseline ? getBaselineStatement(table) + ";\n" : "";
80+
81+
return createTable + baselineStatement;
82+
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*-
2+
* ========================LICENSE_START=================================
3+
* flyway-database-duckdb
4+
* ========================================================================
5+
* Copyright (C) 2010 - 2025 Red Gate Software Ltd
6+
* ========================================================================
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* =========================LICENSE_END==================================
19+
*/
20+
package org.flywaydb.community.database.duckdb;
21+
22+
import org.flywaydb.community.database.DuckDBDatabaseExtension;
23+
import org.flywaydb.core.api.ResourceProvider;
24+
import org.flywaydb.core.api.configuration.Configuration;
25+
import org.flywaydb.core.internal.database.base.BaseDatabaseType;
26+
import org.flywaydb.core.internal.database.base.CommunityDatabaseType;
27+
import org.flywaydb.core.internal.jdbc.JdbcConnectionFactory;
28+
import org.flywaydb.core.internal.jdbc.StatementInterceptor;
29+
import org.flywaydb.core.internal.parser.Parser;
30+
import org.flywaydb.core.internal.parser.ParsingContext;
31+
32+
import java.sql.Connection;
33+
34+
public class DuckDBDatabaseType extends BaseDatabaseType implements CommunityDatabaseType {
35+
36+
@Override
37+
public String getName() {
38+
return "DuckDB";
39+
}
40+
41+
@Override
42+
public int getNullType() {
43+
return 0;
44+
}
45+
46+
@Override
47+
public boolean handlesJDBCUrl(String url) {
48+
return url.startsWith("jdbc:duckdb:");
49+
}
50+
51+
@Override
52+
public String getDriverClass(String url, ClassLoader classLoader) {
53+
return "org.duckdb.DuckDBDriver";
54+
}
55+
56+
@Override
57+
public boolean handlesDatabaseProductNameAndVersion(String databaseProductName, String databaseProductVersion, Connection connection) {
58+
return databaseProductName.startsWith("DuckDB");
59+
}
60+
61+
@Override
62+
public DuckDBDatabase createDatabase(Configuration configuration, JdbcConnectionFactory jdbcConnectionFactory, StatementInterceptor statementInterceptor) {
63+
return new DuckDBDatabase(configuration, jdbcConnectionFactory, statementInterceptor);
64+
}
65+
66+
@Override
67+
public Parser createParser(Configuration configuration, ResourceProvider resourceProvider, ParsingContext parsingContext) {
68+
return new DuckDBParser(configuration, parsingContext);
69+
}
70+
71+
@Override
72+
public String getPluginVersion(Configuration config) {
73+
return DuckDBDatabaseExtension.readVersion();
74+
}
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*-
2+
* ========================LICENSE_START=================================
3+
* flyway-database-duckdb
4+
* ========================================================================
5+
* Copyright (C) 2010 - 2025 Red Gate Software Ltd
6+
* ========================================================================
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* =========================LICENSE_END==================================
19+
*/
20+
package org.flywaydb.community.database.duckdb;
21+
22+
import org.flywaydb.core.api.configuration.Configuration;
23+
import org.flywaydb.core.internal.parser.Parser;
24+
import org.flywaydb.core.internal.parser.ParsingContext;
25+
26+
public class DuckDBParser extends Parser {
27+
28+
protected DuckDBParser(Configuration configuration, ParsingContext parsingContext) {
29+
super(configuration, parsingContext, 2);
30+
}
31+
}

0 commit comments

Comments
 (0)