--- /dev/null
+package org.asamk.signal.manager.storage;
+
+import com.zaxxer.hikari.HikariDataSource;
+
+import org.asamk.signal.manager.storage.sendLog.MessageSendLogStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class AccountDatabase extends Database {
+
+ private final static Logger logger = LoggerFactory.getLogger(AccountDatabase.class);
+ private static final long DATABASE_VERSION = 1;
+
+ private AccountDatabase(final HikariDataSource dataSource) {
+ super(logger, DATABASE_VERSION, dataSource);
+ }
+
+ public static AccountDatabase init(File databaseFile) throws SQLException {
+ return initDatabase(databaseFile, AccountDatabase::new);
+ }
+
+ @Override
+ protected void upgradeDatabase(final Connection connection, final long oldVersion) throws SQLException {
+ if (oldVersion < 1) {
+ logger.debug("Updating database: Creating message send log tables");
+ MessageSendLogStore.createSql(connection);
+ }
+ }
+}
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
-import org.asamk.signal.manager.storage.sendLog.MessageSendLogStore;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sqlite.SQLiteConfig;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.function.Function;
-public class Database implements AutoCloseable {
-
- private final static Logger logger = LoggerFactory.getLogger(SignalAccount.class);
- private static final long DATABASE_VERSION = 1;
+public abstract class Database implements AutoCloseable {
+ private final Logger logger;
+ private final long databaseVersion;
private final HikariDataSource dataSource;
- private Database(final HikariDataSource dataSource) {
+ protected Database(final Logger logger, final long databaseVersion, final HikariDataSource dataSource) {
+ this.logger = logger;
+ this.databaseVersion = databaseVersion;
this.dataSource = dataSource;
}
- public static Database init(File databaseFile) throws SQLException {
+ public static <T extends Database> T initDatabase(
+ File databaseFile, Function<HikariDataSource, T> newDatabase
+ ) throws SQLException {
HikariDataSource dataSource = null;
try {
dataSource = getHikariDataSource(databaseFile.getAbsolutePath());
- try (final var connection = dataSource.getConnection()) {
- final var userVersion = getUserVersion(connection);
- logger.trace("Current database version: {} Program database version: {}",
- userVersion,
- DATABASE_VERSION);
-
- if (userVersion > DATABASE_VERSION) {
- logger.error("Database has been updated by a newer signal-cli version");
- throw new SQLException("Database has been updated by a newer signal-cli version");
- } else if (userVersion < DATABASE_VERSION) {
- if (userVersion < 1) {
- logger.debug("Updating database: Creating message send log tables");
- MessageSendLogStore.createSql(connection);
- }
- setUserVersion(connection, DATABASE_VERSION);
- }
-
- final var result = new Database(dataSource);
- dataSource = null;
- return result;
- }
+ final var result = newDatabase.apply(dataSource);
+ result.initDb();
+ dataSource = null;
+ return result;
} finally {
if (dataSource != null) {
dataSource.close();
}
}
- public Connection getConnection() throws SQLException {
+ public final Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
dataSource.close();
}
+ protected final void initDb() throws SQLException {
+ try (final var connection = dataSource.getConnection()) {
+ final var userVersion = getUserVersion(connection);
+ logger.trace("Current database version: {} Program database version: {}", userVersion, databaseVersion);
+
+ if (userVersion > databaseVersion) {
+ logger.error("Database has been updated by a newer signal-cli version");
+ throw new SQLException("Database has been updated by a newer signal-cli version");
+ } else if (userVersion < databaseVersion) {
+ upgradeDatabase(connection, userVersion);
+ setUserVersion(connection, databaseVersion);
+ }
+ }
+ }
+
+ protected abstract void upgradeDatabase(final Connection connection, long oldVersion) throws SQLException;
+
private static long getUserVersion(final Connection connection) throws SQLException {
try (final var statement = connection.createStatement()) {
final var resultSet = statement.executeQuery("PRAGMA user_version");
private MessageCache messageCache;
private MessageSendLogStore messageSendLogStore;
- private Database database;
+ private AccountDatabase accountDatabase;
private SignalAccount(final FileChannel fileChannel, final FileLock lock) {
this.fileChannel = fileChannel;
}
public void initDatabase() {
- getDatabase();
+ getAccountDatabase();
}
private void clearAllPreKeys() {
() -> messageCache = new MessageCache(getMessageCachePath(dataPath, account)));
}
- public Database getDatabase() {
- return getOrCreate(() -> database, () -> {
+ public AccountDatabase getAccountDatabase() {
+ return getOrCreate(() -> accountDatabase, () -> {
try {
- database = Database.init(getDatabaseFile(dataPath, account));
+ accountDatabase = AccountDatabase.init(getDatabaseFile(dataPath, account));
} catch (SQLException e) {
throw new RuntimeException(e);
}
public MessageSendLogStore getMessageSendLogStore() {
return getOrCreate(() -> messageSendLogStore,
- () -> messageSendLogStore = new MessageSendLogStore(getRecipientStore(), getDatabase()));
+ () -> messageSendLogStore = new MessageSendLogStore(getRecipientStore(), getAccountDatabase()));
}
public String getAccount() {
@Override
public void close() {
synchronized (fileChannel) {
- if (database != null) {
+ if (accountDatabase != null) {
try {
- database.close();
+ accountDatabase.close();
} catch (SQLException e) {
logger.warn("Failed to close account database: {}", e.getMessage(), e);
}