1 package org
.asamk
.signal
.manager
.storage
.stickers
;
3 import org
.asamk
.signal
.manager
.api
.StickerPackId
;
4 import org
.asamk
.signal
.manager
.storage
.Database
;
5 import org
.asamk
.signal
.manager
.storage
.Utils
;
6 import org
.slf4j
.Logger
;
7 import org
.slf4j
.LoggerFactory
;
9 import java
.sql
.Connection
;
10 import java
.sql
.ResultSet
;
11 import java
.sql
.SQLException
;
12 import java
.util
.Collection
;
14 public class StickerStore
{
16 private final static Logger logger
= LoggerFactory
.getLogger(StickerStore
.class);
17 private static final String TABLE_STICKER
= "sticker";
19 private final Database database
;
21 public static void createSql(Connection connection
) throws SQLException
{
22 // When modifying the CREATE statement here, also add a migration in AccountDatabase.java
23 try (final var statement
= connection
.createStatement()) {
24 statement
.executeUpdate("""
25 CREATE TABLE sticker (
26 _id INTEGER PRIMARY KEY,
27 pack_id BLOB UNIQUE NOT NULL,
28 pack_key BLOB NOT NULL,
29 installed BOOLEAN NOT NULL DEFAULT FALSE
35 public StickerStore(final Database database
) {
36 this.database
= database
;
39 public Collection
<StickerPack
> getStickerPacks() {
42 SELECT s._id, s.pack_id, s.pack_key, s.installed
45 ).formatted(TABLE_STICKER
);
46 try (final var connection
= database
.getConnection()) {
47 try (final var statement
= connection
.prepareStatement(sql
)) {
48 try (var result
= Utils
.executeQueryForStream(statement
, this::getStickerPackFromResultSet
)) {
49 return result
.toList();
52 } catch (SQLException e
) {
53 throw new RuntimeException("Failed read from sticker store", e
);
57 public StickerPack
getStickerPack(StickerPackId packId
) {
60 SELECT s._id, s.pack_id, s.pack_key, s.installed
64 ).formatted(TABLE_STICKER
);
65 try (final var connection
= database
.getConnection()) {
66 try (final var statement
= connection
.prepareStatement(sql
)) {
67 statement
.setBytes(1, packId
.serialize());
68 return Utils
.executeQueryForOptional(statement
, this::getStickerPackFromResultSet
).orElse(null);
70 } catch (SQLException e
) {
71 throw new RuntimeException("Failed read from sticker store", e
);
75 public void addStickerPack(StickerPack stickerPack
) {
78 INSERT INTO %s (pack_id, pack_key, installed)
81 ).formatted(TABLE_STICKER
);
82 try (final var connection
= database
.getConnection()) {
83 try (final var statement
= connection
.prepareStatement(sql
)) {
84 statement
.setBytes(1, stickerPack
.packId().serialize());
85 statement
.setBytes(2, stickerPack
.packKey());
86 statement
.setBoolean(3, stickerPack
.isInstalled());
87 statement
.executeUpdate();
89 } catch (SQLException e
) {
90 throw new RuntimeException("Failed update sticker store", e
);
94 public void updateStickerPackInstalled(StickerPackId stickerPackId
, boolean installed
) {
101 ).formatted(TABLE_STICKER
);
102 try (final var connection
= database
.getConnection()) {
103 try (final var statement
= connection
.prepareStatement(sql
)) {
104 statement
.setBytes(1, stickerPackId
.serialize());
105 statement
.setBoolean(2, installed
);
106 statement
.executeUpdate();
108 } catch (SQLException e
) {
109 throw new RuntimeException("Failed update sticker store", e
);
113 void addLegacyStickers(Collection
<StickerPack
> stickerPacks
) {
114 logger
.debug("Migrating legacy stickers to database");
115 long start
= System
.nanoTime();
118 INSERT INTO %s (pack_id, pack_key, installed)
121 ).formatted(TABLE_STICKER
);
122 try (final var connection
= database
.getConnection()) {
123 connection
.setAutoCommit(false);
124 try (final var statement
= connection
.prepareStatement("DELETE FROM %s".formatted(TABLE_STICKER
))) {
125 statement
.executeUpdate();
127 try (final var statement
= connection
.prepareStatement(sql
)) {
128 for (final var sticker
: stickerPacks
) {
129 statement
.setBytes(1, sticker
.packId().serialize());
130 statement
.setBytes(2, sticker
.packKey());
131 statement
.setBoolean(3, sticker
.isInstalled());
132 statement
.executeUpdate();
136 } catch (SQLException e
) {
137 throw new RuntimeException("Failed update sticker store", e
);
139 logger
.debug("Stickers migration took {}ms", (System
.nanoTime() - start
) / 1000000);
142 private StickerPack
getStickerPackFromResultSet(ResultSet resultSet
) throws SQLException
{
143 final var internalId
= resultSet
.getLong("_id");
144 final var packId
= resultSet
.getBytes("pack_id");
145 final var packKey
= resultSet
.getBytes("pack_key");
146 final var installed
= resultSet
.getBoolean("installed");
147 return new StickerPack(internalId
, StickerPackId
.deserialize(packId
), packKey
, installed
);