Quarkus JDBC Sqlite

Quarkus SQLite4j is a Quarkus extension for the SQLite database.

Installation

If you want to use this extension, you need to add the io.quarkiverse.jdbc:quarkus-jdbc-sqlite4j extension first.

For instance, in your pom.xml file, add the following dependency:

<dependency>
    <groupId>io.quarkiverse.jdbc</groupId>
    <artifactId>quarkus-jdbc-sqlite4j</artifactId>
    <version>0.0.5</version>
</dependency>

Tl;DR: Suggested Usage

For an effective usage of this extension we suggest this configuration parameters:

quarkus.datasource.db-kind=sqlite # select this jdbc driver
quarkus.datasource.jdbc.url=jdbc:sqlite:mydb.sqlite # mydb.sqlite is the relative path of the DB file you want to use
quarkus.datasource.jdbc.min-size=1 # avoid additional readings from disk to memory of the DB

To have a scheduled backup of the DB back to the disk you can use a scheduled job like:

@ApplicationScoped
public class SQLiteBackup {

    private static final Logger LOGGER = Logger.getLogger(SQLiteBackup.class.getName());

    @ConfigProperty(name = "quarkus.datasource.jdbc.url")
    String jdbcUrl;

    @Inject
    AgroalDataSource dataSource;

    private final AtomicBoolean executing = new AtomicBoolean(false);

    // Execute a backup every 10 seconds
    @Scheduled(delay=10, delayUnit=TimeUnit.SECONDS, every="10s")
    void scheduled() {
        backup();
    }

    // Execute a backup during shutdown
    public void onShutdown(@Observes ShutdownEvent event) {
        backup();
    }

    void backup() {
        if (executing.compareAndSet(false, true)) {
            try {
                int prefixLength = "jdbc:sqlite:".length();
                int queryParamsIdx = jdbcUrl.indexOf('?');
                int length = (queryParamsIdx != -1) ? queryParamsIdx : jdbcUrl.length();
                String dbFile = jdbcUrl.substring(prefixLength, length);

                var originalDbFilePath = Paths.get(dbFile);
                LOGGER.info("Starting DB backup for file: " + dbFile);
                var backupDbFilePath = originalDbFilePath.toAbsolutePath().getParent().resolve(originalDbFilePath.getFileName() + "_backup");

                try (var conn = dataSource.getConnection();
                     var stmt = conn.createStatement()) {
                    // Execute the backup
                    stmt.executeUpdate("backup to " + backupDbFilePath);
                    // Atomically substitute the DB file with its backup
                    Files.move(backupDbFilePath, originalDbFilePath, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
                } catch (SQLException e) {
                    throw new RuntimeException("Failed to backup the database", e);
                } catch (IOException e) {
                    throw new RuntimeException("Failed to create backup files or folders", e);
                }
                LOGGER.info("Backup of " + dbFile + " completed.");
            } finally {
                executing.set(false);
            }
        } else {
            LOGGER.info("Backup in progress.");
        }
    }
}

Configuration

You can find more information about how to configure the datasource here.