work on db connection basic
This commit is contained in:
parent
1142def290
commit
2fa76d84df
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AskMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Ask2AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="EditMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
16
.idea/kotlinc.xml
generated
Normal file
16
.idea/kotlinc.xml
generated
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Kotlin2JsCompilerArguments">
|
||||||
|
<option name="moduleKind" value="plain" />
|
||||||
|
</component>
|
||||||
|
<component name="Kotlin2JvmCompilerArguments">
|
||||||
|
<option name="jvmTarget" value="1.8" />
|
||||||
|
</component>
|
||||||
|
<component name="KotlinCommonCompilerArguments">
|
||||||
|
<option name="apiVersion" value="2.1" />
|
||||||
|
<option name="languageVersion" value="2.1" />
|
||||||
|
</component>
|
||||||
|
<component name="KotlinJpsPluginSettings">
|
||||||
|
<option name="version" value="2.2.0" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
95
pom.xml
95
pom.xml
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<kotlin.version>2.2.0</kotlin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -24,6 +25,70 @@
|
|||||||
<target>21</target>
|
<target>21</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirs>
|
||||||
|
<source>src/main/java</source>
|
||||||
|
<source>target/generated-sources/annotations</source>
|
||||||
|
</sourceDirs>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirs>
|
||||||
|
<source>src/test/java</source>
|
||||||
|
<source>target/generated-test-sources/test-annotations</source>
|
||||||
|
</sourceDirs>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-compile</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>default-testCompile</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>testCompile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>testCompile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@ -69,6 +134,17 @@
|
|||||||
<version>2.0.16</version>
|
<version>2.0.16</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-scripting-jvm</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-scripting-common</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- TEST -->
|
<!-- TEST -->
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
|
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
|
||||||
@ -78,5 +154,24 @@
|
|||||||
<version>5.13.4</version>
|
<version>5.13.4</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<version>2.3.230</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-test</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@ -22,6 +22,7 @@ public class App {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
db.init();
|
db.init();
|
||||||
|
Migration.of(db).getPendingBaseMigrations().forEach(f -> System.out.println(f.getName()));
|
||||||
|
|
||||||
var app = Javalin.create(cnf -> {});
|
var app = Javalin.create(cnf -> {});
|
||||||
app.before(
|
app.before(
|
||||||
|
|||||||
@ -2,63 +2,95 @@ package dev.mduchene;
|
|||||||
|
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.impl.DSL;
|
||||||
|
import org.jooq.impl.SQLDataType;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.jooq.conf.RenderQuotedNames;
|
||||||
|
import org.jooq.conf.Settings;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
|
||||||
public class Db {
|
public class Db {
|
||||||
private HikariDataSource dataSource;
|
private HikariDataSource dataSource;
|
||||||
private Db() {}
|
private org.jooq.DSLContext dsl;
|
||||||
|
|
||||||
public void init() {
|
private Db() {}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
connection.setAutoCommit(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore if the table already exists
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private String url;
|
||||||
|
private String user;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private Builder() {}
|
||||||
|
|
||||||
|
public static Builder create() {
|
||||||
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public Builder url(String url) {
|
||||||
private String url;
|
this.url = url;
|
||||||
private String user;
|
return this;
|
||||||
private String password;
|
|
||||||
|
|
||||||
private Builder() {}
|
|
||||||
public static Builder create() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder url(String url) {
|
|
||||||
this.url = url;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder user(String user) {
|
|
||||||
this.user = user;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder password(String password) {
|
|
||||||
this.password = password;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Db build() {
|
|
||||||
Db db = new Db();
|
|
||||||
HikariConfig config = new HikariConfig();
|
|
||||||
config.setJdbcUrl(url);
|
|
||||||
config.setUsername(user);
|
|
||||||
config.setPassword(password);
|
|
||||||
config.addDataSourceProperty("cachePrepStmts", "true");
|
|
||||||
config.addDataSourceProperty("prepStmtCacheSize", "250");
|
|
||||||
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
|
||||||
config.setMaximumPoolSize(64);
|
|
||||||
db.dataSource = new HikariDataSource(config);
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection getConnection() throws Exception {
|
public Builder user(String user) {
|
||||||
Connection connection = dataSource.getConnection();
|
this.user = user;
|
||||||
connection.setAutoCommit(false);
|
return this;
|
||||||
return connection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder password(String password) {
|
||||||
|
this.password = password;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Db build() {
|
||||||
|
Db db = new Db();
|
||||||
|
HikariConfig config = new HikariConfig();
|
||||||
|
config.setJdbcUrl(url);
|
||||||
|
config.setUsername(user);
|
||||||
|
config.setPassword(password);
|
||||||
|
config.addDataSourceProperty("cachePrepStmts", "true");
|
||||||
|
config.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||||
|
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||||
|
config.setMaximumPoolSize(64);
|
||||||
|
db.dataSource = new HikariDataSource(config);
|
||||||
|
db.dsl =
|
||||||
|
DSL.using(
|
||||||
|
db.dataSource,
|
||||||
|
SQLDialect.MARIADB,
|
||||||
|
new Settings().withRenderQuotedNames(RenderQuotedNames.NEVER));
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getConnection() throws Exception {
|
||||||
|
Connection connection = dataSource.getConnection();
|
||||||
|
connection.setAutoCommit(false);
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(String query) {
|
||||||
|
try (Connection connection = getConnection()) {
|
||||||
|
dsl.execute(query);
|
||||||
|
connection.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public DSLContext dsl() {
|
||||||
|
return dsl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
src/main/java/dev/mduchene/Migration.java
Normal file
77
src/main/java/dev/mduchene/Migration.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package dev.mduchene;
|
||||||
|
|
||||||
|
import org.jooq.Meta;
|
||||||
|
import org.jooq.impl.DSL;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class Migration {
|
||||||
|
|
||||||
|
private final Db db;
|
||||||
|
|
||||||
|
private Migration(Db db) {
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Migration of(Db db) {
|
||||||
|
return new Migration(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<File> getPendingBaseMigrations() {
|
||||||
|
List<String> ranMigrations = getRanBaseMigrations();
|
||||||
|
List<File> migrations = ResourceFileLister.listFilesInResourceFolder("migrations");
|
||||||
|
return migrations.stream()
|
||||||
|
.filter(file -> !ranMigrations.contains(file.getName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tableExists(String tableName) {
|
||||||
|
// Get the Meta object, which contains all database metadata
|
||||||
|
Meta meta = db.dsl().meta();
|
||||||
|
|
||||||
|
// Use the getTables() method with a filter
|
||||||
|
return meta.getTables(DSL.name("bolts", tableName)).stream()
|
||||||
|
.anyMatch(
|
||||||
|
table ->
|
||||||
|
table.getName().equalsIgnoreCase(tableName)
|
||||||
|
&& table.getSchema().getName().equalsIgnoreCase("bolts"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRanBaseMigrations() {
|
||||||
|
try (Connection connection = db.getConnection()) {
|
||||||
|
boolean migrationsExists = tableExists("_migrations");
|
||||||
|
if (!migrationsExists) return List.of();
|
||||||
|
|
||||||
|
return db.dsl()
|
||||||
|
.select(DSL.field("name"))
|
||||||
|
.from(DSL.table("_migrations"))
|
||||||
|
.where(DSL.field("base").eq(true))
|
||||||
|
.and(DSL.field("executedAt").isNull())
|
||||||
|
.fetch(DSL.field("name"), String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRanMigrations() {
|
||||||
|
try (Connection connection = db.getConnection()) {
|
||||||
|
return db.dsl()
|
||||||
|
.select(DSL.field("name"))
|
||||||
|
.from(DSL.table("_migrations"))
|
||||||
|
.fetch(DSL.field("name"), String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/main/java/dev/mduchene/ResourceFileLister.java
Normal file
37
src/main/java/dev/mduchene/ResourceFileLister.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package dev.mduchene;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ResourceFileLister {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
listFilesInResourceFolder("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<File> listFilesInResourceFolder(String folderName) {
|
||||||
|
ClassLoader classLoader = ResourceFileLister.class.getClassLoader();
|
||||||
|
URL folderUrl = classLoader.getResource(folderName);
|
||||||
|
|
||||||
|
if (folderUrl == null) {
|
||||||
|
throw new IllegalArgumentException("Folder not found: " + folderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Path folderPath = Paths.get(folderUrl.toURI());
|
||||||
|
try (Stream<Path> stream = Files.list(folderPath)) {
|
||||||
|
return stream.filter(Files::isRegularFile).map(Path::toFile).toList();
|
||||||
|
}
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user