Skip to content

Commit 0fd4474

Browse files
committed
Partial refactoring of working with stores + settings update.
See - AsamK#1668 - AsamK#1675 # Conflicts: # lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java # lib/src/main/java/org/asamk/signal/manager/storage/Database.java # lib/src/main/java/org/asamk/signal/manager/storage/keyValue/KeyValueStore.java # lib/src/main/java/org/asamk/signal/manager/syncStorage/AccountRecordProcessor.java # lib/src/main/java/org/asamk/signal/manager/syncStorage/ContactRecordProcessor.java
1 parent 93d281e commit 0fd4474

13 files changed

+438
-305
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ local.properties
1212
out/
1313
.DS_Store
1414
/bin/
15+
bin
1516
/test-config/

lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java

+19-18
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,8 @@ private boolean readDataFromStorage(
211211
}
212212

213213
if (!idDifference.localOnlyIds().isEmpty()) {
214-
final var updated = account.getRecipientStore()
215-
.removeStorageIdsFromLocalOnlyUnregisteredRecipients(connection,
216-
idDifference.localOnlyIds());
214+
final var updated = account.getRecipientStore().withConnection(connection)
215+
.removeStorageIdsFromLocalOnlyUnregisteredRecipients(idDifference.localOnlyIds());
217216

218217
if (updated > 0) {
219218
logger.warn(
@@ -359,22 +358,24 @@ private void forcePushToStorage(
359358
try (final var connection = account.getAccountDatabase().getConnection()) {
360359
connection.setAutoCommit(false);
361360

362-
final var recipientIds = account.getRecipientStore().getRecipientIds(connection);
361+
var recipientStore = account.getRecipientStore().withConnection(connection);
362+
var identityStore = account.getIdentityKeyStore().withConnection(connection);
363+
364+
final var recipientIds = recipientStore.getRecipientIds();
363365
newContactStorageIds = generateContactStorageIds(recipientIds);
364366
for (final var recipientId : recipientIds) {
365367
final var storageId = newContactStorageIds.get(recipientId);
366368
if (storageId.getType() == ManifestRecord.Identifier.Type.ACCOUNT.getValue()) {
367-
final var recipient = account.getRecipientStore().getRecipient(connection, recipientId);
368-
final var accountRecord = StorageSyncModels.localToRemoteRecord(connection,
369-
account.getConfigurationStore(),
369+
final var recipient = recipientStore.getRecipient(recipientId);
370+
final var accountRecord = StorageSyncModels.localToRemoteRecord(account.getConfigurationStore().withConnection(connection),
370371
recipient,
371372
account.getUsernameLink());
372373
newStorageRecords.add(new SignalStorageRecord(storageId,
373374
new StorageRecord.Builder().account(accountRecord).build()));
374375
} else {
375-
final var recipient = account.getRecipientStore().getRecipient(connection, recipientId);
376+
final var recipient = recipientStore.getRecipient(recipientId);
376377
final var address = recipient.getAddress().getIdentifier();
377-
final var identity = account.getIdentityKeyStore().getIdentityInfo(connection, address);
378+
final var identity = identityStore.getIdentityInfo(address);
378379
final var record = StorageSyncModels.localToRemoteRecord(recipient, identity);
379380
newStorageRecords.add(new SignalStorageRecord(storageId,
380381
new StorageRecord.Builder().contact(record).build()));
@@ -449,7 +450,7 @@ final var record = StorageSyncModels.localToRemoteRecord(group);
449450

450451
try (final var connection = account.getAccountDatabase().getConnection()) {
451452
connection.setAutoCommit(false);
452-
account.getRecipientStore().updateStorageIds(connection, newContactStorageIds);
453+
account.getRecipientStore().withConnection(connection).updateStorageIds(newContactStorageIds);
453454
account.getGroupStore().updateStorageIds(connection, newGroupV1StorageIds, newGroupV2StorageIds);
454455

455456
// delete all unknown storage ids
@@ -521,8 +522,8 @@ private List<StorageId> getAllLocalStorageIds(final Connection connection) throw
521522
final var storageIds = new ArrayList<StorageId>();
522523
storageIds.addAll(account.getUnknownStorageIdStore().getUnknownStorageIds(connection));
523524
storageIds.addAll(account.getGroupStore().getStorageIds(connection));
524-
storageIds.addAll(account.getRecipientStore().getStorageIds(connection));
525-
storageIds.add(account.getRecipientStore().getSelfStorageId(connection));
525+
storageIds.addAll(account.getRecipientStore().withConnection(connection).getStorageIds());
526+
storageIds.add(account.getRecipientStore().withConnection(connection).getSelfStorageId());
526527
return storageIds;
527528
}
528529

@@ -542,11 +543,13 @@ private SignalStorageRecord buildLocalStorageRecord(
542543
Connection connection,
543544
StorageId storageId
544545
) throws SQLException {
546+
var rs =account.getRecipientStore().withConnection(connection);
547+
var is = account.getIdentityKeyStore().withConnection(connection);
545548
return switch (ManifestRecord.Identifier.Type.fromValue(storageId.getType())) {
546549
case ManifestRecord.Identifier.Type.CONTACT -> {
547-
final var recipient = account.getRecipientStore().getRecipient(connection, storageId);
550+
final var recipient = rs.getRecipient(storageId);
548551
final var address = recipient.getAddress().getIdentifier();
549-
final var identity = account.getIdentityKeyStore().getIdentityInfo(connection, address);
552+
final var identity = is.getIdentityInfo(address);
550553
final var record = StorageSyncModels.localToRemoteRecord(recipient, identity);
551554
yield new SignalStorageRecord(storageId, new StorageRecord.Builder().contact(record).build());
552555
}
@@ -561,11 +564,9 @@ final var record = StorageSyncModels.localToRemoteRecord(groupV2);
561564
yield new SignalStorageRecord(storageId, new StorageRecord.Builder().groupV2(record).build());
562565
}
563566
case ManifestRecord.Identifier.Type.ACCOUNT -> {
564-
final var selfRecipient = account.getRecipientStore()
565-
.getRecipient(connection, account.getSelfRecipientId());
567+
final var selfRecipient = rs.getRecipient(account.getSelfRecipientId());
566568

567-
final var record = StorageSyncModels.localToRemoteRecord(connection,
568-
account.getConfigurationStore(),
569+
final var record = StorageSyncModels.localToRemoteRecord(account.getConfigurationStore().withConnection(connection),
569570
selfRecipient,
570571
account.getUsernameLink());
571572
yield new SignalStorageRecord(storageId, new StorageRecord.Builder().account(record).build());

lib/src/main/java/org/asamk/signal/manager/storage/Database.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,14 @@ private static void setUserVersion(final Connection connection, long userVersion
9292
private static HikariDataSource getHikariDataSource(final String databaseFile) {
9393
final var sqliteConfig = new SQLiteConfig();
9494
sqliteConfig.setBusyTimeout(60_000);
95-
sqliteConfig.setTransactionMode(SQLiteConfig.TransactionMode.IMMEDIATE);
95+
sqliteConfig.setTransactionMode(SQLiteConfig.TransactionMode.DEFERRED);
9696

9797
HikariConfig config = new HikariConfig();
9898
config.setJdbcUrl("jdbc:sqlite:" + databaseFile + "?foreign_keys=ON&journal_mode=wal");
9999
config.setDataSourceProperties(sqliteConfig.toProperties());
100-
config.setMinimumIdle(1);
101-
config.setConnectionTimeout(90_000);
102-
config.setMaximumPoolSize(50);
100+
config.setMinimumIdle(0);
101+
config.setConnectionTimeout(30_000);
102+
config.setMaximumPoolSize(1); // this + lower timeouts allows us to find connection issues faster
103103
config.setMaxLifetime(0);
104104
return new HikariDataSource(config);
105105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.asamk.signal.manager.storage;
2+
3+
import java.sql.Connection;
4+
import java.sql.SQLException;
5+
import java.util.function.Supplier;
6+
7+
public abstract class StoreBase {
8+
private final Database database;
9+
private final Connection existingConnection;
10+
11+
protected StoreBase(Database database, Connection existingConnection) {
12+
this.database = database;
13+
this.existingConnection = existingConnection;
14+
if (database == null && existingConnection == null) {
15+
throw new IllegalArgumentException("Database or connection is required");
16+
}
17+
}
18+
19+
public record ConnectionHolder(Connection connection, boolean shouldClose) implements Supplier<Connection>, AutoCloseable {
20+
public ConnectionHolder {
21+
if (connection == null) {
22+
throw new IllegalArgumentException("Connection is required");
23+
}
24+
}
25+
26+
@Override
27+
public void close() throws SQLException {
28+
if (shouldClose) {
29+
connection.close();
30+
}
31+
}
32+
33+
@Override
34+
public Connection get() {
35+
return connection;
36+
}
37+
}
38+
39+
@FunctionalInterface
40+
public interface SQLFunction<T> {
41+
T apply(Connection connection) throws SQLException;
42+
}
43+
44+
@FunctionalInterface
45+
public interface SQLRunnable {
46+
void run(Connection connection) throws SQLException;
47+
}
48+
49+
50+
protected ConnectionHolder getConnectionImpl() throws SQLException {
51+
return getDatabase() != null
52+
? new ConnectionHolder(getDatabase().getConnection(), true)
53+
: new ConnectionHolder(getExistingConnection(), false);
54+
}
55+
56+
protected <T> T withConnection(SQLFunction<T> function) throws SQLException {
57+
try (final var connection = getConnectionImpl()) {
58+
return function.apply(connection.get());
59+
}
60+
}
61+
62+
protected void withConnectionRun(SQLRunnable runnable) throws SQLException {
63+
try (final var connection = getConnectionImpl()) {
64+
runnable.run(connection.get());
65+
}
66+
}
67+
68+
protected Database getDatabase() {
69+
return database;
70+
}
71+
72+
protected Connection getExistingConnection() {
73+
return existingConnection;
74+
}
75+
}

lib/src/main/java/org/asamk/signal/manager/storage/configuration/ConfigurationStore.java

+35-76
Original file line numberDiff line numberDiff line change
@@ -13,168 +13,127 @@ public class ConfigurationStore {
1313
private final KeyValueStore keyValueStore;
1414
private final RecipientStore recipientStore;
1515

16-
private final KeyValueEntry<Boolean> readReceipts = new KeyValueEntry<>("config-read-receipts", Boolean.class);
17-
private final KeyValueEntry<Boolean> unidentifiedDeliveryIndicators = new KeyValueEntry<>(
16+
private final static KeyValueEntry<Boolean> readReceipts = new KeyValueEntry<>("config-read-receipts", Boolean.class);
17+
private final static KeyValueEntry<Boolean> unidentifiedDeliveryIndicators = new KeyValueEntry<>(
1818
"config-unidentified-delivery-indicators",
1919
Boolean.class);
20-
private final KeyValueEntry<Boolean> typingIndicators = new KeyValueEntry<>("config-typing-indicators",
20+
private final static KeyValueEntry<Boolean> typingIndicators = new KeyValueEntry<>("config-typing-indicators",
2121
Boolean.class);
22-
private final KeyValueEntry<Boolean> linkPreviews = new KeyValueEntry<>("config-link-previews", Boolean.class);
23-
private final KeyValueEntry<Boolean> phoneNumberUnlisted = new KeyValueEntry<>("config-phone-number-unlisted",
22+
private final static KeyValueEntry<Boolean> linkPreviews = new KeyValueEntry<>("config-link-previews", Boolean.class);
23+
private final static KeyValueEntry<Boolean> phoneNumberUnlisted = new KeyValueEntry<>("config-phone-number-unlisted",
2424
Boolean.class);
25-
private final KeyValueEntry<PhoneNumberSharingMode> phoneNumberSharingMode = new KeyValueEntry<>(
25+
private final static KeyValueEntry<PhoneNumberSharingMode> phoneNumberSharingMode = new KeyValueEntry<>(
2626
"config-phone-number-sharing-mode",
2727
PhoneNumberSharingMode.class);
28-
private final KeyValueEntry<String> usernameLinkColor = new KeyValueEntry<>("username-link-color", String.class);
28+
private final static KeyValueEntry<String> usernameLinkColor = new KeyValueEntry<>("username-link-color", String.class);
2929

3030
public ConfigurationStore(final KeyValueStore keyValueStore, RecipientStore recipientStore) {
3131
this.keyValueStore = keyValueStore;
3232
this.recipientStore = recipientStore;
3333
}
3434

35+
public ConnectedConfigurationStore withConnection(final Connection connection) throws SQLException {
36+
return new ConnectedConfigurationStore(keyValueStore, recipientStore, connection);
37+
}
38+
3539
public Boolean getReadReceipts() {
3640
return keyValueStore.getEntry(readReceipts);
3741
}
3842

39-
public Boolean getReadReceipts(final Connection connection) throws SQLException {
40-
return keyValueStore.getEntry(connection, readReceipts);
41-
}
43+
// DS: thanks to `withConnection()` method we don't need these versions.
44+
// Commenting them out for now, to simplify merge. Will try to refactor connection management to use context object pattern.
45+
46+
// public Boolean getReadReceipts(final Connection connection) throws SQLException {
47+
// return keyValueStore.getEntry(connection, readReceipts);
48+
// }
4249

4350
public void setReadReceipts(final boolean value) {
4451
if (keyValueStore.storeEntry(readReceipts, value)) {
4552
recipientStore.rotateSelfStorageId();
4653
}
4754
}
4855

49-
public void setReadReceipts(final Connection connection, final boolean value) throws SQLException {
50-
if (keyValueStore.storeEntry(connection, readReceipts, value)) {
51-
recipientStore.rotateSelfStorageId(connection);
52-
}
53-
}
54-
5556
public Boolean getUnidentifiedDeliveryIndicators() {
5657
return keyValueStore.getEntry(unidentifiedDeliveryIndicators);
5758
}
5859

59-
public Boolean getUnidentifiedDeliveryIndicators(final Connection connection) throws SQLException {
60-
return keyValueStore.getEntry(connection, unidentifiedDeliveryIndicators);
61-
}
60+
// public Boolean getUnidentifiedDeliveryIndicators(final Connection connection) throws SQLException {
61+
// return keyValueStore.getEntry(connection, unidentifiedDeliveryIndicators);
62+
// }
6263

6364
public void setUnidentifiedDeliveryIndicators(final boolean value) {
6465
if (keyValueStore.storeEntry(unidentifiedDeliveryIndicators, value)) {
6566
recipientStore.rotateSelfStorageId();
6667
}
6768
}
6869

69-
public void setUnidentifiedDeliveryIndicators(
70-
final Connection connection,
71-
final boolean value
72-
) throws SQLException {
73-
if (keyValueStore.storeEntry(connection, unidentifiedDeliveryIndicators, value)) {
74-
recipientStore.rotateSelfStorageId(connection);
75-
}
76-
}
77-
7870
public Boolean getTypingIndicators() {
7971
return keyValueStore.getEntry(typingIndicators);
8072
}
8173

82-
public Boolean getTypingIndicators(final Connection connection) throws SQLException {
83-
return keyValueStore.getEntry(connection, typingIndicators);
84-
}
74+
// public Boolean getTypingIndicators(final Connection connection) throws SQLException {
75+
// return keyValueStore.getEntry(connection, typingIndicators);
76+
// }
8577

8678
public void setTypingIndicators(final boolean value) {
8779
if (keyValueStore.storeEntry(typingIndicators, value)) {
8880
recipientStore.rotateSelfStorageId();
8981
}
9082
}
9183

92-
public void setTypingIndicators(final Connection connection, final boolean value) throws SQLException {
93-
if (keyValueStore.storeEntry(connection, typingIndicators, value)) {
94-
recipientStore.rotateSelfStorageId(connection);
95-
}
96-
}
97-
9884
public Boolean getLinkPreviews() {
9985
return keyValueStore.getEntry(linkPreviews);
10086
}
10187

102-
public Boolean getLinkPreviews(final Connection connection) throws SQLException {
103-
return keyValueStore.getEntry(connection, linkPreviews);
104-
}
88+
// public Boolean getLinkPreviews(final Connection connection) throws SQLException {
89+
// return keyValueStore.getEntry(connection, linkPreviews);
90+
// }
10591

10692
public void setLinkPreviews(final boolean value) {
10793
if (keyValueStore.storeEntry(linkPreviews, value)) {
10894
recipientStore.rotateSelfStorageId();
10995
}
11096
}
11197

112-
public void setLinkPreviews(final Connection connection, final boolean value) throws SQLException {
113-
if (keyValueStore.storeEntry(connection, linkPreviews, value)) {
114-
recipientStore.rotateSelfStorageId(connection);
115-
}
116-
}
117-
11898
public Boolean getPhoneNumberUnlisted() {
11999
return keyValueStore.getEntry(phoneNumberUnlisted);
120100
}
121101

122-
public Boolean getPhoneNumberUnlisted(final Connection connection) throws SQLException {
123-
return keyValueStore.getEntry(connection, phoneNumberUnlisted);
124-
}
102+
// public Boolean getPhoneNumberUnlisted(final Connection connection) throws SQLException {
103+
// return keyValueStore.getEntry(connection, phoneNumberUnlisted);
104+
// }
125105

126106
public void setPhoneNumberUnlisted(final boolean value) {
127107
if (keyValueStore.storeEntry(phoneNumberUnlisted, value)) {
128108
recipientStore.rotateSelfStorageId();
129109
}
130110
}
131111

132-
public void setPhoneNumberUnlisted(final Connection connection, final boolean value) throws SQLException {
133-
if (keyValueStore.storeEntry(connection, phoneNumberUnlisted, value)) {
134-
recipientStore.rotateSelfStorageId(connection);
135-
}
136-
}
137-
138112
public PhoneNumberSharingMode getPhoneNumberSharingMode() {
139113
return keyValueStore.getEntry(phoneNumberSharingMode);
140114
}
141115

142-
public PhoneNumberSharingMode getPhoneNumberSharingMode(final Connection connection) throws SQLException {
143-
return keyValueStore.getEntry(connection, phoneNumberSharingMode);
144-
}
116+
// public PhoneNumberSharingMode getPhoneNumberSharingMode(final Connection connection) throws SQLException {
117+
// return keyValueStore.getEntry(connection, phoneNumberSharingMode);
118+
// }
145119

146120
public void setPhoneNumberSharingMode(final PhoneNumberSharingMode value) {
147121
if (keyValueStore.storeEntry(phoneNumberSharingMode, value)) {
148122
recipientStore.rotateSelfStorageId();
149123
}
150124
}
151125

152-
public void setPhoneNumberSharingMode(
153-
final Connection connection,
154-
final PhoneNumberSharingMode value
155-
) throws SQLException {
156-
if (keyValueStore.storeEntry(connection, phoneNumberSharingMode, value)) {
157-
recipientStore.rotateSelfStorageId(connection);
158-
}
159-
}
160-
161126
public String getUsernameLinkColor() {
162127
return keyValueStore.getEntry(usernameLinkColor);
163128
}
164129

165-
public String getUsernameLinkColor(final Connection connection) throws SQLException {
166-
return keyValueStore.getEntry(connection, usernameLinkColor);
167-
}
130+
// public String getUsernameLinkColor(final Connection connection) throws SQLException {
131+
// return keyValueStore.getEntry(connection, usernameLinkColor);
132+
// }
168133

169134
public void setUsernameLinkColor(final String color) {
170135
if (keyValueStore.storeEntry(usernameLinkColor, color)) {
171136
recipientStore.rotateSelfStorageId();
172137
}
173138
}
174-
175-
public void setUsernameLinkColor(final Connection connection, final String color) throws SQLException {
176-
if (keyValueStore.storeEntry(connection, usernameLinkColor, color)) {
177-
recipientStore.rotateSelfStorageId(connection);
178-
}
179-
}
180139
}

0 commit comments

Comments
 (0)