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
;
13 import java
.util
.List
;
15 public class StickerStore
{
17 private final static Logger logger
= LoggerFactory
.getLogger(StickerStore
.class);
18 private static final String TABLE_STICKER
= "sticker";
20 private final Database database
;
22 public static void createSql(Connection connection
) throws SQLException
{
23 // When modifying the CREATE statement here, also add a migration in AccountDatabase.java
24 try (final var statement
= connection
.createStatement()) {
25 statement
.executeUpdate("""
26 CREATE TABLE sticker (
27 _id INTEGER PRIMARY KEY,
28 pack_id BLOB UNIQUE NOT NULL,
29 pack_key BLOB NOT NULL,
30 installed INTEGER NOT NULL DEFAULT FALSE
36 public StickerStore(final Database database
) {
37 this.database
= database
;
40 public List
<StickerPack
> getStickerPacks() {
43 SELECT s._id, s.pack_id, s.pack_key, s.installed
46 ).formatted(TABLE_STICKER
);
47 try (final var connection
= database
.getConnection()) {
48 try (final var statement
= connection
.prepareStatement(sql
)) {
49 try (var result
= Utils
.executeQueryForStream(statement
, this::getStickerPackFromResultSet
)) {
50 return result
.toList();
53 } catch (SQLException e
) {
54 throw new RuntimeException("Failed read from sticker store", e
);
58 public StickerPack
getStickerPack(StickerPackId packId
) {
61 SELECT s._id, s.pack_id, s.pack_key, s.installed
65 ).formatted(TABLE_STICKER
);
66 try (final var connection
= database
.getConnection()) {
67 try (final var statement
= connection
.prepareStatement(sql
)) {
68 statement
.setBytes(1, packId
.serialize());
69 return Utils
.executeQueryForOptional(statement
, this::getStickerPackFromResultSet
).orElse(null);
71 } catch (SQLException e
) {
72 throw new RuntimeException("Failed read from sticker store", e
);
76 public void addStickerPack(StickerPack stickerPack
) {
79 INSERT INTO %s (pack_id, pack_key, installed)
82 ).formatted(TABLE_STICKER
);
83 try (final var connection
= database
.getConnection()) {
84 try (final var statement
= connection
.prepareStatement(sql
)) {
85 statement
.setBytes(1, stickerPack
.packId().serialize());
86 statement
.setBytes(2, stickerPack
.packKey());
87 statement
.setBoolean(3, stickerPack
.isInstalled());
88 statement
.executeUpdate();
90 } catch (SQLException e
) {
91 throw new RuntimeException("Failed update sticker store", e
);
95 public void updateStickerPackInstalled(StickerPackId stickerPackId
, boolean installed
) {
102 ).formatted(TABLE_STICKER
);
103 try (final var connection
= database
.getConnection()) {
104 try (final var statement
= connection
.prepareStatement(sql
)) {
105 statement
.setBytes(1, stickerPackId
.serialize());
106 statement
.setBoolean(2, installed
);
107 statement
.executeUpdate();
109 } catch (SQLException e
) {
110 throw new RuntimeException("Failed update sticker store", e
);
114 void addLegacyStickers(Collection
<StickerPack
> stickerPacks
) {
115 logger
.debug("Migrating legacy stickers to database");
116 long start
= System
.nanoTime();
119 INSERT INTO %s (pack_id, pack_key, installed)
122 ).formatted(TABLE_STICKER
);
123 try (final var connection
= database
.getConnection()) {
124 connection
.setAutoCommit(false);
125 try (final var statement
= connection
.prepareStatement("DELETE FROM %s".formatted(TABLE_STICKER
))) {
126 statement
.executeUpdate();
128 try (final var statement
= connection
.prepareStatement(sql
)) {
129 for (final var sticker
: stickerPacks
) {
130 statement
.setBytes(1, sticker
.packId().serialize());
131 statement
.setBytes(2, sticker
.packKey());
132 statement
.setBoolean(3, sticker
.isInstalled());
133 statement
.executeUpdate();
137 } catch (SQLException e
) {
138 throw new RuntimeException("Failed update sticker store", e
);
140 logger
.debug("Stickers migration took {}ms", (System
.nanoTime() - start
) / 1000000);
143 private StickerPack
getStickerPackFromResultSet(ResultSet resultSet
) throws SQLException
{
144 final var internalId
= resultSet
.getLong("_id");
145 final var packId
= resultSet
.getBytes("pack_id");
146 final var packKey
= resultSet
.getBytes("pack_key");
147 final var installed
= resultSet
.getBoolean("installed");
148 return new StickerPack(internalId
, StickerPackId
.deserialize(packId
), packKey
, installed
);