Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,28 @@ public class ThingStoreProviderConfig {
public static final String DEFAULT_REPOSITORY_MODE = "memory";
public static final String ARG_REPOSITORY_MODE = "-thingifier-repository";
public static final String ARG_SQLITE_DIRECTORY = "-thingifier-sqlite-directory";
public static final String ARG_SQLITE_FILE = "-thingifier-sqlite-file";
public static final String ARG_SQLITE_MEMORY = "-sqlite-memory";
public static final String ENV_REPOSITORY_MODE = "THINGIFIER_REPOSITORY";
public static final String ENV_SQLITE_DIRECTORY = "THINGIFIER_SQLITE_DIRECTORY";
public static final String ENV_SQLITE_FILE = "THINGIFIER_SQLITE_FILE";
public static final String PROPERTY_REPOSITORY_MODE = "thingifier.repository";
public static final String PROPERTY_SQLITE_DIRECTORY = "thingifier.sqlite.directory";
public static final String PROPERTY_SQLITE_FILE = "thingifier.sqlite.file";

private final String repositoryMode;
private final Path sqliteDirectory;
private final Path sqliteFile;

public ThingStoreProviderConfig(final String repositoryMode, final Path sqliteDirectory) {
this(repositoryMode, sqliteDirectory, null);
}

public ThingStoreProviderConfig(
final String repositoryMode, final Path sqliteDirectory, final Path sqliteFile) {
this.repositoryMode = normalize(repositoryMode);
this.sqliteDirectory = sqliteDirectory;
this.sqliteFile = sqliteFile;
}

public static ThingStoreProviderConfig fromArgs(final String[] args) {
Expand All @@ -44,7 +54,16 @@ public static ThingStoreProviderConfig fromArgs(final String[] args) {
System.getenv(ENV_SQLITE_DIRECTORY),
"thingifier-sqlite");

return new ThingStoreProviderConfig(repositoryMode, Paths.get(sqliteDirectory));
String sqliteFile =
firstNonBlank(
argValue(args, ARG_SQLITE_FILE),
System.getProperty(PROPERTY_SQLITE_FILE),
System.getenv(ENV_SQLITE_FILE));

return new ThingStoreProviderConfig(
repositoryMode,
Paths.get(sqliteDirectory),
sqliteFile.isEmpty() ? null : Paths.get(sqliteFile));
}

public ThingStoreProvider createProvider() {
Expand All @@ -60,6 +79,9 @@ public ThingStoreProvider createProvider() {
case "sqlite-file":
case "sqlite-disk":
case "file":
if (sqliteFile != null) {
return SqliteThingStoreProvider.fileBackedFile(sqliteFile);
}
return SqliteThingStoreProvider.fileBacked(sqliteDirectory);
default:
throw new IllegalArgumentException(
Expand All @@ -77,10 +99,21 @@ public Path getSqliteDirectory() {
return sqliteDirectory;
}

public Path getSqliteFile() {
return sqliteFile;
}

public boolean hasSqliteFile() {
return sqliteFile != null;
}

public String describe() {
if (repositoryMode.equals("sqlite-file")
|| repositoryMode.equals("sqlite-disk")
|| repositoryMode.equals("file")) {
if (sqliteFile != null) {
return repositoryMode + " at " + sqliteFile.toAbsolutePath();
}
return repositoryMode + " at " + sqliteDirectory.toAbsolutePath();
}
return repositoryMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ public static SqliteThingStoreProvider fileBacked(final Path directory) {
});
}

public static SqliteThingStoreProvider fileBackedFile(final Path databaseFile) {
final Path normalized = databaseFile.toAbsolutePath().normalize();
final Path parent = normalized.getParent();
if (parent != null) {
try {
Files.createDirectories(parent);
} catch (IOException e) {
throw new IllegalStateException(
"Could not create SQLite repository directory " + parent, e);
}
}

return new SqliteThingStoreProvider(
databaseKey ->
"jdbc:sqlite:"
+ databaseFileFor(normalized, databaseKey)
.toAbsolutePath()
.toString()
.replace("\\", "/"));
}

@Override
public ThingStore getDefaultStore() {
return repositories.get(EntityRelModel.DEFAULT_DATABASE_NAME);
Expand Down Expand Up @@ -106,4 +127,18 @@ public void deleteStore(final String databaseKey) {
private static String safeName(final String databaseKey) {
return databaseKey.replaceAll("[^A-Za-z0-9._-]", "_");
}

private static Path databaseFileFor(final Path databaseFile, final String databaseKey) {
if (EntityRelModel.DEFAULT_DATABASE_NAME.equals(databaseKey)) {
return databaseFile;
}

final Path parent = databaseFile.getParent();
final String fileName = databaseFile.getFileName().toString();
final int extensionAt = fileName.lastIndexOf(".");
final String baseName = extensionAt > 0 ? fileName.substring(0, extensionAt) : fileName;
final String extension = extensionAt > 0 ? fileName.substring(extensionAt) : ".sqlite";
final String sessionFileName = baseName + "-" + safeName(databaseKey) + extension;
return parent == null ? Path.of(sessionFileName) : parent.resolve(sessionFileName);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.co.compendiumdev.thingifier.core.repository;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -58,6 +59,34 @@ public void sqliteProviderKeepsLogicalDatabasesSeparate() {
}
}

@Test
public void directSqliteFileProviderCreatesAndReopensDatabaseFile() {
ERSchema schema = todoSchema();
Path databasePath = tempDir.resolve("direct-provider.sqlite");

try (ThingStoreProvider provider = SqliteThingStoreProvider.fileBackedFile(databasePath)) {
ThingStore store = provider.getDefaultStore();
store.administration().initializeFrom(schema);
create(store, schema.getEntityDefinitionNamed("project"), "File provider");
}

Assertions.assertTrue(Files.exists(databasePath));

try (ThingStoreProvider reopened = SqliteThingStoreProvider.fileBackedFile(databasePath)) {
ThingStore store = reopened.getDefaultStore();
store.administration().initializeFrom(schema);

Assertions.assertEquals(
1, store.entityQueries().count(schema.getEntityDefinitionNamed("project")));
Assertions.assertEquals(
"File provider",
store.entityQueries()
.findByPrimaryKey(schema.getEntityDefinitionNamed("project"), "1")
.getFieldValue("title")
.asString());
}
}

@Test
public void inMemoryTransactionCommitPersistsChanges() {
ThingStore repository = new InMemoryThingStore(EntityRelModel.DEFAULT_DATABASE_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ public void canCreateSqliteFileRepositoryFromArgs() {
Assertions.assertTrue(config.createProvider() instanceof SqliteThingStoreProvider);
}

@Test
public void canCreateDirectSqliteFileRepositoryFromArgs() {
Path databaseFile = tempDir.resolve("crud-ui.sqlite");
ThingStoreProviderConfig config =
ThingStoreProviderConfig.fromArgs(
new String[] {
"-thingifier-repository=sqlite-file",
"-thingifier-sqlite-file=" + databaseFile
});

Assertions.assertEquals("sqlite-file", config.getRepositoryMode());
Assertions.assertTrue(config.hasSqliteFile());
Assertions.assertEquals(databaseFile, config.getSqliteFile());
Assertions.assertTrue(config.createProvider() instanceof SqliteThingStoreProvider);
}

@Test
public void rejectsUnknownRepositoryModes() {
ThingStoreProviderConfig config =
Expand Down
68 changes: 68 additions & 0 deletions thingifier-crud-ui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
<name>thingifier crud ui</name>
<url>https://compendiumdev.co.uk</url>

<properties>
<playwright.version>1.61.0</playwright.version>
<crud.ui.headless>true</crud.ui.headless>
<skipITs>false</skipITs>
</properties>

<dependencies>
<dependency>
<groupId>uk.co.compendiumdev</groupId>
Expand Down Expand Up @@ -54,6 +60,12 @@
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>${playwright.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -72,6 +84,62 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>install-playwright-chromium</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<skip>${skipITs}</skip>
<executable>${java.home}/bin/java</executable>
<classpathScope>test</classpathScope>
<arguments>
<argument>-cp</argument>
<classpath/>
<argument>com.microsoft.playwright.CLI</argument>
<argument>install</argument>
<argument>chromium</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<skipITs>${skipITs}</skipITs>
<systemPropertyVariables>
<crud.ui.headless>${crud.ui.headless}</crud.ui.headless>
</systemPropertyVariables>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify-integration-tests</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
Expand Down
Loading
Loading