1 package org
.asamk
.signal
.manager
.storage
;
3 import com
.zaxxer
.hikari
.HikariDataSource
;
5 import org
.asamk
.signal
.manager
.storage
.groups
.GroupStore
;
6 import org
.asamk
.signal
.manager
.storage
.prekeys
.PreKeyStore
;
7 import org
.asamk
.signal
.manager
.storage
.prekeys
.SignedPreKeyStore
;
8 import org
.asamk
.signal
.manager
.storage
.recipients
.RecipientStore
;
9 import org
.asamk
.signal
.manager
.storage
.sendLog
.MessageSendLogStore
;
10 import org
.asamk
.signal
.manager
.storage
.sessions
.SessionStore
;
11 import org
.asamk
.signal
.manager
.storage
.stickers
.StickerStore
;
12 import org
.slf4j
.Logger
;
13 import org
.slf4j
.LoggerFactory
;
16 import java
.sql
.Connection
;
17 import java
.sql
.SQLException
;
19 public class AccountDatabase
extends Database
{
21 private final static Logger logger
= LoggerFactory
.getLogger(AccountDatabase
.class);
22 private static final long DATABASE_VERSION
= 6;
24 private AccountDatabase(final HikariDataSource dataSource
) {
25 super(logger
, DATABASE_VERSION
, dataSource
);
28 public static AccountDatabase
init(File databaseFile
) throws SQLException
{
29 return initDatabase(databaseFile
, AccountDatabase
::new);
33 protected void createDatabase(final Connection connection
) throws SQLException
{
34 RecipientStore
.createSql(connection
);
35 MessageSendLogStore
.createSql(connection
);
36 StickerStore
.createSql(connection
);
37 PreKeyStore
.createSql(connection
);
38 SignedPreKeyStore
.createSql(connection
);
39 GroupStore
.createSql(connection
);
40 SessionStore
.createSql(connection
);
44 protected void upgradeDatabase(final Connection connection
, final long oldVersion
) throws SQLException
{
46 logger
.debug("Updating database: Creating recipient table");
47 try (final var statement
= connection
.createStatement()) {
48 statement
.executeUpdate("""
49 CREATE TABLE recipient (
50 _id INTEGER PRIMARY KEY AUTOINCREMENT,
54 profile_key_credential BLOB,
60 expiration_time INTEGER NOT NULL DEFAULT 0,
61 blocked BOOLEAN NOT NULL DEFAULT FALSE,
62 archived BOOLEAN NOT NULL DEFAULT FALSE,
63 profile_sharing BOOLEAN NOT NULL DEFAULT FALSE,
65 profile_last_update_timestamp INTEGER NOT NULL DEFAULT 0,
66 profile_given_name TEXT,
67 profile_family_name TEXT,
69 profile_about_emoji TEXT,
70 profile_avatar_url_path TEXT,
71 profile_mobile_coin_address BLOB,
72 profile_unidentified_access_mode TEXT,
73 profile_capabilities TEXT
79 logger
.debug("Updating database: Creating sticker table");
80 try (final var statement
= connection
.createStatement()) {
81 statement
.executeUpdate("""
82 CREATE TABLE sticker (
83 _id INTEGER PRIMARY KEY,
84 pack_id BLOB UNIQUE NOT NULL,
85 pack_key BLOB NOT NULL,
86 installed BOOLEAN NOT NULL DEFAULT FALSE
92 logger
.debug("Updating database: Creating pre key tables");
93 try (final var statement
= connection
.createStatement()) {
94 statement
.executeUpdate("""
95 CREATE TABLE signed_pre_key (
96 _id INTEGER PRIMARY KEY,
97 account_id_type INTEGER NOT NULL,
98 key_id INTEGER NOT NULL,
99 public_key BLOB NOT NULL,
100 private_key BLOB NOT NULL,
101 signature BLOB NOT NULL,
102 timestamp INTEGER DEFAULT 0,
103 UNIQUE(account_id_type, key_id)
105 CREATE TABLE pre_key (
106 _id INTEGER PRIMARY KEY,
107 account_id_type INTEGER NOT NULL,
108 key_id INTEGER NOT NULL,
109 public_key BLOB NOT NULL,
110 private_key BLOB NOT NULL,
111 UNIQUE(account_id_type, key_id)
116 if (oldVersion
< 5) {
117 logger
.debug("Updating database: Creating group tables");
118 try (final var statement
= connection
.createStatement()) {
119 statement
.executeUpdate("""
120 CREATE TABLE group_v2 (
121 _id INTEGER PRIMARY KEY,
122 group_id BLOB UNIQUE NOT NULL,
123 master_key BLOB NOT NULL,
125 distribution_id BLOB UNIQUE NOT NULL,
126 blocked BOOLEAN NOT NULL DEFAULT FALSE,
127 permission_denied BOOLEAN NOT NULL DEFAULT FALSE
129 CREATE TABLE group_v1 (
130 _id INTEGER PRIMARY KEY,
131 group_id BLOB UNIQUE NOT NULL,
132 group_id_v2 BLOB UNIQUE,
135 expiration_time INTEGER NOT NULL DEFAULT 0,
136 blocked BOOLEAN NOT NULL DEFAULT FALSE,
137 archived BOOLEAN NOT NULL DEFAULT FALSE
139 CREATE TABLE group_v1_member (
140 _id INTEGER PRIMARY KEY,
141 group_id INTEGER NOT NULL REFERENCES group_v1 (_id) ON DELETE CASCADE,
142 recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
143 UNIQUE(group_id, recipient_id)
148 if (oldVersion
< 6) {
149 logger
.debug("Updating database: Creating session tables");
150 try (final var statement
= connection
.createStatement()) {
151 statement
.executeUpdate("""
152 CREATE TABLE session (
153 _id INTEGER PRIMARY KEY,
154 account_id_type INTEGER NOT NULL,
155 recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
156 device_id INTEGER NOT NULL,
157 record BLOB NOT NULL,
158 UNIQUE(account_id_type, recipient_id, device_id)