@capgo/capacitor-fast-sql 8.0.11 → 8.0.13
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.
- package/CapgoCapacitorFastSql.podspec +1 -0
- package/README.md +23 -0
- package/android/build.gradle +2 -1
- package/android/src/main/java/app/capgo/capacitor/fastsql/CapgoCapacitorFastSqlPlugin.java +19 -8
- package/android/src/main/java/app/capgo/capacitor/fastsql/DatabaseConnection.java +16 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/EncryptedSQLDatabase.java +222 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/SQLDatabase.java +1 -1
- package/android/src/main/java/app/capgo/capacitor/fastsql/SQLHTTPServer.java +8 -8
- package/dist/esm/fast-sql.d.ts.map +1 -1
- package/dist/esm/fast-sql.js +3 -2
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/key-value.d.ts +61 -0
- package/dist/esm/key-value.d.ts.map +1 -0
- package/dist/esm/key-value.js +183 -0
- package/dist/plugin.cjs.js +187 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +187 -2
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/CapgoCapacitorFastSqlPlugin.swift +9 -2
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLDatabase.swift +68 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
High-performance native SQLite plugin with HTTP server for efficient sync operations and IndexedDB replacement.
|
|
10
|
+
Official Capgo alternative to Ionic Appflow Secure Storage.
|
|
10
11
|
|
|
11
12
|
## Why Fast SQL?
|
|
12
13
|
|
|
@@ -75,6 +76,10 @@ Add to your `AndroidManifest.xml` if needed:
|
|
|
75
76
|
</application>
|
|
76
77
|
```
|
|
77
78
|
|
|
79
|
+
## Encryption (iOS/Android)
|
|
80
|
+
|
|
81
|
+
Set `encrypted: true` and provide an `encryptionKey` when connecting. This uses SQLCipher on mobile platforms (ensure SQLCipher is linked on iOS if you use SwiftPM).
|
|
82
|
+
|
|
78
83
|
## Usage
|
|
79
84
|
|
|
80
85
|
### Basic Example
|
|
@@ -139,6 +144,24 @@ const results = await db.executeBatch([
|
|
|
139
144
|
]);
|
|
140
145
|
```
|
|
141
146
|
|
|
147
|
+
### Key-Value Storage (Mobile-focused)
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { KeyValueStore } from '@capgo/capacitor-fast-sql';
|
|
151
|
+
|
|
152
|
+
const kv = await KeyValueStore.open({
|
|
153
|
+
database: 'myapp',
|
|
154
|
+
encrypted: true,
|
|
155
|
+
encryptionKey: 'super-secret-key',
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await kv.set('session', { token: 'abc123', expiresAt: 1710000000 });
|
|
159
|
+
const session = await kv.get('session');
|
|
160
|
+
await kv.remove('session');
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> Note: Web support is intended for minimal testing only. The primary focus is iOS/Android.
|
|
164
|
+
|
|
142
165
|
## API
|
|
143
166
|
|
|
144
167
|
<docgen-index>
|
package/android/build.gradle
CHANGED
|
@@ -44,7 +44,6 @@ android {
|
|
|
44
44
|
|
|
45
45
|
repositories {
|
|
46
46
|
google()
|
|
47
|
-
jcenter()
|
|
48
47
|
mavenCentral()
|
|
49
48
|
}
|
|
50
49
|
|
|
@@ -52,8 +51,10 @@ dependencies {
|
|
|
52
51
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
53
52
|
implementation project(':capacitor-android')
|
|
54
53
|
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
54
|
+
implementation 'androidx.sqlite:sqlite:2.4.0'
|
|
55
55
|
implementation 'com.google.code.gson:gson:2.13.2'
|
|
56
56
|
implementation 'org.nanohttpd:nanohttpd:2.3.1'
|
|
57
|
+
implementation 'net.zetetic:sqlcipher-android:4.13.0'
|
|
57
58
|
testImplementation "junit:junit:$junitVersion"
|
|
58
59
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
59
60
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
@@ -19,9 +19,9 @@ import java.util.Map;
|
|
|
19
19
|
@CapacitorPlugin(name = "CapgoCapacitorFastSql")
|
|
20
20
|
public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
21
21
|
|
|
22
|
-
private final String pluginVersion = "8.0.
|
|
22
|
+
private final String pluginVersion = "8.0.13";
|
|
23
23
|
|
|
24
|
-
private Map<String,
|
|
24
|
+
private Map<String, DatabaseConnection> databases = new HashMap<>();
|
|
25
25
|
private SQLHTTPServer server;
|
|
26
26
|
|
|
27
27
|
@PluginMethod
|
|
@@ -31,6 +31,12 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
31
31
|
call.reject("Database name is required");
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
+
boolean encrypted = call.getBoolean("encrypted", false);
|
|
35
|
+
String encryptionKey = call.getString("encryptionKey");
|
|
36
|
+
if (encrypted && (encryptionKey == null || encryptionKey.isEmpty())) {
|
|
37
|
+
call.reject("Encryption key is required when encrypted is true");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
34
40
|
|
|
35
41
|
// Check if already connected
|
|
36
42
|
if (databases.containsKey(database)) {
|
|
@@ -49,7 +55,12 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
49
55
|
File dbFile = getDatabasePath(database);
|
|
50
56
|
|
|
51
57
|
// Open database
|
|
52
|
-
|
|
58
|
+
DatabaseConnection db;
|
|
59
|
+
if (encrypted) {
|
|
60
|
+
db = new EncryptedSQLDatabase(dbFile.getAbsolutePath(), encryptionKey);
|
|
61
|
+
} else {
|
|
62
|
+
db = new SQLDatabase(dbFile.getAbsolutePath());
|
|
63
|
+
}
|
|
53
64
|
databases.put(database, db);
|
|
54
65
|
|
|
55
66
|
// Start HTTP server if not already running
|
|
@@ -76,7 +87,7 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
76
87
|
return;
|
|
77
88
|
}
|
|
78
89
|
|
|
79
|
-
|
|
90
|
+
DatabaseConnection db = databases.get(database);
|
|
80
91
|
if (db == null) {
|
|
81
92
|
call.reject("Database '" + database + "' is not connected");
|
|
82
93
|
return;
|
|
@@ -132,7 +143,7 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
132
143
|
return;
|
|
133
144
|
}
|
|
134
145
|
|
|
135
|
-
|
|
146
|
+
DatabaseConnection db = databases.get(database);
|
|
136
147
|
if (db == null) {
|
|
137
148
|
call.reject("Database '" + database + "' is not connected");
|
|
138
149
|
return;
|
|
@@ -156,7 +167,7 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
156
167
|
return;
|
|
157
168
|
}
|
|
158
169
|
|
|
159
|
-
|
|
170
|
+
DatabaseConnection db = databases.get(database);
|
|
160
171
|
if (db == null) {
|
|
161
172
|
call.reject("Database '" + database + "' is not connected");
|
|
162
173
|
return;
|
|
@@ -178,7 +189,7 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
178
189
|
return;
|
|
179
190
|
}
|
|
180
191
|
|
|
181
|
-
|
|
192
|
+
DatabaseConnection db = databases.get(database);
|
|
182
193
|
if (db == null) {
|
|
183
194
|
call.reject("Database '" + database + "' is not connected");
|
|
184
195
|
return;
|
|
@@ -200,7 +211,7 @@ public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
|
200
211
|
return;
|
|
201
212
|
}
|
|
202
213
|
|
|
203
|
-
|
|
214
|
+
DatabaseConnection db = databases.get(database);
|
|
204
215
|
if (db == null) {
|
|
205
216
|
call.reject("Database '" + database + "' is not connected");
|
|
206
217
|
return;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package app.capgo.capacitor.fastsql;
|
|
2
|
+
|
|
3
|
+
import com.getcapacitor.JSArray;
|
|
4
|
+
import com.getcapacitor.JSObject;
|
|
5
|
+
|
|
6
|
+
public interface DatabaseConnection {
|
|
7
|
+
JSObject execute(String statement, JSArray params) throws Exception;
|
|
8
|
+
|
|
9
|
+
void beginTransaction() throws Exception;
|
|
10
|
+
|
|
11
|
+
void commitTransaction() throws Exception;
|
|
12
|
+
|
|
13
|
+
void rollbackTransaction() throws Exception;
|
|
14
|
+
|
|
15
|
+
void close();
|
|
16
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
package app.capgo.capacitor.fastsql;
|
|
2
|
+
|
|
3
|
+
import android.database.Cursor;
|
|
4
|
+
import android.util.Base64;
|
|
5
|
+
import com.getcapacitor.JSArray;
|
|
6
|
+
import com.getcapacitor.JSObject;
|
|
7
|
+
import java.nio.charset.StandardCharsets;
|
|
8
|
+
import java.util.ArrayList;
|
|
9
|
+
import java.util.List;
|
|
10
|
+
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
|
11
|
+
import net.zetetic.database.sqlcipher.SQLiteStatement;
|
|
12
|
+
import org.json.JSONObject;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* SQLite database wrapper for Android using SQLCipher.
|
|
16
|
+
*/
|
|
17
|
+
public class EncryptedSQLDatabase implements DatabaseConnection {
|
|
18
|
+
|
|
19
|
+
private SQLiteDatabase db;
|
|
20
|
+
private boolean inTransaction = false;
|
|
21
|
+
|
|
22
|
+
public EncryptedSQLDatabase(String path, String encryptionKey) throws Exception {
|
|
23
|
+
if (encryptionKey == null || encryptionKey.isEmpty()) {
|
|
24
|
+
throw new Exception("Encryption key is required when encrypted is true");
|
|
25
|
+
}
|
|
26
|
+
byte[] keyBytes = encryptionKey.getBytes(StandardCharsets.UTF_8);
|
|
27
|
+
this.db = SQLiteDatabase.openOrCreateDatabase(path, keyBytes, null, null);
|
|
28
|
+
// Enable foreign keys
|
|
29
|
+
db.execSQL("PRAGMA foreign_keys = ON");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public void close() {
|
|
33
|
+
if (db != null && db.isOpen()) {
|
|
34
|
+
db.close();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public JSObject execute(String statement, JSArray params) throws Exception {
|
|
39
|
+
if (db == null || !db.isOpen()) {
|
|
40
|
+
throw new Exception("Database is not open");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
String trimmedStatement = statement.trim().toUpperCase();
|
|
44
|
+
boolean isQuery =
|
|
45
|
+
trimmedStatement.startsWith("SELECT") || trimmedStatement.startsWith("PRAGMA") || trimmedStatement.startsWith("EXPLAIN");
|
|
46
|
+
|
|
47
|
+
if (isQuery) {
|
|
48
|
+
return executeQuery(statement, params);
|
|
49
|
+
} else {
|
|
50
|
+
return executeUpdate(statement, params);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private JSObject executeQuery(String statement, JSArray params) throws Exception {
|
|
55
|
+
Cursor cursor = null;
|
|
56
|
+
try {
|
|
57
|
+
String[] bindArgs = convertParamsToStringArray(params);
|
|
58
|
+
cursor = db.rawQuery(statement, bindArgs);
|
|
59
|
+
|
|
60
|
+
JSArray rows = new JSArray();
|
|
61
|
+
while (cursor.moveToNext()) {
|
|
62
|
+
JSObject row = new JSObject();
|
|
63
|
+
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
|
64
|
+
String columnName = cursor.getColumnName(i);
|
|
65
|
+
Object value = getColumnValue(cursor, i);
|
|
66
|
+
row.put(columnName, value);
|
|
67
|
+
}
|
|
68
|
+
rows.put(row);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
JSObject result = new JSObject();
|
|
72
|
+
result.put("rows", rows);
|
|
73
|
+
result.put("rowsAffected", 0);
|
|
74
|
+
return result;
|
|
75
|
+
} finally {
|
|
76
|
+
if (cursor != null) {
|
|
77
|
+
cursor.close();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private JSObject executeUpdate(String statement, JSArray params) throws Exception {
|
|
83
|
+
SQLiteStatement stmt = null;
|
|
84
|
+
try {
|
|
85
|
+
stmt = db.compileStatement(statement);
|
|
86
|
+
bindParams(stmt, params);
|
|
87
|
+
|
|
88
|
+
long result;
|
|
89
|
+
if (statement.trim().toUpperCase().startsWith("INSERT")) {
|
|
90
|
+
result = stmt.executeInsert();
|
|
91
|
+
} else {
|
|
92
|
+
stmt.execute();
|
|
93
|
+
result = -1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
int changes = (int) db.compileStatement("SELECT changes()").simpleQueryForLong();
|
|
97
|
+
|
|
98
|
+
JSObject ret = new JSObject();
|
|
99
|
+
ret.put("rows", new JSArray());
|
|
100
|
+
ret.put("rowsAffected", changes);
|
|
101
|
+
if (result > 0) {
|
|
102
|
+
ret.put("insertId", result);
|
|
103
|
+
}
|
|
104
|
+
return ret;
|
|
105
|
+
} finally {
|
|
106
|
+
if (stmt != null) {
|
|
107
|
+
stmt.close();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public void beginTransaction() throws Exception {
|
|
113
|
+
if (inTransaction) {
|
|
114
|
+
throw new Exception("Transaction already active");
|
|
115
|
+
}
|
|
116
|
+
db.beginTransaction();
|
|
117
|
+
inTransaction = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public void commitTransaction() throws Exception {
|
|
121
|
+
if (!inTransaction) {
|
|
122
|
+
throw new Exception("No transaction active");
|
|
123
|
+
}
|
|
124
|
+
db.setTransactionSuccessful();
|
|
125
|
+
db.endTransaction();
|
|
126
|
+
inTransaction = false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public void rollbackTransaction() throws Exception {
|
|
130
|
+
if (!inTransaction) {
|
|
131
|
+
throw new Exception("No transaction active");
|
|
132
|
+
}
|
|
133
|
+
db.endTransaction();
|
|
134
|
+
inTransaction = false;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private String[] convertParamsToStringArray(JSArray params) throws Exception {
|
|
138
|
+
if (params == null || params.length() == 0) {
|
|
139
|
+
return new String[0];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
List<String> args = new ArrayList<>();
|
|
143
|
+
for (int i = 0; i < params.length(); i++) {
|
|
144
|
+
Object value = params.get(i);
|
|
145
|
+
|
|
146
|
+
if (value == null || value == JSONObject.NULL) {
|
|
147
|
+
args.add(null);
|
|
148
|
+
} else if (value instanceof JSONObject) {
|
|
149
|
+
JSONObject obj = (JSONObject) value;
|
|
150
|
+
if (obj.has("_type") && "binary".equals(obj.getString("_type"))) {
|
|
151
|
+
args.add(obj.getString("_data"));
|
|
152
|
+
} else {
|
|
153
|
+
args.add(value.toString());
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
args.add(value.toString());
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return args.toArray(new String[0]);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private void bindParams(SQLiteStatement stmt, JSArray params) throws Exception {
|
|
163
|
+
if (params == null || params.length() == 0) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
for (int i = 0; i < params.length(); i++) {
|
|
168
|
+
Object value = params.get(i);
|
|
169
|
+
int index = i + 1;
|
|
170
|
+
|
|
171
|
+
if (value == null || value == JSONObject.NULL) {
|
|
172
|
+
stmt.bindNull(index);
|
|
173
|
+
} else if (value instanceof String) {
|
|
174
|
+
stmt.bindString(index, (String) value);
|
|
175
|
+
} else if (value instanceof Integer) {
|
|
176
|
+
stmt.bindLong(index, ((Integer) value).longValue());
|
|
177
|
+
} else if (value instanceof Long) {
|
|
178
|
+
stmt.bindLong(index, (Long) value);
|
|
179
|
+
} else if (value instanceof Double) {
|
|
180
|
+
stmt.bindDouble(index, (Double) value);
|
|
181
|
+
} else if (value instanceof Float) {
|
|
182
|
+
stmt.bindDouble(index, ((Float) value).doubleValue());
|
|
183
|
+
} else if (value instanceof Boolean) {
|
|
184
|
+
stmt.bindLong(index, ((Boolean) value) ? 1 : 0);
|
|
185
|
+
} else if (value instanceof JSONObject) {
|
|
186
|
+
JSONObject obj = (JSONObject) value;
|
|
187
|
+
if (obj.has("_type") && "binary".equals(obj.getString("_type"))) {
|
|
188
|
+
String base64 = obj.getString("_data");
|
|
189
|
+
byte[] bytes = Base64.decode(base64, Base64.DEFAULT);
|
|
190
|
+
stmt.bindBlob(index, bytes);
|
|
191
|
+
} else {
|
|
192
|
+
stmt.bindString(index, value.toString());
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
stmt.bindString(index, value.toString());
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private Object getColumnValue(Cursor cursor, int index) {
|
|
201
|
+
int type = cursor.getType(index);
|
|
202
|
+
switch (type) {
|
|
203
|
+
case Cursor.FIELD_TYPE_NULL:
|
|
204
|
+
return JSONObject.NULL;
|
|
205
|
+
case Cursor.FIELD_TYPE_INTEGER:
|
|
206
|
+
return cursor.getLong(index);
|
|
207
|
+
case Cursor.FIELD_TYPE_FLOAT:
|
|
208
|
+
return cursor.getDouble(index);
|
|
209
|
+
case Cursor.FIELD_TYPE_STRING:
|
|
210
|
+
return cursor.getString(index);
|
|
211
|
+
case Cursor.FIELD_TYPE_BLOB:
|
|
212
|
+
byte[] blob = cursor.getBlob(index);
|
|
213
|
+
String base64 = Base64.encodeToString(blob, Base64.NO_WRAP);
|
|
214
|
+
JSObject blobObj = new JSObject();
|
|
215
|
+
blobObj.put("_type", "binary");
|
|
216
|
+
blobObj.put("_data", base64);
|
|
217
|
+
return blobObj;
|
|
218
|
+
default:
|
|
219
|
+
return JSONObject.NULL;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -23,10 +23,10 @@ import org.json.JSONObject;
|
|
|
23
23
|
public class SQLHTTPServer extends NanoHTTPD {
|
|
24
24
|
|
|
25
25
|
private final String token;
|
|
26
|
-
private final Map<String,
|
|
26
|
+
private final Map<String, DatabaseConnection> databases;
|
|
27
27
|
private final Gson gson = new Gson();
|
|
28
28
|
|
|
29
|
-
public SQLHTTPServer(Map<String,
|
|
29
|
+
public SQLHTTPServer(Map<String, DatabaseConnection> databases) throws IOException {
|
|
30
30
|
super(findAvailablePort());
|
|
31
31
|
this.databases = databases;
|
|
32
32
|
this.token = generateToken();
|
|
@@ -55,7 +55,7 @@ public class SQLHTTPServer extends NanoHTTPD {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// Check if database exists
|
|
58
|
-
|
|
58
|
+
DatabaseConnection db = databases.get(database);
|
|
59
59
|
if (db == null) {
|
|
60
60
|
return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "Database not found");
|
|
61
61
|
}
|
|
@@ -82,7 +82,7 @@ public class SQLHTTPServer extends NanoHTTPD {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
private Response handleExecute(IHTTPSession session,
|
|
85
|
+
private Response handleExecute(IHTTPSession session, DatabaseConnection db) throws Exception {
|
|
86
86
|
// Read request body
|
|
87
87
|
String body = readRequestBody(session);
|
|
88
88
|
JsonObject request = JsonParser.parseString(body).getAsJsonObject();
|
|
@@ -125,7 +125,7 @@ public class SQLHTTPServer extends NanoHTTPD {
|
|
|
125
125
|
return newFixedLengthResponse(Response.Status.OK, "application/json", resultJson);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
private Response handleBatch(IHTTPSession session,
|
|
128
|
+
private Response handleBatch(IHTTPSession session, DatabaseConnection db) throws Exception {
|
|
129
129
|
// Read request body
|
|
130
130
|
String body = readRequestBody(session);
|
|
131
131
|
JsonObject request = JsonParser.parseString(body).getAsJsonObject();
|
|
@@ -171,17 +171,17 @@ public class SQLHTTPServer extends NanoHTTPD {
|
|
|
171
171
|
return newFixedLengthResponse(Response.Status.OK, "application/json", results.toString());
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
private Response handleBeginTransaction(
|
|
174
|
+
private Response handleBeginTransaction(DatabaseConnection db) throws Exception {
|
|
175
175
|
db.beginTransaction();
|
|
176
176
|
return newFixedLengthResponse(Response.Status.OK, "application/json", "{}");
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
private Response handleCommitTransaction(
|
|
179
|
+
private Response handleCommitTransaction(DatabaseConnection db) throws Exception {
|
|
180
180
|
db.commitTransaction();
|
|
181
181
|
return newFixedLengthResponse(Response.Status.OK, "application/json", "{}");
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
private Response handleRollbackTransaction(
|
|
184
|
+
private Response handleRollbackTransaction(DatabaseConnection db) throws Exception {
|
|
185
185
|
db.rollbackTransaction();
|
|
186
186
|
return newFixedLengthResponse(Response.Status.OK, "application/json", "{}");
|
|
187
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fast-sql.d.ts","sourceRoot":"","sources":["../../src/fast-sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;;GAKG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAyC;IAEnE;;;;;OAKG;WACU,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"fast-sql.d.ts","sourceRoot":"","sources":["../../src/fast-sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;;GAKG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAyC;IAEnE;;;;;OAKG;WACU,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;IAmB3E;;;;OAIG;WACU,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxD;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAI5D;;OAEG;WACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3C;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,IAAI,MAAM,EAAE;CAGpC"}
|
package/dist/esm/fast-sql.js
CHANGED
|
@@ -15,8 +15,9 @@ export class FastSQL {
|
|
|
15
15
|
*/
|
|
16
16
|
static async connect(options) {
|
|
17
17
|
// Check if already connected
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const existing = this.connections.get(options.database);
|
|
19
|
+
if (existing) {
|
|
20
|
+
return existing;
|
|
20
21
|
}
|
|
21
22
|
// Connect via native plugin
|
|
22
23
|
const info = await CapgoCapacitorFastSql.connect(options);
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export * from './definitions';
|
|
|
2
2
|
export { CapgoCapacitorFastSql } from './plugin';
|
|
3
3
|
export { FastSQL } from './fast-sql';
|
|
4
4
|
export { SQLConnection } from './sql-connection';
|
|
5
|
+
export { KeyValueStore } from './key-value';
|
|
6
|
+
export type { KeyValueStoreOptions, KeyValueValue } from './key-value';
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { SQLConnectionOptions } from './definitions';
|
|
2
|
+
import type { SQLConnection } from './sql-connection';
|
|
3
|
+
export type KeyValueValue = string | number | boolean | null | Uint8Array | Record<string, unknown> | unknown[];
|
|
4
|
+
export interface KeyValueStoreOptions extends SQLConnectionOptions {
|
|
5
|
+
store?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Key-value storage backed by the FastSQL database connection.
|
|
9
|
+
*
|
|
10
|
+
* This is a lightweight wrapper for mobile-focused secure storage use cases.
|
|
11
|
+
*/
|
|
12
|
+
export declare class KeyValueStore {
|
|
13
|
+
private connection;
|
|
14
|
+
private store;
|
|
15
|
+
private initialized;
|
|
16
|
+
private ownsConnection;
|
|
17
|
+
private closed;
|
|
18
|
+
private constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Open (or create) a key-value store for the given database.
|
|
21
|
+
*/
|
|
22
|
+
static open(options: KeyValueStoreOptions): Promise<KeyValueStore>;
|
|
23
|
+
/**
|
|
24
|
+
* Create a key-value store from an existing SQLConnection.
|
|
25
|
+
* Note: The caller retains ownership and is responsible for closing the connection.
|
|
26
|
+
*/
|
|
27
|
+
static fromConnection(connection: SQLConnection, store?: string): Promise<KeyValueStore>;
|
|
28
|
+
/**
|
|
29
|
+
* Close the key-value store and release resources.
|
|
30
|
+
* Only disconnects the database if this store owns the connection (created via open()).
|
|
31
|
+
*/
|
|
32
|
+
close(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Store a value by key.
|
|
35
|
+
*/
|
|
36
|
+
set(key: string, value: KeyValueValue): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Retrieve a value by key. Returns null if the key is missing.
|
|
39
|
+
*/
|
|
40
|
+
get(key: string): Promise<KeyValueValue | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Check if a key exists.
|
|
43
|
+
*/
|
|
44
|
+
has(key: string): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Remove a single key.
|
|
47
|
+
*/
|
|
48
|
+
remove(key: string): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Clear all keys for the current store.
|
|
51
|
+
*/
|
|
52
|
+
clear(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* List all keys for the current store.
|
|
55
|
+
*/
|
|
56
|
+
keys(): Promise<string[]>;
|
|
57
|
+
private ensureSchema;
|
|
58
|
+
private encodeValue;
|
|
59
|
+
private decodeValue;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=key-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-value.d.ts","sourceRoot":"","sources":["../../src/key-value.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAoB,MAAM,eAAe,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,CAAC;AAEhH,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;IAKP;;OAEG;WACU,IAAI,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;IASxE;;;OAGG;WACU,cAAc,CAAC,UAAU,EAAE,aAAa,EAAE,KAAK,SAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAMjG;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3D;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAerD;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASxC;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAMjB,YAAY;IAW1B,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,WAAW;CAsCpB"}
|