1 /*
2  * Copyright (C) 2021 Finn Herzfeld
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 package io.finn.signald.db;
19 
20 import java.sql.PreparedStatement;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.util.UUID;
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.Logger;
26 
27 public class AccountDataTable {
28   private static final Logger logger = LogManager.getLogger();
29 
30   private static final String TABLE_NAME = "account_data";
31 
32   private static final String ACCOUNT_UUID = "account_uuid";
33   private static final String KEY = "key";
34   private static final String VALUE = "value";
35 
36   public enum Key {
37     OWN_IDENTITY_KEY_PAIR,
38     LOCAL_REGISTRATION_ID,
39     LAST_PRE_KEY_REFRESH,
40     DEVICE_NAME,
41     SENDER_CERTIFICATE,
42     SENDER_CERTIFICATE_REFRESH_TIME,
43     MULTI_DEVICE,
44     DEVICE_ID,
45     PASSWORD,
46     LAST_ACCOUNT_REFRESH,
47     PRE_KEY_ID_OFFSET,
48     NEXT_SIGNED_PRE_KEY_ID
49   }
50 
getBytes(UUID uuid, Key key)51   public static byte[] getBytes(UUID uuid, Key key) throws SQLException {
52     PreparedStatement statement = Database.getConn().prepareStatement("SELECT " + VALUE + " FROM " + TABLE_NAME + " WHERE " + KEY + " = ? AND " + ACCOUNT_UUID + " = ?");
53     statement.setString(1, key.name());
54     statement.setString(2, uuid.toString());
55     ResultSet rows = statement.executeQuery();
56     if (!rows.next()) {
57       rows.close();
58       return null;
59     }
60     byte[] result = rows.getBytes(VALUE);
61     rows.close();
62     return result;
63   }
64 
getInt(UUID uuid, Key key)65   public static int getInt(UUID uuid, Key key) throws SQLException {
66     PreparedStatement statement = Database.getConn().prepareStatement("SELECT " + VALUE + " FROM " + TABLE_NAME + " WHERE " + KEY + " = ? AND " + ACCOUNT_UUID + " = ?");
67     statement.setString(1, key.name());
68     statement.setString(2, uuid.toString());
69     ResultSet rows = statement.executeQuery();
70     if (!rows.next()) {
71       rows.close();
72       return -1;
73     }
74     int result = rows.getInt(VALUE);
75     rows.close();
76     return result;
77   }
78 
getLong(UUID uuid, Key key)79   public static long getLong(UUID uuid, Key key) throws SQLException {
80     PreparedStatement statement = Database.getConn().prepareStatement("SELECT " + VALUE + " FROM " + TABLE_NAME + " WHERE " + KEY + " = ? AND " + ACCOUNT_UUID + " = ?");
81     statement.setString(1, key.name());
82     statement.setString(2, uuid.toString());
83     ResultSet rows = statement.executeQuery();
84     if (!rows.next()) {
85       rows.close();
86       return -1;
87     }
88     long result = rows.getLong(VALUE);
89     rows.close();
90     return result;
91   }
92 
getString(UUID uuid, Key key)93   public static String getString(UUID uuid, Key key) throws SQLException {
94     PreparedStatement statement = Database.getConn().prepareStatement("SELECT " + VALUE + " FROM " + TABLE_NAME + " WHERE " + KEY + " = ? AND " + ACCOUNT_UUID + " = ?");
95     statement.setString(1, key.name());
96     statement.setString(2, uuid.toString());
97     ResultSet rows = statement.executeQuery();
98     if (!rows.next()) {
99       rows.close();
100       return null;
101     }
102     String result = rows.getString(VALUE);
103     rows.close();
104     return result;
105   }
106 
getBoolean(UUID uuid, Key key)107   public static Boolean getBoolean(UUID uuid, Key key) throws SQLException {
108     PreparedStatement statement = Database.getConn().prepareStatement("SELECT " + VALUE + " FROM " + TABLE_NAME + " WHERE " + KEY + " = ? AND " + ACCOUNT_UUID + " = ?");
109     statement.setString(1, key.name());
110     statement.setString(2, uuid.toString());
111     ResultSet rows = statement.executeQuery();
112     if (!rows.next()) {
113       rows.close();
114       return null;
115     }
116     Boolean result = rows.getBoolean(VALUE);
117     rows.close();
118     return result;
119   }
120 
set(UUID uuid, Key key, byte[] value)121   public static void set(UUID uuid, Key key, byte[] value) throws SQLException {
122     PreparedStatement statement =
123         Database.getConn().prepareStatement("INSERT INTO " + TABLE_NAME + "(" + ACCOUNT_UUID + "," + KEY + "," + VALUE + ") VALUES (?, ?, ?) ON CONFLICT(" + ACCOUNT_UUID + "," +
124                                             KEY + ") DO UPDATE SET " + VALUE + " = excluded." + VALUE);
125     statement.setString(1, uuid.toString());
126     statement.setString(2, key.name());
127     statement.setBytes(3, value);
128     statement.executeUpdate();
129   }
130 
set(UUID uuid, Key key, int value)131   public static void set(UUID uuid, Key key, int value) throws SQLException {
132     PreparedStatement statement =
133         Database.getConn().prepareStatement("INSERT INTO " + TABLE_NAME + "(" + ACCOUNT_UUID + "," + KEY + "," + VALUE + ") VALUES (?, ?, ?) ON CONFLICT(" + ACCOUNT_UUID + "," +
134                                             KEY + ") DO UPDATE SET " + VALUE + " = excluded." + VALUE);
135     statement.setString(1, uuid.toString());
136     statement.setString(2, key.name());
137     statement.setInt(3, value);
138     statement.executeUpdate();
139   }
140 
set(UUID uuid, Key key, long value)141   public static void set(UUID uuid, Key key, long value) throws SQLException {
142     PreparedStatement statement =
143         Database.getConn().prepareStatement("INSERT INTO " + TABLE_NAME + "(" + ACCOUNT_UUID + "," + KEY + "," + VALUE + ") VALUES (?, ?, ?) ON CONFLICT(" + ACCOUNT_UUID + "," +
144                                             KEY + ") DO UPDATE SET " + VALUE + " = excluded." + VALUE);
145     statement.setString(1, uuid.toString());
146     statement.setString(2, key.name());
147     statement.setLong(3, value);
148     statement.executeUpdate();
149   }
150 
set(UUID uuid, Key key, String value)151   public static void set(UUID uuid, Key key, String value) throws SQLException {
152     PreparedStatement statement =
153         Database.getConn().prepareStatement("INSERT INTO " + TABLE_NAME + "(" + ACCOUNT_UUID + "," + KEY + "," + VALUE + ") VALUES (?, ?, ?) ON CONFLICT(" + ACCOUNT_UUID + "," +
154                                             KEY + ") DO UPDATE SET " + VALUE + " = excluded." + VALUE);
155     statement.setString(1, uuid.toString());
156     statement.setString(2, key.name());
157     statement.setString(3, value);
158     statement.executeUpdate();
159   }
160 
set(UUID uuid, Key key, boolean value)161   public static void set(UUID uuid, Key key, boolean value) throws SQLException {
162     PreparedStatement statement =
163         Database.getConn().prepareStatement("INSERT INTO " + TABLE_NAME + "(" + ACCOUNT_UUID + "," + KEY + "," + VALUE + ") VALUES (?, ?, ?) ON CONFLICT(" + ACCOUNT_UUID + "," +
164                                             KEY + ") DO UPDATE SET " + VALUE + " = excluded." + VALUE);
165     statement.setString(1, uuid.toString());
166     statement.setString(2, key.name());
167     statement.setBoolean(3, value);
168     statement.executeUpdate();
169   }
170 
deleteAccount(UUID uuid)171   public static void deleteAccount(UUID uuid) throws SQLException {
172     PreparedStatement statement = Database.getConn().prepareStatement("DELETE FROM " + TABLE_NAME + " WHERE " + ACCOUNT_UUID + " = ?");
173     statement.setString(1, uuid.toString());
174     statement.executeUpdate();
175   }
176 }
177