@capgo/capacitor-fast-sql 7.0.1
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 +18 -0
- package/Package.swift +30 -0
- package/README.md +340 -0
- package/android/build.gradle +60 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/CapgoCapacitorFastSqlPlugin.java +220 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/SQLDatabase.java +231 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/SQLHTTPServer.java +229 -0
- package/dist/esm/definitions.d.ts +225 -0
- package/dist/esm/definitions.d.ts.map +1 -0
- package/dist/esm/definitions.js +10 -0
- package/dist/esm/helpers.d.ts +7 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +6 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/native-sql.d.ts +42 -0
- package/dist/esm/native-sql.d.ts.map +1 -0
- package/dist/esm/native-sql.js +69 -0
- package/dist/esm/plugin.d.ts +3 -0
- package/dist/esm/plugin.d.ts.map +1 -0
- package/dist/esm/plugin.js +4 -0
- package/dist/esm/sql-connection.d.ts +94 -0
- package/dist/esm/sql-connection.d.ts.map +1 -0
- package/dist/esm/sql-connection.js +246 -0
- package/dist/esm/web.d.ts +67 -0
- package/dist/esm/web.d.ts.map +1 -0
- package/dist/esm/web.js +215 -0
- package/dist/plugin.cjs.js +557 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +560 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/CapgoCapacitorFastSqlPlugin.swift +202 -0
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLDatabase.swift +215 -0
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLHTTPServer.swift +311 -0
- package/package.json +90 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'CapgoCapacitorFastSql'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '14.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.dependency 'Telegraph', '~> 0.30'
|
|
17
|
+
s.swift_version = '5.1'
|
|
18
|
+
end
|
package/Package.swift
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// swift-tools-version: 5.9
|
|
2
|
+
import PackageDescription
|
|
3
|
+
|
|
4
|
+
let package = Package(
|
|
5
|
+
name: "CapgoCapacitorFastSql",
|
|
6
|
+
platforms: [.iOS(.v14)],
|
|
7
|
+
products: [
|
|
8
|
+
.library(
|
|
9
|
+
name: "CapgoCapacitorFastSql",
|
|
10
|
+
targets: ["CapgoCapacitorFastSqlPlugin"])
|
|
11
|
+
],
|
|
12
|
+
dependencies: [
|
|
13
|
+
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
|
|
14
|
+
.package(url: "https://github.com/Building42/Telegraph.git", from: "0.30.0")
|
|
15
|
+
],
|
|
16
|
+
targets: [
|
|
17
|
+
.target(
|
|
18
|
+
name: "CapgoCapacitorFastSqlPlugin",
|
|
19
|
+
dependencies: [
|
|
20
|
+
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
21
|
+
.product(name: "Cordova", package: "capacitor-swift-pm"),
|
|
22
|
+
.product(name: "Telegraph", package: "Telegraph")
|
|
23
|
+
],
|
|
24
|
+
path: "ios/Sources/CapgoCapacitorFastSqlPlugin"),
|
|
25
|
+
.testTarget(
|
|
26
|
+
name: "CapgoCapacitorFastSqlPluginTests",
|
|
27
|
+
dependencies: ["CapgoCapacitorFastSqlPlugin"],
|
|
28
|
+
path: "ios/Tests/CapgoCapacitorFastSqlPluginTests")
|
|
29
|
+
]
|
|
30
|
+
)
|
package/README.md
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# @capgo/capacitor-fast-sql
|
|
2
|
+
<a href="https://capgo.app/"><img src='https://raw.githubusercontent.com/Cap-go/capgo/main/assets/capgo_banner.png' alt='Capgo - Instant updates for capacitor'/></a>
|
|
3
|
+
|
|
4
|
+
<div align="center">
|
|
5
|
+
<h2><a href="https://capgo.app/?ref=plugin"> ➡️ Get Instant updates for your App with Capgo</a></h2>
|
|
6
|
+
<h2><a href="https://capgo.app/consulting/?ref=plugin"> Missing a feature? We'll build the plugin for you 💪</a></h2>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
High-performance native SQLite plugin with HTTP server for efficient sync operations and IndexedDB replacement.
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
The most complete doc is available here: https://capgo.app/docs/plugins/fast-sql/
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @capgo/capacitor-fast-sql
|
|
19
|
+
npx cap sync
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
This plugin provides direct native SQLite database access with a custom communication protocol inspired by [capacitor-blob-writer](https://github.com/diachedelic/capacitor-blob-writer). Instead of using Capacitor's standard bridge (which serializes data inefficiently), it establishes a local HTTP server for optimal performance with large datasets and sync operations.
|
|
25
|
+
|
|
26
|
+
### Key Features
|
|
27
|
+
|
|
28
|
+
- **Custom HTTP Protocol**: Bypasses Capacitor's bridge for up to 25x faster performance with large data
|
|
29
|
+
- **Direct Native SQLite**: Full SQL support with transactions, batch operations, and binary data
|
|
30
|
+
- **Sync-Friendly**: Designed for local sync systems (CRDTs, operational transforms, etc.)
|
|
31
|
+
- **IndexedDB Replacement**: Provides reliable alternative to broken/limited IndexedDB implementations
|
|
32
|
+
- **Cross-Platform**: iOS, Android, and Web (using sql.js + IndexedDB for persistence)
|
|
33
|
+
|
|
34
|
+
## iOS Configuration
|
|
35
|
+
|
|
36
|
+
Add to your `Info.plist` if you encounter any issues:
|
|
37
|
+
|
|
38
|
+
```xml
|
|
39
|
+
<key>NSAppTransportSecurity</key>
|
|
40
|
+
<dict>
|
|
41
|
+
<key>NSAllowsLocalNetworking</key>
|
|
42
|
+
<true/>
|
|
43
|
+
</dict>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Android Configuration
|
|
47
|
+
|
|
48
|
+
Add to your `AndroidManifest.xml` if needed:
|
|
49
|
+
|
|
50
|
+
```xml
|
|
51
|
+
<application
|
|
52
|
+
android:usesCleartextTraffic="true">
|
|
53
|
+
...
|
|
54
|
+
</application>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Basic Example
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { NativeSQL } from '@capgo/capacitor-fast-sql';
|
|
63
|
+
|
|
64
|
+
// Connect to database
|
|
65
|
+
const db = await NativeSQL.connect({ database: 'myapp' });
|
|
66
|
+
|
|
67
|
+
// Create table
|
|
68
|
+
await db.execute(`
|
|
69
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
70
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
+
name TEXT NOT NULL,
|
|
72
|
+
email TEXT UNIQUE
|
|
73
|
+
)
|
|
74
|
+
`);
|
|
75
|
+
|
|
76
|
+
// Insert data
|
|
77
|
+
const result = await db.run(
|
|
78
|
+
'INSERT INTO users (name, email) VALUES (?, ?)',
|
|
79
|
+
['John Doe', 'john@example.com']
|
|
80
|
+
);
|
|
81
|
+
console.log('Inserted row ID:', result.insertId);
|
|
82
|
+
|
|
83
|
+
// Query data
|
|
84
|
+
const users = await db.query('SELECT * FROM users WHERE name LIKE ?', ['John%']);
|
|
85
|
+
console.log('Users:', users);
|
|
86
|
+
|
|
87
|
+
// Close connection
|
|
88
|
+
await NativeSQL.disconnect('myapp');
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Transaction Example
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const db = await NativeSQL.connect({ database: 'myapp' });
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
await db.transaction(async (tx) => {
|
|
98
|
+
await tx.run('INSERT INTO accounts (name, balance) VALUES (?, ?)', ['Alice', 1000]);
|
|
99
|
+
await tx.run('INSERT INTO accounts (name, balance) VALUES (?, ?)', ['Bob', 500]);
|
|
100
|
+
await tx.run('UPDATE accounts SET balance = balance - 100 WHERE name = ?', ['Alice']);
|
|
101
|
+
await tx.run('UPDATE accounts SET balance = balance + 100 WHERE name = ?', ['Bob']);
|
|
102
|
+
});
|
|
103
|
+
console.log('Transaction successful!');
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('Transaction failed:', error);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Batch Operations
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const db = await NativeSQL.connect({ database: 'myapp' });
|
|
113
|
+
|
|
114
|
+
const results = await db.executeBatch([
|
|
115
|
+
{ statement: 'INSERT INTO logs (message) VALUES (?)', params: ['Log 1'] },
|
|
116
|
+
{ statement: 'INSERT INTO logs (message) VALUES (?)', params: ['Log 2'] },
|
|
117
|
+
{ statement: 'INSERT INTO logs (message) VALUES (?)', params: ['Log 3'] },
|
|
118
|
+
]);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## API
|
|
122
|
+
|
|
123
|
+
<docgen-index>
|
|
124
|
+
|
|
125
|
+
* [`connect(...)`](#connect)
|
|
126
|
+
* [`disconnect(...)`](#disconnect)
|
|
127
|
+
* [`getServerInfo(...)`](#getserverinfo)
|
|
128
|
+
* [`execute(...)`](#execute)
|
|
129
|
+
* [`beginTransaction(...)`](#begintransaction)
|
|
130
|
+
* [`commitTransaction(...)`](#committransaction)
|
|
131
|
+
* [`rollbackTransaction(...)`](#rollbacktransaction)
|
|
132
|
+
* [`getPluginVersion()`](#getpluginversion)
|
|
133
|
+
* [Interfaces](#interfaces)
|
|
134
|
+
* [Enums](#enums)
|
|
135
|
+
|
|
136
|
+
</docgen-index>
|
|
137
|
+
|
|
138
|
+
<docgen-api>
|
|
139
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
140
|
+
|
|
141
|
+
Native SQL Plugin for high-performance SQLite database access.
|
|
142
|
+
|
|
143
|
+
This plugin uses a custom HTTP-based protocol for efficient data transfer,
|
|
144
|
+
bypassing Capacitor's standard bridge for better performance with sync operations.
|
|
145
|
+
|
|
146
|
+
### connect(...)
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
connect(options: SQLConnectionOptions) => Promise<{ port: number; token: string; database: string; }>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Initialize the database connection and start the HTTP server.
|
|
153
|
+
|
|
154
|
+
| Param | Type | Description |
|
|
155
|
+
| ------------- | --------------------------------------------------------------------- | ------------------- |
|
|
156
|
+
| **`options`** | <code><a href="#sqlconnectionoptions">SQLConnectionOptions</a></code> | - Connection options |
|
|
157
|
+
|
|
158
|
+
**Returns:** <code>Promise<{ port: number; token: string; database: string; }></code>
|
|
159
|
+
|
|
160
|
+
**Since:** 0.0.1
|
|
161
|
+
|
|
162
|
+
--------------------
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
### disconnect(...)
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
disconnect(options: { database: string; }) => Promise<void>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Close database connection and stop the HTTP server.
|
|
172
|
+
|
|
173
|
+
| Param | Type | Description |
|
|
174
|
+
| ------------- | ---------------------------------- | --------------------- |
|
|
175
|
+
| **`options`** | <code>{ database: string; }</code> | - Database name to close |
|
|
176
|
+
|
|
177
|
+
**Since:** 0.0.1
|
|
178
|
+
|
|
179
|
+
--------------------
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
### getServerInfo(...)
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
getServerInfo(options: { database: string; }) => Promise<{ port: number; token: string; }>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Get the HTTP server port and token for direct communication.
|
|
189
|
+
|
|
190
|
+
| Param | Type | Description |
|
|
191
|
+
| ------------- | ---------------------------------- | --------------- |
|
|
192
|
+
| **`options`** | <code>{ database: string; }</code> | - Database name |
|
|
193
|
+
|
|
194
|
+
**Returns:** <code>Promise<{ port: number; token: string; }></code>
|
|
195
|
+
|
|
196
|
+
**Since:** 0.0.1
|
|
197
|
+
|
|
198
|
+
--------------------
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
### execute(...)
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
execute(options: { database: string; statement: string; params?: SQLValue[]; }) => Promise<SQLResult>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Execute a SQL query via Capacitor bridge (for simple queries).
|
|
208
|
+
For better performance with large datasets, use the HTTP protocol directly via SQLConnection class.
|
|
209
|
+
|
|
210
|
+
| Param | Type | Description |
|
|
211
|
+
| ------------- | -------------------------------------------------------------------------------------------- | ------------------ |
|
|
212
|
+
| **`options`** | <code>{ database: string; statement: string; params?: <a href="#sqlvalue">SQLValue</a>[]; }</code> | - Query parameters |
|
|
213
|
+
|
|
214
|
+
**Returns:** <code>Promise<<a href="#sqlresult">SQLResult</a>></code>
|
|
215
|
+
|
|
216
|
+
**Since:** 0.0.1
|
|
217
|
+
|
|
218
|
+
--------------------
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
### beginTransaction(...)
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
beginTransaction(options: { database: string; isolationLevel?: IsolationLevel; }) => Promise<void>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Begin a database transaction.
|
|
228
|
+
|
|
229
|
+
| Param | Type | Description |
|
|
230
|
+
| ------------- | ------------------------------------------------------------------------------------------------------ | ----------------------- |
|
|
231
|
+
| **`options`** | <code>{ database: string; isolationLevel?: <a href="#isolationlevel">IsolationLevel</a>; }</code> | - Transaction options |
|
|
232
|
+
|
|
233
|
+
**Since:** 0.0.1
|
|
234
|
+
|
|
235
|
+
--------------------
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
### commitTransaction(...)
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
commitTransaction(options: { database: string; }) => Promise<void>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Commit the current transaction.
|
|
245
|
+
|
|
246
|
+
| Param | Type | Description |
|
|
247
|
+
| ------------- | ---------------------------------- | --------------- |
|
|
248
|
+
| **`options`** | <code>{ database: string; }</code> | - Database name |
|
|
249
|
+
|
|
250
|
+
**Since:** 0.0.1
|
|
251
|
+
|
|
252
|
+
--------------------
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
### rollbackTransaction(...)
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
rollbackTransaction(options: { database: string; }) => Promise<void>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Rollback the current transaction.
|
|
262
|
+
|
|
263
|
+
| Param | Type | Description |
|
|
264
|
+
| ------------- | ---------------------------------- | --------------- |
|
|
265
|
+
| **`options`** | <code>{ database: string; }</code> | - Database name |
|
|
266
|
+
|
|
267
|
+
**Since:** 0.0.1
|
|
268
|
+
|
|
269
|
+
--------------------
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
### getPluginVersion()
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
getPluginVersion() => Promise<{ version: string; }>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Get the native Capacitor plugin version.
|
|
279
|
+
|
|
280
|
+
**Returns:** <code>Promise<{ version: string; }></code>
|
|
281
|
+
|
|
282
|
+
**Since:** 0.0.1
|
|
283
|
+
|
|
284
|
+
--------------------
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
### Interfaces
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
#### SQLConnectionOptions
|
|
291
|
+
|
|
292
|
+
Database connection options
|
|
293
|
+
|
|
294
|
+
| Prop | Type | Description |
|
|
295
|
+
| ------------------- | -------------------- | --------------------------------------------------- |
|
|
296
|
+
| **`database`** | <code>string</code> | Database name (file will be created in app data directory) |
|
|
297
|
+
| **`encrypted`** | <code>boolean</code> | Enable encryption (iOS/Android only) |
|
|
298
|
+
| **`encryptionKey`** | <code>string</code> | Encryption key (required if encrypted is true) |
|
|
299
|
+
| **`readOnly`** | <code>boolean</code> | Read-only mode |
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
#### SQLResult
|
|
303
|
+
|
|
304
|
+
Result of a SQL query execution
|
|
305
|
+
|
|
306
|
+
| Prop | Type | Description |
|
|
307
|
+
| ------------------- | --------------------------------------------- | ---------------------------------------------------------------- |
|
|
308
|
+
| **`rows`** | <code><a href="#sqlrow">SQLRow</a>[]</code> | Rows returned by the query (for SELECT statements) |
|
|
309
|
+
| **`rowsAffected`** | <code>number</code> | Number of rows affected by the query (for INSERT/UPDATE/DELETE) |
|
|
310
|
+
| **`insertId`** | <code>number</code> | ID of the last inserted row (for INSERT statements with auto-increment) |
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
#### SQLRow
|
|
314
|
+
|
|
315
|
+
SQL row result - values indexed by column name
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
### Enums
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
#### IsolationLevel
|
|
322
|
+
|
|
323
|
+
Transaction isolation levels
|
|
324
|
+
|
|
325
|
+
| Members | Value |
|
|
326
|
+
| ---------------------- | ------------------------------ |
|
|
327
|
+
| **`ReadUncommitted`** | <code>'READ UNCOMMITTED'</code> |
|
|
328
|
+
| **`ReadCommitted`** | <code>'READ COMMITTED'</code> |
|
|
329
|
+
| **`RepeatableRead`** | <code>'REPEATABLE READ'</code> |
|
|
330
|
+
| **`Serializable`** | <code>'SERIALIZABLE'</code> |
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
### Type Aliases
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
#### SQLValue
|
|
337
|
+
|
|
338
|
+
<code>string | number | boolean | null | Uint8Array</code>
|
|
339
|
+
|
|
340
|
+
</docgen-api>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
|
|
4
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
|
|
5
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
repositories {
|
|
10
|
+
mavenCentral()
|
|
11
|
+
google()
|
|
12
|
+
}
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.7.2'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
apply plugin: 'com.android.library'
|
|
19
|
+
|
|
20
|
+
android {
|
|
21
|
+
namespace 'app.capgo.capacitor.fastsql'
|
|
22
|
+
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
|
|
23
|
+
defaultConfig {
|
|
24
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
|
|
25
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
|
|
26
|
+
versionCode 1
|
|
27
|
+
versionName "1.0"
|
|
28
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
29
|
+
}
|
|
30
|
+
buildTypes {
|
|
31
|
+
release {
|
|
32
|
+
minifyEnabled false
|
|
33
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
lintOptions {
|
|
37
|
+
abortOnError false
|
|
38
|
+
}
|
|
39
|
+
compileOptions {
|
|
40
|
+
sourceCompatibility JavaVersion.VERSION_21
|
|
41
|
+
targetCompatibility JavaVersion.VERSION_21
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
repositories {
|
|
46
|
+
google()
|
|
47
|
+
jcenter()
|
|
48
|
+
mavenCentral()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
dependencies {
|
|
52
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
53
|
+
implementation project(':capacitor-android')
|
|
54
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
55
|
+
implementation 'com.google.code.gson:gson:2.10.1'
|
|
56
|
+
implementation 'org.nanohttpd:nanohttpd:2.3.1'
|
|
57
|
+
testImplementation "junit:junit:$junitVersion"
|
|
58
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
59
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
60
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
package app.capgo.capacitor.fastsql;
|
|
2
|
+
|
|
3
|
+
import com.getcapacitor.JSArray;
|
|
4
|
+
import com.getcapacitor.JSObject;
|
|
5
|
+
import com.getcapacitor.Plugin;
|
|
6
|
+
import com.getcapacitor.PluginCall;
|
|
7
|
+
import com.getcapacitor.PluginMethod;
|
|
8
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
9
|
+
|
|
10
|
+
import java.io.File;
|
|
11
|
+
import java.util.HashMap;
|
|
12
|
+
import java.util.Map;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Native SQL Plugin for Android
|
|
16
|
+
*
|
|
17
|
+
* This plugin uses a custom HTTP server for efficient data transfer,
|
|
18
|
+
* bypassing Capacitor's standard bridge for better performance.
|
|
19
|
+
*/
|
|
20
|
+
@CapacitorPlugin(name = "CapgoCapacitorFastSql")
|
|
21
|
+
public class CapgoCapacitorFastSqlPlugin extends Plugin {
|
|
22
|
+
|
|
23
|
+
private Map<String, SQLDatabase> databases = new HashMap<>();
|
|
24
|
+
private SQLHTTPServer server;
|
|
25
|
+
|
|
26
|
+
@PluginMethod
|
|
27
|
+
public void connect(PluginCall call) {
|
|
28
|
+
String database = call.getString("database");
|
|
29
|
+
if (database == null) {
|
|
30
|
+
call.reject("Database name is required");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Check if already connected
|
|
35
|
+
if (databases.containsKey(database)) {
|
|
36
|
+
if (server != null) {
|
|
37
|
+
JSObject ret = new JSObject();
|
|
38
|
+
ret.put("port", server.getPort());
|
|
39
|
+
ret.put("token", server.getToken());
|
|
40
|
+
ret.put("database", database);
|
|
41
|
+
call.resolve(ret);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
// Get database path
|
|
48
|
+
File dbFile = getDatabasePath(database);
|
|
49
|
+
|
|
50
|
+
// Open database
|
|
51
|
+
SQLDatabase db = new SQLDatabase(dbFile.getAbsolutePath());
|
|
52
|
+
databases.put(database, db);
|
|
53
|
+
|
|
54
|
+
// Start HTTP server if not already running
|
|
55
|
+
if (server == null) {
|
|
56
|
+
server = new SQLHTTPServer(databases);
|
|
57
|
+
server.start();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
JSObject ret = new JSObject();
|
|
61
|
+
ret.put("port", server.getPort());
|
|
62
|
+
ret.put("token", server.getToken());
|
|
63
|
+
ret.put("database", database);
|
|
64
|
+
call.resolve(ret);
|
|
65
|
+
} catch (Exception e) {
|
|
66
|
+
call.reject("Failed to connect to database: " + e.getMessage(), e);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@PluginMethod
|
|
71
|
+
public void disconnect(PluginCall call) {
|
|
72
|
+
String database = call.getString("database");
|
|
73
|
+
if (database == null) {
|
|
74
|
+
call.reject("Database name is required");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
SQLDatabase db = databases.get(database);
|
|
79
|
+
if (db == null) {
|
|
80
|
+
call.reject("Database '" + database + "' is not connected");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
db.close();
|
|
85
|
+
databases.remove(database);
|
|
86
|
+
|
|
87
|
+
// Stop server if no more databases
|
|
88
|
+
if (databases.isEmpty() && server != null) {
|
|
89
|
+
server.stop();
|
|
90
|
+
server = null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
call.resolve();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@PluginMethod
|
|
97
|
+
public void getServerInfo(PluginCall call) {
|
|
98
|
+
String database = call.getString("database");
|
|
99
|
+
if (database == null) {
|
|
100
|
+
call.reject("Database name is required");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!databases.containsKey(database)) {
|
|
105
|
+
call.reject("Database '" + database + "' is not connected");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (server == null) {
|
|
110
|
+
call.reject("Server is not running");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
JSObject ret = new JSObject();
|
|
115
|
+
ret.put("port", server.getPort());
|
|
116
|
+
ret.put("token", server.getToken());
|
|
117
|
+
call.resolve(ret);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@PluginMethod
|
|
121
|
+
public void execute(PluginCall call) {
|
|
122
|
+
String database = call.getString("database");
|
|
123
|
+
if (database == null) {
|
|
124
|
+
call.reject("Database name is required");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
String statement = call.getString("statement");
|
|
129
|
+
if (statement == null) {
|
|
130
|
+
call.reject("Statement is required");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
SQLDatabase db = databases.get(database);
|
|
135
|
+
if (db == null) {
|
|
136
|
+
call.reject("Database '" + database + "' is not connected");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
JSArray params = call.getArray("params", new JSArray());
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
JSObject result = db.execute(statement, params);
|
|
144
|
+
call.resolve(result);
|
|
145
|
+
} catch (Exception e) {
|
|
146
|
+
call.reject("Failed to execute statement: " + e.getMessage(), e);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@PluginMethod
|
|
151
|
+
public void beginTransaction(PluginCall call) {
|
|
152
|
+
String database = call.getString("database");
|
|
153
|
+
if (database == null) {
|
|
154
|
+
call.reject("Database name is required");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
SQLDatabase db = databases.get(database);
|
|
159
|
+
if (db == null) {
|
|
160
|
+
call.reject("Database '" + database + "' is not connected");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
db.beginTransaction();
|
|
166
|
+
call.resolve();
|
|
167
|
+
} catch (Exception e) {
|
|
168
|
+
call.reject("Failed to begin transaction: " + e.getMessage(), e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@PluginMethod
|
|
173
|
+
public void commitTransaction(PluginCall call) {
|
|
174
|
+
String database = call.getString("database");
|
|
175
|
+
if (database == null) {
|
|
176
|
+
call.reject("Database name is required");
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
SQLDatabase db = databases.get(database);
|
|
181
|
+
if (db == null) {
|
|
182
|
+
call.reject("Database '" + database + "' is not connected");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
db.commitTransaction();
|
|
188
|
+
call.resolve();
|
|
189
|
+
} catch (Exception e) {
|
|
190
|
+
call.reject("Failed to commit transaction: " + e.getMessage(), e);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
@PluginMethod
|
|
195
|
+
public void rollbackTransaction(PluginCall call) {
|
|
196
|
+
String database = call.getString("database");
|
|
197
|
+
if (database == null) {
|
|
198
|
+
call.reject("Database name is required");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
SQLDatabase db = databases.get(database);
|
|
203
|
+
if (db == null) {
|
|
204
|
+
call.reject("Database '" + database + "' is not connected");
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
db.rollbackTransaction();
|
|
210
|
+
call.resolve();
|
|
211
|
+
} catch (Exception e) {
|
|
212
|
+
call.reject("Failed to rollback transaction: " + e.getMessage(), e);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private File getDatabasePath(String database) {
|
|
217
|
+
File dataDir = getContext().getFilesDir();
|
|
218
|
+
return new File(dataDir, database + ".db");
|
|
219
|
+
}
|
|
220
|
+
}
|