@capacitor-community/sqlite 4.1.0-4 → 4.1.0-7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,366 +1,83 @@
1
1
  package com.getcapacitor.community.database.sqlite.SQLite;
2
2
 
3
- import android.content.Context;
4
3
  import android.util.Log;
5
- import com.getcapacitor.JSArray;
6
4
  import com.getcapacitor.JSObject;
7
- import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.UtilsJson;
8
5
  import java.util.ArrayList;
9
- import java.util.Date;
6
+ import java.util.Collections;
10
7
  import java.util.Dictionary;
11
- import java.util.Hashtable;
12
8
  import java.util.List;
13
9
  import org.json.JSONArray;
14
- import org.json.JSONException;
15
10
  import org.json.JSONObject;
16
11
 
17
12
  public class UtilsUpgrade {
18
13
 
19
14
  private static final String TAG = UtilsUpgrade.class.getName();
20
- private UtilsFile _uFile = new UtilsFile();
21
- private UtilsJson _uJson = new UtilsJson();
22
- private UtilsDrop _uDrop = new UtilsDrop();
23
- private UtilsSQLite _uSqlite = new UtilsSQLite();
24
- private Dictionary<String, List<String>> _alterTables = new Hashtable<>();
25
- private Dictionary<String, List<String>> _commonColumns = new Hashtable<>();
26
15
 
27
16
  /**
28
17
  * OnUpgrade Method
29
18
  * Database version upgrade flow process
19
+ *
30
20
  * @param db
31
- * @param context
32
- * @param dbName
33
21
  * @param upgDict
34
22
  * @param curVersion
35
23
  * @param targetVersion
36
24
  * @throws Exception
37
25
  */
38
- public void onUpgrade(
39
- Database db,
40
- Context context,
41
- String dbName,
42
- Dictionary<Integer, JSONObject> upgDict,
43
- Integer curVersion,
44
- Integer targetVersion
45
- ) throws Exception {
46
- JSONObject upgrade = upgDict.get(curVersion);
47
- int toVersion = upgrade.has("toVersion") ? upgrade.getInt("toVersion") : -1;
48
- if (toVersion == -1) {
49
- String msg = "Error: onUpgrade toVersion not given";
50
- throw new Exception(msg);
51
- }
52
- String statement = upgrade.has("statement") ? upgrade.getString("statement") : "";
53
- if (statement.length() <= 0) {
54
- String msg = "Error: onUpgrade statement not given";
55
- throw new Exception(msg);
56
- }
57
- JSONArray set = upgrade.has("set") ? upgrade.getJSONArray("set") : new JSONArray();
26
+ public void onUpgrade(Database db, Dictionary<Integer, JSONObject> upgDict, Integer curVersion, Integer targetVersion)
27
+ throws Exception {
28
+ Log.i(TAG, "UtilsUpgrade.onUpgrade: " + curVersion + " => " + targetVersion);
58
29
 
59
- if (targetVersion < toVersion) {
60
- String msg = "Error: version mistmatch Upgrade ";
61
- msg += "Statement would upgrade to version " + toVersion;
62
- msg += " , but target version is " + targetVersion;
63
- msg += " for database " + dbName + " and version ";
64
- msg += curVersion;
65
- throw new Exception(msg);
66
- }
67
- // Set Foreign Key Off
68
- try {
69
- db.getDb().setForeignKeyConstraintsEnabled(false);
70
- } catch (IllegalStateException e) {
71
- String msg = "Error: onUpgrade ";
72
- msg += "setForeignKeyConstraintsEnabled failed " + e;
73
- throw new Exception(msg);
74
- }
75
- // backup the database
30
+ List<Integer> sortedKeys = Collections.list(upgDict.keys());
31
+ Collections.sort(sortedKeys);
76
32
 
77
- Boolean ret = this._uFile.copyFile(context, dbName, "backup-" + dbName);
78
- if (!ret) {
79
- String msg = "Error: onUpgrade ";
80
- msg += "copy backup file failed ";
81
- throw new Exception(msg);
82
- }
83
- // Here we assume all the tables schema are given in
84
- // the upgrade statement
85
- if (statement.length() > 0) {
86
- try {
87
- executeStatementProcess(db, statement);
88
- } catch (Exception e) {
89
- String msg = "Error: onUpgrade executeStatementProcess";
90
- msg += " failed " + e;
91
- throw new Exception(msg);
92
- }
93
- }
94
- // here we assume that the Set contains only
95
- // - the data for new tables as INSERT statements
96
- // - the data for new columns in existing tables
97
- // as UPDATE statements
98
- if (set.length() > 0) {
99
- try {
100
- executeSetProcess(db, set, toVersion);
101
- } catch (Exception e) {
102
- String msg = "Error: onUpgrade executeSetProcess";
103
- msg += " failed " + e;
104
- throw new Exception(msg);
105
- }
106
- }
107
- // Set pragma FOREIGN KEY ON
108
- try {
109
- db.getDb().setForeignKeyConstraintsEnabled(true);
110
- } catch (IllegalStateException e) {
111
- String msg = "Error: onUpgrade ";
112
- msg += "setForeignKeyConstraintsEnabled failed " + e;
113
- throw new Exception(msg);
114
- }
115
- }
33
+ for (Integer versionKey : sortedKeys) {
34
+ if (versionKey > curVersion && versionKey <= targetVersion) {
35
+ JSONObject upgrade = upgDict.get(versionKey);
116
36
 
117
- /**
118
- * ExecuteStatementProcess Method
119
- * Execute Statement Flow Process
120
- *
121
- * @param db
122
- * @param statement
123
- * @throws Exception
124
- */
125
- private void executeStatementProcess(Database db, String statement) throws Exception {
126
- int changes = Integer.valueOf(-1);
127
- try {
128
- // -> backup all existing tables "tableName" in
129
- // "temp_tableName"
130
- backupTables(db);
131
-
132
- // -> Drop all Indexes
133
- _uDrop.dropIndexes(db);
134
-
135
- // -> Drop all Triggers
136
- _uDrop.dropTriggers(db);
137
-
138
- // -> Create new tables from upgrade.statement
139
-
140
- String[] sqlCmdArray = _uSqlite.getStatementsArray(statement);
141
-
142
- JSObject retObj = db.execute(sqlCmdArray);
143
- changes = retObj.getInteger("changes");
144
- if (changes < Integer.valueOf(0)) {
145
- throw new Exception("create new tables failed");
146
- }
147
-
148
- // -> Create the list of table's common fields
149
- findCommonColumns(db);
150
-
151
- // -> Update the new table's data from old table's data
152
- updateNewTablesData(db);
153
- } catch (Exception e) {
154
- throw new Exception("Error: executeStatementProcess " + " failed " + e);
155
- } finally {
156
- // -> Drop _temp_tables
157
- _uDrop.dropTempTables(db, _alterTables);
158
-
159
- // -> Do some cleanup
160
- _alterTables = new Hashtable<>();
161
- _commonColumns = new Hashtable<>();
162
- }
163
- }
164
-
165
- /**
166
- * BackupTables Method
167
- * Backup all Tables of a database
168
- *
169
- * @param db
170
- * @throws Exception
171
- */
172
- private void backupTables(Database db) throws Exception {
173
- try {
174
- List<String> tables = _uDrop.getTablesNames(db);
175
- for (String table : tables) {
176
- this.backupTable(db, table);
177
- }
178
- } catch (Exception e) {
179
- throw new Exception("Error: backupTables failed " + e);
180
- }
181
- }
182
-
183
- /**
184
- * BackupTable Method
185
- * Backup a Table
186
- *
187
- * @param db
188
- * @param table
189
- * @throws Exception
190
- */
191
- private void backupTable(Database db, String table) throws Exception {
192
- int changes = Integer.valueOf(-1);
193
- try {
194
- // get the column's name
195
- List<String> colNames = getColumnNames(db, table);
196
- _alterTables.put(table, colNames);
197
- // Delete _temp_table if exists
198
- String tmpTable = "_temp_" + table;
199
- String delStmt = "DROP TABLE IF EXISTS " + tmpTable + ";";
200
- db.runSQL(delStmt, new ArrayList<>());
201
- // prefix the table with _temp_
202
- String stmt = "ALTER TABLE " + table + " RENAME ";
203
- stmt += "TO " + tmpTable + ";";
204
- JSObject ret = db.runSQL(stmt, new ArrayList<>());
205
- long lastId = ret.getLong("lastId");
206
- if (lastId == -1) {
207
- throw new Exception("lastId = -1");
208
- }
209
- } catch (Exception e) {
210
- throw new Exception("Error: backupTable failed " + e);
211
- }
212
- }
37
+ JSONArray statementsJson = upgrade.has("statements") ? upgrade.getJSONArray("statements") : new JSONArray();
213
38
 
214
- /**
215
- * GetColumnNames Method
216
- * Get Column Names for a Given Table
217
- *
218
- * @param db
219
- * @param table
220
- * @return
221
- * @throws Exception
222
- */
223
- private List<String> getColumnNames(Database db, String table) throws Exception {
224
- List<String> retNames = new ArrayList<>();
225
- String query = new StringBuilder("PRAGMA table_info('").append(table).append("');").toString();
226
- JSArray resQuery = db.selectSQL(query, new ArrayList<Object>());
227
- List<JSObject> lQuery = resQuery.toList();
228
- if (lQuery.size() > 0) {
229
- for (JSObject obj : lQuery) {
230
- retNames.add(obj.getString("name"));
231
- }
232
- }
233
- return retNames;
234
- }
39
+ List<String> statements = new ArrayList<String>();
235
40
 
236
- /**
237
- * FindCommonColumns Method
238
- * Find Common Columns
239
- *
240
- * @param db
241
- * @throws Exception
242
- */
243
- private void findCommonColumns(Database db) throws Exception {
244
- List<String> columnNames = new ArrayList<>();
245
- try {
246
- List<String> tables = _uDrop.getTablesNames(db);
247
- for (String table : tables) {
248
- columnNames = getColumnNames(db, table);
249
- List<String> arr = _alterTables.get(table);
250
- if (arr != null && arr.size() > 0) {
251
- List<String> comCols = arrayIntersection(arr, columnNames);
252
- _commonColumns.put(table, comCols);
41
+ for (int i = 0; i < statementsJson.length(); i++) {
42
+ statements.add(statementsJson.getString(i));
253
43
  }
254
- }
255
- } catch (Exception e) {
256
- throw new Exception("findCommonColumns failed " + e);
257
- }
258
- }
259
44
 
260
- /**
261
- * ArrayIntersection Method
262
- * Calculate Two Arrays Intersection
263
- *
264
- * @param array1
265
- * @param array2
266
- * @return
267
- */
268
- private List<String> arrayIntersection(List<String> array1, List<String> array2) {
269
- List<String> intList = new ArrayList<>();
270
- for (String col : array1) {
271
- if (array2.contains(col)) {
272
- intList.add(col);
273
- }
274
- }
275
- return intList;
276
- }
45
+ if (statements.size() == 0) {
46
+ String msg = "Error: onUpgrade statement not given";
47
+ throw new Exception(msg);
48
+ }
277
49
 
278
- /**
279
- * UpdateNewTablesData Method
280
- * Update the New Table's Data from Old Table's Data
281
- *
282
- * @param db
283
- * @throws Exception
284
- */
285
- private void updateNewTablesData(Database db) throws Exception {
286
- int changes = Integer.valueOf(-1);
287
- try {
288
- List<String> statements = new ArrayList<>();
289
- List<String> keys = _uDrop.getDictStringKeys(_commonColumns);
290
- for (String key : keys) {
291
- List<String> values = _commonColumns.get(key);
292
- if (values.size() > 0) {
293
- String columns = _uJson.convertToString((ArrayList<String>) values, ',');
50
+ try {
51
+ executeStatementsProcess(db, statements.toArray(new String[0]));
294
52
 
295
- String stmt = "INSERT INTO " + key + " ";
296
- stmt += "(" + columns + ") SELECT ";
297
- stmt += columns + " FROM _temp_" + key + ";";
298
- statements.add(stmt);
299
- }
300
- }
301
- if (statements.size() > 0) {
302
- JSObject retObj = db.execute(statements.toArray(new String[0]));
303
- changes = retObj.getInteger("changes");
304
- if (changes < Integer.valueOf(0)) {
305
- throw new Exception("updateNewTablesData failed");
53
+ db.getDb().setVersion(versionKey);
54
+ } catch (Exception e) {
55
+ String msg = "Error: onUpgrade executeStatementProcess";
56
+ msg += " failed " + e;
57
+ throw new Exception(msg);
306
58
  }
307
59
  }
308
- } catch (Exception e) {
309
- throw new Exception("updateNewTablesData failed " + e);
310
60
  }
311
61
  }
312
62
 
313
63
  /**
314
- * ExecuteSetProcess Method
315
- * Execute Set Flow Process
64
+ * ExecuteStatementsProcess Method
65
+ * Execute Statement Flow Process
316
66
  *
317
67
  * @param db
318
- * @param set
319
- * @param toVersion
68
+ * @param statements
320
69
  * @throws Exception
321
70
  */
322
- private void executeSetProcess(Database db, JSONArray set, int toVersion) throws Exception {
71
+ private void executeStatementsProcess(Database db, String[] statements) throws Exception {
72
+ db.getDb().beginTransaction();
323
73
  try {
324
- // -> load new data
325
- JSArray jsSet = convertJSONArrayToJSArray(set);
326
- JSObject retObj = db.executeSet(jsSet);
327
- if (retObj.getInt("lastId") < 0) {
328
- throw new Exception("load new data failed");
329
- }
330
- // -> update database version
331
- db.getDb().setVersion(toVersion);
332
- // -> update syncDate if any
333
- Boolean isExists = _uJson.isTableExists(db, "sync_table");
334
- if (isExists) {
335
- Date date = new Date();
336
- long syncTime = date.getTime() / 1000L;
337
- String stmt = "UPDATE sync_table SET ";
338
- stmt += "sync_date = " + syncTime;
339
- stmt += " WHERE id = 1;";
340
- try {
341
- db.runSQL(stmt, new ArrayList<>());
342
- } catch (Exception e) {
343
- throw new Exception("executeSetProcess failed" + e.getMessage());
344
- }
345
- }
346
- } catch (Exception e) {
347
- throw new Exception("Error: executeSetProcess failed " + e.getMessage());
348
- }
349
- }
74
+ db.execute(statements);
350
75
 
351
- /**
352
- * ConvertJSONArrayToJSArray Method
353
- * Convert a JSONArray to a JSArray
354
- *
355
- * @param array
356
- * @return
357
- * @throws JSONException
358
- */
359
- private JSArray convertJSONArrayToJSArray(JSONArray array) throws JSONException {
360
- JSArray rArr = new JSArray();
361
- for (int i = 0; i < array.length(); i++) {
362
- rArr.put(array.get(i));
76
+ db.getDb().setTransactionSuccessful();
77
+ } catch (Exception e) {
78
+ throw new Exception("Error: executeStatementsProcess " + " failed " + e);
79
+ } finally {
80
+ db.getDb().endTransaction();
363
81
  }
364
- return rArr;
365
82
  }
366
83
  }
@@ -347,6 +347,10 @@ export interface capConnectionOptions {
347
347
  * ["encryption", "secret", "newsecret"]
348
348
  */
349
349
  mode?: string;
350
+ /**
351
+ * Set to true (database in read-only mode) / false
352
+ */
353
+ readonly?: boolean;
350
354
  }
351
355
  export interface capAllConnectionsOptions {
352
356
  /**
@@ -360,6 +364,10 @@ export interface capSQLiteOptions {
360
364
  * The database name
361
365
  */
362
366
  database?: string;
367
+ /**
368
+ * Set to true (database in read-only mode) / false
369
+ */
370
+ readonly?: boolean;
363
371
  }
364
372
  export interface capNCDatabasePathOptions {
365
373
  /**
@@ -740,10 +748,8 @@ export interface capJsonProgressListener {
740
748
  progress?: string;
741
749
  }
742
750
  export interface capSQLiteVersionUpgrade {
743
- fromVersion: number;
744
751
  toVersion: number;
745
- statement: string;
746
- set?: capSQLiteSet[];
752
+ statements: string[];
747
753
  }
748
754
  /**
749
755
  * SQLiteConnection Interface
@@ -799,38 +805,40 @@ export interface ISQLiteConnection {
799
805
  /**
800
806
  * Add the upgrade Statement for database version upgrading
801
807
  * @param database
802
- * @param fromVersion
803
808
  * @param toVersion
804
809
  * @param statement
805
810
  * @param set
806
811
  * @returns Promise<void>
807
812
  * @since 2.9.0 refactor
808
813
  */
809
- addUpgradeStatement(database: string, fromVersion: number, toVersion: number, statement: string, set?: capSQLiteSet[]): Promise<void>;
814
+ addUpgradeStatement(database: string, toVersion: number, statements: string[]): Promise<void>;
810
815
  /**
811
816
  * Create a connection to a database
812
817
  * @param database
813
818
  * @param encrypted
814
819
  * @param mode
815
820
  * @param version
821
+ * @param readonly
816
822
  * @returns Promise<SQLiteDBConnection>
817
823
  * @since 2.9.0 refactor
818
824
  */
819
- createConnection(database: string, encrypted: boolean, mode: string, version: number): Promise<SQLiteDBConnection>;
825
+ createConnection(database: string, encrypted: boolean, mode: string, version: number, readonly: boolean): Promise<SQLiteDBConnection>;
820
826
  /**
821
827
  * Check if a connection exists
822
828
  * @param database
829
+ * @param readonly
823
830
  * @returns Promise<capSQLiteResult>
824
831
  * @since 3.0.0-beta.5
825
832
  */
826
- isConnection(database: string): Promise<capSQLiteResult>;
833
+ isConnection(database: string, readonly: boolean): Promise<capSQLiteResult>;
827
834
  /**
828
835
  * Retrieve an existing database connection
829
836
  * @param database
837
+ * @param readonly
830
838
  * @returns Promise<SQLiteDBConnection>
831
839
  * @since 2.9.0 refactor
832
840
  */
833
- retrieveConnection(database: string): Promise<SQLiteDBConnection>;
841
+ retrieveConnection(database: string, readonly: boolean): Promise<SQLiteDBConnection>;
834
842
  /**
835
843
  * Retrieve all database connections
836
844
  * @returns Promise<Map<string, SQLiteDBConnection>>
@@ -840,10 +848,11 @@ export interface ISQLiteConnection {
840
848
  /**
841
849
  * Close a database connection
842
850
  * @param database
851
+ * @param readonly
843
852
  * @returns Promise<void>
844
853
  * @since 2.9.0 refactor
845
854
  */
846
- closeConnection(database: string): Promise<void>;
855
+ closeConnection(database: string, readonly: boolean): Promise<void>;
847
856
  /**
848
857
  * Close all database connections
849
858
  * @returns Promise<void>
@@ -981,11 +990,11 @@ export declare class SQLiteConnection implements ISQLiteConnection {
981
990
  setEncryptionSecret(passphrase: string): Promise<void>;
982
991
  changeEncryptionSecret(passphrase: string, oldpassphrase: string): Promise<void>;
983
992
  clearEncryptionSecret(): Promise<void>;
984
- addUpgradeStatement(database: string, fromVersion: number, toVersion: number, statement: string, set?: capSQLiteSet[]): Promise<void>;
985
- createConnection(database: string, encrypted: boolean, mode: string, version: number): Promise<SQLiteDBConnection>;
986
- closeConnection(database: string): Promise<void>;
987
- isConnection(database: string): Promise<capSQLiteResult>;
988
- retrieveConnection(database: string): Promise<SQLiteDBConnection>;
993
+ addUpgradeStatement(database: string, toVersion: number, statements: string[]): Promise<void>;
994
+ createConnection(database: string, encrypted: boolean, mode: string, version: number, readonly: boolean): Promise<SQLiteDBConnection>;
995
+ closeConnection(database: string, readonly: boolean): Promise<void>;
996
+ isConnection(database: string, readonly: boolean): Promise<capSQLiteResult>;
997
+ retrieveConnection(database: string, readonly: boolean): Promise<SQLiteDBConnection>;
989
998
  getNCDatabasePath(path: string, database: string): Promise<capNCDatabasePathResult>;
990
999
  createNCConnection(databasePath: string, version: number): Promise<SQLiteDBConnection>;
991
1000
  closeNCConnection(databasePath: string): Promise<void>;
@@ -1015,6 +1024,12 @@ export interface ISQLiteDBConnection {
1015
1024
  * @since 2.9.0 refactor
1016
1025
  */
1017
1026
  getConnectionDBName(): string;
1027
+ /**
1028
+ * Get SQLite DB Connection read-only mode
1029
+ * @returns boolean
1030
+ * @since 4.1.0
1031
+ */
1032
+ getConnectionReadOnly(): boolean;
1018
1033
  /**
1019
1034
  * Open a SQLite DB Connection
1020
1035
  * @returns Promise<void>
@@ -1146,9 +1161,11 @@ export interface ISQLiteDBConnection {
1146
1161
  */
1147
1162
  export declare class SQLiteDBConnection implements ISQLiteDBConnection {
1148
1163
  private dbName;
1164
+ private readonly;
1149
1165
  private sqlite;
1150
- constructor(dbName: string, sqlite: any);
1166
+ constructor(dbName: string, readonly: boolean, sqlite: any);
1151
1167
  getConnectionDBName(): string;
1168
+ getConnectionReadOnly(): boolean;
1152
1169
  open(): Promise<void>;
1153
1170
  close(): Promise<void>;
1154
1171
  getUrl(): Promise<capSQLiteUrl>;