Extra Database base class from AccountDatabase

This commit is contained in:
AsamK 2022-02-06 13:01:35 +01:00
parent b9f66248ac
commit 3040da99c4
3 changed files with 73 additions and 38 deletions

View file

@ -0,0 +1,33 @@
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);
}
}
}

View file

@ -3,53 +3,38 @@ package org.asamk.signal.manager.storage;
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);
final var result = newDatabase.apply(dataSource);
result.initDb();
dataSource = null;
return result;
}
} finally {
if (dataSource != null) {
dataSource.close();
@ -57,7 +42,7 @@ public class Database implements AutoCloseable {
}
}
public Connection getConnection() throws SQLException {
public final Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
@ -66,6 +51,23 @@ public class Database implements AutoCloseable {
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");

View file

@ -124,7 +124,7 @@ public class SignalAccount implements Closeable {
private MessageCache messageCache;
private MessageSendLogStore messageSendLogStore;
private Database database;
private AccountDatabase accountDatabase;
private SignalAccount(final FileChannel fileChannel, final FileLock lock) {
this.fileChannel = fileChannel;
@ -233,7 +233,7 @@ public class SignalAccount implements Closeable {
}
public void initDatabase() {
getDatabase();
getAccountDatabase();
}
private void clearAllPreKeys() {
@ -882,10 +882,10 @@ public class SignalAccount implements Closeable {
() -> 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);
}
@ -894,7 +894,7 @@ public class SignalAccount implements Closeable {
public MessageSendLogStore getMessageSendLogStore() {
return getOrCreate(() -> messageSendLogStore,
() -> messageSendLogStore = new MessageSendLogStore(getRecipientStore(), getDatabase()));
() -> messageSendLogStore = new MessageSendLogStore(getRecipientStore(), getAccountDatabase()));
}
public String getAccount() {
@ -1081,9 +1081,9 @@ public class SignalAccount implements Closeable {
@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);
}