@powersync/common 1.57.1 → 2.0.0
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/lib/attachments/AttachmentContext.d.ts +5 -5
- package/lib/attachments/AttachmentContext.js +6 -2
- package/lib/attachments/AttachmentContext.js.map +1 -1
- package/lib/attachments/AttachmentQueue.d.ts +6 -6
- package/lib/attachments/AttachmentQueue.js +9 -8
- package/lib/attachments/AttachmentQueue.js.map +1 -1
- package/lib/attachments/AttachmentService.d.ts +3 -3
- package/lib/attachments/AttachmentService.js +4 -3
- package/lib/attachments/AttachmentService.js.map +1 -1
- package/lib/attachments/Schema.d.ts +2 -2
- package/lib/attachments/SyncingService.d.ts +2 -2
- package/lib/attachments/SyncingService.js +21 -6
- package/lib/attachments/SyncingService.js.map +1 -1
- package/lib/client/{AbstractPowerSyncDatabase.d.ts → CommonPowerSyncDatabase.d.ts} +56 -232
- package/lib/client/CommonPowerSyncDatabase.js +2 -0
- package/lib/client/CommonPowerSyncDatabase.js.map +1 -0
- package/lib/client/SQLOpenFactory.d.ts +35 -13
- package/lib/client/SQLOpenFactory.js +1 -25
- package/lib/client/SQLOpenFactory.js.map +1 -1
- package/lib/client/compilableQueryWatch.d.ts +2 -2
- package/lib/client/compilableQueryWatch.js +1 -2
- package/lib/client/compilableQueryWatch.js.map +1 -1
- package/lib/client/connection/PowerSyncBackendConnector.d.ts +3 -3
- package/lib/client/runOnSchemaChange.d.ts +2 -2
- package/lib/client/runOnSchemaChange.js.map +1 -1
- package/lib/client/sync/bucket/CrudEntry.d.ts +3 -34
- package/lib/client/sync/bucket/CrudEntry.js +0 -99
- package/lib/client/sync/bucket/CrudEntry.js.map +1 -1
- package/lib/client/sync/options.d.ts +65 -0
- package/lib/client/sync/options.js +25 -0
- package/lib/client/sync/options.js.map +1 -0
- package/lib/client/sync/sync-streams.d.ts +1 -1
- package/lib/client/triggers/TriggerManager.d.ts +9 -38
- package/lib/client/watched/GetAllQuery.d.ts +3 -3
- package/lib/client/watched/GetAllQuery.js +1 -1
- package/lib/client/watched/GetAllQuery.js.map +1 -1
- package/lib/client/watched/WatchedQuery.d.ts +2 -10
- package/lib/client/watched/WatchedQuery.js +0 -11
- package/lib/client/watched/WatchedQuery.js.map +1 -1
- package/lib/client/watched/processors/DifferentialQueryProcessor.d.ts +0 -50
- package/lib/client/watched/processors/DifferentialQueryProcessor.js +1 -176
- package/lib/client/watched/processors/DifferentialQueryProcessor.js.map +1 -1
- package/lib/client/watched/processors/OnChangeQueryProcessor.d.ts +0 -22
- package/lib/client/watched/processors/OnChangeQueryProcessor.js +1 -82
- package/lib/client/watched/processors/OnChangeQueryProcessor.js.map +1 -1
- package/lib/db/DBAdapter.d.ts +72 -154
- package/lib/db/DBAdapter.js +70 -108
- package/lib/db/DBAdapter.js.map +1 -1
- package/lib/db/QueryResult.d.ts +104 -0
- package/lib/db/QueryResult.js +96 -0
- package/lib/db/QueryResult.js.map +1 -0
- package/lib/db/crud/SyncProgress.d.ts +1 -13
- package/lib/db/crud/SyncProgress.js +1 -62
- package/lib/db/crud/SyncProgress.js.map +1 -1
- package/lib/db/crud/SyncStatus.d.ts +32 -66
- package/lib/db/crud/SyncStatus.js +1 -253
- package/lib/db/crud/SyncStatus.js.map +1 -1
- package/lib/db/schema/Column.d.ts +0 -7
- package/lib/db/schema/Column.js +0 -7
- package/lib/db/schema/Column.js.map +1 -1
- package/lib/db/schema/Index.d.ts +2 -6
- package/lib/db/schema/Index.js +1 -4
- package/lib/db/schema/Index.js.map +1 -1
- package/lib/db/schema/IndexedColumn.d.ts +2 -6
- package/lib/db/schema/IndexedColumn.js +1 -4
- package/lib/db/schema/IndexedColumn.js.map +1 -1
- package/lib/db/schema/Schema.d.ts +4 -28
- package/lib/db/schema/Schema.js.map +1 -1
- package/lib/db/schema/Table.d.ts +50 -96
- package/lib/db/schema/Table.js +83 -91
- package/lib/db/schema/Table.js.map +1 -1
- package/lib/index.d.ts +5 -21
- package/lib/index.js +5 -22
- package/lib/index.js.map +1 -1
- package/lib/utils/BaseObserver.d.ts +1 -1
- package/lib/utils/BaseObserver.js +1 -1
- package/lib/utils/Logger.d.ts +52 -23
- package/lib/utils/Logger.js +35 -33
- package/lib/utils/Logger.js.map +1 -1
- package/lib/utils/MetaBaseObserver.d.ts +11 -11
- package/lib/utils/MetaBaseObserver.js +1 -50
- package/lib/utils/MetaBaseObserver.js.map +1 -1
- package/lib/utils/mutex.d.ts +3 -53
- package/lib/utils/mutex.js +1 -156
- package/lib/utils/mutex.js.map +1 -1
- package/package.json +8 -45
- package/src/attachments/AttachmentContext.ts +11 -10
- package/src/attachments/AttachmentQueue.ts +15 -14
- package/src/attachments/AttachmentService.ts +7 -6
- package/src/attachments/Schema.ts +2 -2
- package/src/attachments/SyncingService.ts +23 -9
- package/src/client/CommonPowerSyncDatabase.ts +540 -0
- package/src/client/SQLOpenFactory.ts +38 -22
- package/src/client/compilableQueryWatch.ts +3 -4
- package/src/client/connection/PowerSyncBackendConnector.ts +3 -3
- package/src/client/runOnSchemaChange.ts +2 -2
- package/src/client/sync/bucket/CrudEntry.ts +4 -104
- package/src/client/sync/options.ts +77 -0
- package/src/client/sync/sync-streams.ts +1 -1
- package/src/client/triggers/TriggerManager.ts +10 -41
- package/src/client/watched/GetAllQuery.ts +3 -3
- package/src/client/watched/WatchedQuery.ts +2 -15
- package/src/client/watched/processors/DifferentialQueryProcessor.ts +0 -223
- package/src/client/watched/processors/OnChangeQueryProcessor.ts +0 -111
- package/src/db/DBAdapter.ts +141 -226
- package/src/db/QueryResult.ts +195 -0
- package/src/db/crud/SyncProgress.ts +2 -42
- package/src/db/crud/SyncStatus.ts +45 -220
- package/src/db/schema/Column.ts +0 -8
- package/src/db/schema/Index.ts +3 -6
- package/src/db/schema/IndexedColumn.ts +3 -6
- package/src/db/schema/Schema.ts +4 -4
- package/src/db/schema/Table.ts +111 -186
- package/src/index.ts +5 -21
- package/src/utils/BaseObserver.ts +1 -1
- package/src/utils/Logger.ts +80 -34
- package/src/utils/MetaBaseObserver.ts +14 -60
- package/src/utils/mutex.ts +4 -201
- package/dist/bundle.cjs +0 -14390
- package/dist/bundle.cjs.map +0 -1
- package/dist/bundle.mjs +0 -14309
- package/dist/bundle.mjs.map +0 -1
- package/dist/bundle.node.cjs +0 -12021
- package/dist/bundle.node.cjs.map +0 -1
- package/dist/bundle.node.mjs +0 -11940
- package/dist/bundle.node.mjs.map +0 -1
- package/dist/index.d.cts +0 -4651
- package/legacy/sync_protocol.d.ts +0 -103
- package/lib/client/AbstractPowerSyncDatabase.js +0 -990
- package/lib/client/AbstractPowerSyncDatabase.js.map +0 -1
- package/lib/client/AbstractPowerSyncOpenFactory.d.ts +0 -28
- package/lib/client/AbstractPowerSyncOpenFactory.js +0 -28
- package/lib/client/AbstractPowerSyncOpenFactory.js.map +0 -1
- package/lib/client/ConnectionManager.d.ts +0 -115
- package/lib/client/ConnectionManager.js +0 -294
- package/lib/client/ConnectionManager.js.map +0 -1
- package/lib/client/CustomQuery.d.ts +0 -22
- package/lib/client/CustomQuery.js +0 -43
- package/lib/client/CustomQuery.js.map +0 -1
- package/lib/client/constants.d.ts +0 -4
- package/lib/client/constants.js +0 -5
- package/lib/client/constants.js.map +0 -1
- package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +0 -56
- package/lib/client/sync/bucket/BucketStorageAdapter.js +0 -29
- package/lib/client/sync/bucket/BucketStorageAdapter.js.map +0 -1
- package/lib/client/sync/bucket/SqliteBucketStorage.d.ts +0 -37
- package/lib/client/sync/bucket/SqliteBucketStorage.js +0 -165
- package/lib/client/sync/bucket/SqliteBucketStorage.js.map +0 -1
- package/lib/client/sync/stream/AbstractRemote.d.ts +0 -180
- package/lib/client/sync/stream/AbstractRemote.js +0 -505
- package/lib/client/sync/stream/AbstractRemote.js.map +0 -1
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +0 -265
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +0 -705
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +0 -1
- package/lib/client/sync/stream/WebsocketClientTransport.d.ts +0 -15
- package/lib/client/sync/stream/WebsocketClientTransport.js +0 -62
- package/lib/client/sync/stream/WebsocketClientTransport.js.map +0 -1
- package/lib/client/sync/stream/core-instruction.d.ts +0 -77
- package/lib/client/sync/stream/core-instruction.js +0 -30
- package/lib/client/sync/stream/core-instruction.js.map +0 -1
- package/lib/client/triggers/MemoryTriggerClaimManager.d.ts +0 -6
- package/lib/client/triggers/MemoryTriggerClaimManager.js +0 -21
- package/lib/client/triggers/MemoryTriggerClaimManager.js.map +0 -1
- package/lib/client/triggers/TriggerManagerImpl.d.ts +0 -39
- package/lib/client/triggers/TriggerManagerImpl.js +0 -410
- package/lib/client/triggers/TriggerManagerImpl.js.map +0 -1
- package/lib/client/watched/processors/AbstractQueryProcessor.d.ts +0 -68
- package/lib/client/watched/processors/AbstractQueryProcessor.js +0 -151
- package/lib/client/watched/processors/AbstractQueryProcessor.js.map +0 -1
- package/lib/db/ConnectionClosedError.d.ts +0 -12
- package/lib/db/ConnectionClosedError.js +0 -23
- package/lib/db/ConnectionClosedError.js.map +0 -1
- package/lib/db/schema/TableV2.d.ts +0 -11
- package/lib/db/schema/TableV2.js +0 -11
- package/lib/db/schema/TableV2.js.map +0 -1
- package/lib/utils/AbortOperation.d.ts +0 -11
- package/lib/utils/AbortOperation.js +0 -21
- package/lib/utils/AbortOperation.js.map +0 -1
- package/lib/utils/ControlledExecutor.d.ts +0 -31
- package/lib/utils/ControlledExecutor.js +0 -54
- package/lib/utils/ControlledExecutor.js.map +0 -1
- package/lib/utils/async.d.ts +0 -46
- package/lib/utils/async.js +0 -147
- package/lib/utils/async.js.map +0 -1
- package/lib/utils/compatibility.d.ts +0 -8
- package/lib/utils/compatibility.js +0 -9
- package/lib/utils/compatibility.js.map +0 -1
- package/lib/utils/parseQuery.d.ts +0 -12
- package/lib/utils/parseQuery.js +0 -20
- package/lib/utils/parseQuery.js.map +0 -1
- package/lib/utils/queue.d.ts +0 -16
- package/lib/utils/queue.js +0 -42
- package/lib/utils/queue.js.map +0 -1
- package/lib/utils/stream_transform.d.ts +0 -41
- package/lib/utils/stream_transform.js +0 -211
- package/lib/utils/stream_transform.js.map +0 -1
- package/src/client/AbstractPowerSyncDatabase.ts +0 -1408
- package/src/client/AbstractPowerSyncOpenFactory.ts +0 -45
- package/src/client/ConnectionManager.ts +0 -405
- package/src/client/CustomQuery.ts +0 -56
- package/src/client/constants.ts +0 -4
- package/src/client/sync/bucket/BucketStorageAdapter.ts +0 -65
- package/src/client/sync/bucket/SqliteBucketStorage.ts +0 -202
- package/src/client/sync/stream/AbstractRemote.ts +0 -644
- package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +0 -970
- package/src/client/sync/stream/WebsocketClientTransport.ts +0 -82
- package/src/client/sync/stream/core-instruction.ts +0 -109
- package/src/client/triggers/MemoryTriggerClaimManager.ts +0 -25
- package/src/client/triggers/TriggerManagerImpl.ts +0 -501
- package/src/client/watched/processors/AbstractQueryProcessor.ts +0 -226
- package/src/db/ConnectionClosedError.ts +0 -25
- package/src/db/schema/TableV2.ts +0 -11
- package/src/utils/AbortOperation.ts +0 -19
- package/src/utils/ControlledExecutor.ts +0 -78
- package/src/utils/async.ts +0 -185
- package/src/utils/compatibility.ts +0 -9
- package/src/utils/parseQuery.ts +0 -31
- package/src/utils/queue.ts +0 -48
- package/src/utils/stream_transform.ts +0 -260
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { WatchCompatibleQuery, WatchedQuery, WatchedQueryOptions } from '../WatchedQuery.js';
|
|
2
|
-
import {
|
|
3
|
-
AbstractQueryProcessor,
|
|
4
|
-
AbstractQueryProcessorOptions,
|
|
5
|
-
LinkQueryOptions,
|
|
6
|
-
MutableWatchedQueryState
|
|
7
|
-
} from './AbstractQueryProcessor.js';
|
|
8
|
-
import { WatchedQueryComparator } from './comparators.js';
|
|
9
2
|
|
|
10
3
|
/**
|
|
11
4
|
* Settings for {@link WatchedQuery} instances created via {@link Query#watch}.
|
|
@@ -22,107 +15,3 @@ export interface WatchedQuerySettings<DataType> extends WatchedQueryOptions {
|
|
|
22
15
|
* @public
|
|
23
16
|
*/
|
|
24
17
|
export type StandardWatchedQuery<DataType> = WatchedQuery<DataType, WatchedQuerySettings<DataType>>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @internal
|
|
28
|
-
*/
|
|
29
|
-
export interface OnChangeQueryProcessorOptions<Data> extends AbstractQueryProcessorOptions<
|
|
30
|
-
Data,
|
|
31
|
-
WatchedQuerySettings<Data>
|
|
32
|
-
> {
|
|
33
|
-
comparator?: WatchedQueryComparator<Data>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Uses the PowerSync onChange event to trigger watched queries.
|
|
38
|
-
* Results are emitted on every change of the relevant tables.
|
|
39
|
-
* @internal
|
|
40
|
-
*/
|
|
41
|
-
export class OnChangeQueryProcessor<Data> extends AbstractQueryProcessor<Data, WatchedQuerySettings<Data>> {
|
|
42
|
-
constructor(protected options: OnChangeQueryProcessorOptions<Data>) {
|
|
43
|
-
super(options);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @returns If the sets are equal
|
|
48
|
-
*/
|
|
49
|
-
protected checkEquality(current: Data, previous: Data): boolean {
|
|
50
|
-
// Use the provided comparator if available. Assume values are unique if not available.
|
|
51
|
-
return this.options.comparator?.checkEquality?.(current, previous) ?? false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
protected async linkQuery(options: LinkQueryOptions<Data>): Promise<void> {
|
|
55
|
-
const { db, watchOptions } = this.options;
|
|
56
|
-
const { abortSignal } = options;
|
|
57
|
-
|
|
58
|
-
const compiledQuery = watchOptions.query.compile();
|
|
59
|
-
const tables = await db.resolveTables(compiledQuery.sql, compiledQuery.parameters as any[], {
|
|
60
|
-
tables: options.settings.triggerOnTables
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
db.onChangeWithCallback(
|
|
64
|
-
{
|
|
65
|
-
onChange: async () => {
|
|
66
|
-
if (this.closed || abortSignal.aborted) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
// This fires for each change of the relevant tables
|
|
70
|
-
try {
|
|
71
|
-
if (this.reportFetching && !this.state.isFetching) {
|
|
72
|
-
await this.updateState({ isFetching: true });
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const partialStateUpdate: Partial<MutableWatchedQueryState<Data>> & { data?: Data } = {};
|
|
76
|
-
|
|
77
|
-
// Always run the query if an underlying table has changed
|
|
78
|
-
const result = await watchOptions.query.execute({
|
|
79
|
-
sql: compiledQuery.sql,
|
|
80
|
-
// Allows casting from ReadOnlyArray[unknown] to Array<unknown>
|
|
81
|
-
// This allows simpler compatibility with PowerSync queries
|
|
82
|
-
parameters: [...compiledQuery.parameters],
|
|
83
|
-
db: this.options.db
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
if (abortSignal.aborted) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (this.reportFetching) {
|
|
91
|
-
partialStateUpdate.isFetching = false;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (this.state.isLoading) {
|
|
95
|
-
partialStateUpdate.isLoading = false;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Check if the result has changed
|
|
99
|
-
if (!this.checkEquality(result, this.state.data)) {
|
|
100
|
-
Object.assign(partialStateUpdate, {
|
|
101
|
-
data: result
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (this.state.error) {
|
|
106
|
-
partialStateUpdate.error = null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (Object.keys(partialStateUpdate).length > 0) {
|
|
110
|
-
await this.updateState(partialStateUpdate);
|
|
111
|
-
}
|
|
112
|
-
} catch (error: any) {
|
|
113
|
-
await this.updateState({ error });
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
onError: async (error) => {
|
|
117
|
-
await this.updateState({ error });
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
signal: abortSignal,
|
|
122
|
-
tables,
|
|
123
|
-
throttleMs: watchOptions.throttleMs,
|
|
124
|
-
triggerImmediate: true // used to emit the initial state
|
|
125
|
-
}
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
}
|
package/src/db/DBAdapter.ts
CHANGED
|
@@ -3,52 +3,43 @@
|
|
|
3
3
|
* different SQLite DB implementations.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { BaseListener,
|
|
6
|
+
import { BaseListener, BaseObserver } from '../utils/BaseObserver.js';
|
|
7
|
+
import {
|
|
8
|
+
QueryResult,
|
|
9
|
+
queryResultFromRaw,
|
|
10
|
+
queryResultWithoutRows,
|
|
11
|
+
RawQueryResult,
|
|
12
|
+
SqliteRecord
|
|
13
|
+
} from './QueryResult.js';
|
|
7
14
|
|
|
8
15
|
/**
|
|
9
|
-
* TODO most of these types could be exported to a common `types` package
|
|
10
|
-
* which is used by the DB adapter libraries as well.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Object returned by SQL Query executions.
|
|
15
|
-
*
|
|
16
16
|
* @public
|
|
17
17
|
*/
|
|
18
|
-
export
|
|
19
|
-
/** Represents the auto-generated row id if applicable. */
|
|
20
|
-
insertId?: number;
|
|
18
|
+
export interface DBGetUtils {
|
|
21
19
|
/**
|
|
22
|
-
*
|
|
20
|
+
* Execute a read-only query and return results.
|
|
23
21
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* @param sql - The SQL query to execute
|
|
23
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
24
|
+
* @returns An array of results
|
|
27
25
|
*/
|
|
28
|
-
rowsAffected: number;
|
|
29
|
-
/** if status is undefined or 0 this object will contain the query results */
|
|
30
|
-
rows?: {
|
|
31
|
-
/** Raw array with all dataset */
|
|
32
|
-
_array: any[];
|
|
33
|
-
/** The length of the dataset */
|
|
34
|
-
length: number;
|
|
35
|
-
/** A convenience function to acess the index based the row object
|
|
36
|
-
* @param idx - the row index
|
|
37
|
-
* @returns the row structure identified by column names
|
|
38
|
-
*/
|
|
39
|
-
item: (idx: number) => any;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @public
|
|
45
|
-
*/
|
|
46
|
-
export interface DBGetUtils {
|
|
47
|
-
/** Execute a read-only query and return results. */
|
|
48
26
|
getAll<T>(sql: string, parameters?: any[]): Promise<T[]>;
|
|
49
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
29
|
+
*
|
|
30
|
+
* @param sql - The SQL query to execute
|
|
31
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
32
|
+
* @returns The first result if found, or null if no results are returned
|
|
33
|
+
*/
|
|
50
34
|
getOptional<T>(sql: string, parameters?: any[]): Promise<T | null>;
|
|
51
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
37
|
+
*
|
|
38
|
+
* @param sql - The SQL query to execute
|
|
39
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
40
|
+
* @returns The first result matching the query
|
|
41
|
+
* @throws Error if no rows are returned
|
|
42
|
+
*/
|
|
52
43
|
get<T>(sql: string, parameters?: any[]): Promise<T>;
|
|
53
44
|
}
|
|
54
45
|
|
|
@@ -56,97 +47,91 @@ export interface DBGetUtils {
|
|
|
56
47
|
* @public
|
|
57
48
|
*/
|
|
58
49
|
export interface SqlExecutor {
|
|
59
|
-
/** Execute a single write statement. */
|
|
60
|
-
execute: (query: string, params?: any[] | undefined) => Promise<QueryResult>;
|
|
61
50
|
/**
|
|
62
|
-
* Execute a
|
|
63
|
-
*
|
|
64
|
-
* `executeRaw` returns a nested array of raw values, where each row is
|
|
65
|
-
* represented as an array of column values without field names.
|
|
66
|
-
*
|
|
67
|
-
* Example result:
|
|
68
|
-
*
|
|
69
|
-
* ```JavaScript
|
|
70
|
-
* [ [ '1', 'list 1', '33', 'Post content', '1' ] ]
|
|
71
|
-
* ```
|
|
51
|
+
* Execute a SQL write (INSERT/UPDATE/DELETE) query
|
|
52
|
+
* and optionally return results.
|
|
72
53
|
*
|
|
73
|
-
*
|
|
54
|
+
* When using the default client-side [JSON-based view system](https://docs.powersync.com/architecture/client-architecture#client-side-schema-and-sqlite-database-structure),
|
|
55
|
+
* the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
|
|
56
|
+
* Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
|
|
74
57
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
58
|
+
* @param sql - The SQL query to execute
|
|
59
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
60
|
+
* @returns The query result as an object with structured key-value pairs
|
|
78
61
|
*/
|
|
79
|
-
|
|
62
|
+
execute: <T = SqliteRecord>(query: string, params?: any[] | undefined) => Promise<QueryResult<T>>;
|
|
80
63
|
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Execute a SQL write (INSERT/UPDATE/DELETE) query directly on the database without any PowerSync processing.
|
|
66
|
+
* This bypasses certain PowerSync abstractions and is useful for accessing the raw database results.
|
|
67
|
+
*
|
|
68
|
+
* @param sql - The SQL query to execute
|
|
69
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
70
|
+
* @returns The {@link RawQueryResult} representing each row as an array.
|
|
71
|
+
*/
|
|
72
|
+
executeRaw: (query: string, params?: any[] | undefined) => Promise<RawQueryResult>;
|
|
83
73
|
|
|
84
|
-
/**
|
|
85
|
-
* @public
|
|
86
|
-
*/
|
|
87
|
-
export interface LockContext extends SqlExecutor, DBGetUtils {
|
|
88
74
|
/**
|
|
89
|
-
*
|
|
75
|
+
* Execute a write query (INSERT/UPDATE/DELETE) multiple times with each parameter set
|
|
76
|
+
* and optionally return results.
|
|
77
|
+
* This is faster than executing separately with each parameter set.
|
|
90
78
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* `readOnly` indicates that the lock context has been opened by passing `SQLITE_OPEN_READONLY` to `sqlite3_open_v2`.
|
|
79
|
+
* @param sql - The SQL query to execute
|
|
80
|
+
* @param parameters - Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
81
|
+
* @returns The query result
|
|
95
82
|
*/
|
|
96
|
-
|
|
83
|
+
executeBatch: (query: string, params?: any[][]) => Promise<QueryResult<never>>;
|
|
97
84
|
}
|
|
98
85
|
|
|
99
86
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* @internal
|
|
87
|
+
* @public
|
|
103
88
|
*/
|
|
104
|
-
export
|
|
105
|
-
|
|
106
|
-
) {
|
|
107
|
-
return class extends Base implements DBGetUtils, SqlExecutor {
|
|
108
|
-
async getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
|
|
109
|
-
const res = await this.execute(sql, parameters);
|
|
110
|
-
return res.rows?._array ?? [];
|
|
111
|
-
}
|
|
89
|
+
export abstract class LockContext implements SqlExecutor, DBGetUtils {
|
|
90
|
+
abstract executeRaw<T>(query: string, params?: any[] | undefined): Promise<RawQueryResult>;
|
|
112
91
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
async getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
|
|
93
|
+
const rs = await this.execute<T>(sql, parameters);
|
|
94
|
+
return Array.from(rs);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async getOptional<T>(sql: string, parameters?: any[]): Promise<T | null> {
|
|
98
|
+
const { array } = await this.execute<T>(sql, parameters);
|
|
99
|
+
if (array.length > 0) {
|
|
100
|
+
return array[0];
|
|
116
101
|
}
|
|
117
102
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async get<T>(sql: string, parameters?: any[]): Promise<T> {
|
|
107
|
+
const row = await this.getOptional<T>(sql, parameters);
|
|
108
|
+
if (row == null) {
|
|
109
|
+
throw new Error('Result set is empty');
|
|
125
110
|
}
|
|
126
111
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// @ts-ignore
|
|
130
|
-
if (super.executeBatch) {
|
|
131
|
-
// @ts-ignore
|
|
132
|
-
return super.executeBatch(query, params);
|
|
133
|
-
}
|
|
112
|
+
return row;
|
|
113
|
+
}
|
|
134
114
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const result = await this.execute(query, set);
|
|
140
|
-
lastInsertId = result.insertId;
|
|
141
|
-
rowsAffected += result.rowsAffected;
|
|
142
|
-
}
|
|
115
|
+
async execute<T = SqliteRecord>(query: string, params?: any[] | undefined): Promise<QueryResult<T>> {
|
|
116
|
+
const raw = await this.executeRaw(query, params);
|
|
117
|
+
return queryResultFromRaw(raw);
|
|
118
|
+
}
|
|
143
119
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
120
|
+
async executeBatch(query: string, params: any[][] = []): Promise<QueryResult<never>> {
|
|
121
|
+
// Emulate executeBatch by running statements individually.
|
|
122
|
+
let lastInsertId: number | undefined;
|
|
123
|
+
let rowsAffected = 0;
|
|
124
|
+
for (const set of params) {
|
|
125
|
+
const result = await this.execute(query, set);
|
|
126
|
+
lastInsertId = result.insertId;
|
|
127
|
+
rowsAffected += result.rowsAffected ?? 0;
|
|
148
128
|
}
|
|
149
|
-
|
|
129
|
+
|
|
130
|
+
return queryResultWithoutRows({
|
|
131
|
+
rowsAffected,
|
|
132
|
+
insertId: lastInsertId
|
|
133
|
+
});
|
|
134
|
+
}
|
|
150
135
|
}
|
|
151
136
|
|
|
152
137
|
/**
|
|
@@ -154,46 +139,16 @@ export function DBGetUtilsDefaultMixin<TBase extends new (...args: any[]) => Omi
|
|
|
154
139
|
*/
|
|
155
140
|
export interface Transaction extends LockContext {
|
|
156
141
|
/** Commit multiple changes to the local DB using the Transaction context. */
|
|
157
|
-
commit: () => Promise<
|
|
142
|
+
commit: () => Promise<void>;
|
|
158
143
|
/** Roll back multiple attempted changes using the Transaction context. */
|
|
159
|
-
rollback: () => Promise<
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Update table operation numbers from SQLite
|
|
164
|
-
*
|
|
165
|
-
* @public
|
|
166
|
-
*/
|
|
167
|
-
export enum RowUpdateType {
|
|
168
|
-
SQLITE_INSERT = 18,
|
|
169
|
-
SQLITE_DELETE = 9,
|
|
170
|
-
SQLITE_UPDATE = 23
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* @public
|
|
175
|
-
*/
|
|
176
|
-
export interface TableUpdateOperation {
|
|
177
|
-
opType: RowUpdateType;
|
|
178
|
-
rowId: number;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Notification of an update to one or more tables, for the purpose of realtime change notifications.
|
|
182
|
-
*
|
|
183
|
-
* @public
|
|
184
|
-
*/
|
|
185
|
-
export interface UpdateNotification extends TableUpdateOperation {
|
|
186
|
-
table: string;
|
|
144
|
+
rollback: () => Promise<void>;
|
|
187
145
|
}
|
|
188
146
|
|
|
189
147
|
/**
|
|
190
148
|
* @public
|
|
191
149
|
*/
|
|
192
150
|
export interface BatchedUpdateNotification {
|
|
193
|
-
// TODO (breaking change): Normalize to only including tables
|
|
194
|
-
rawUpdates: UpdateNotification[];
|
|
195
151
|
tables: string[];
|
|
196
|
-
groupedUpdates: Record<string, TableUpdateOperation[]>;
|
|
197
152
|
}
|
|
198
153
|
|
|
199
154
|
/**
|
|
@@ -206,7 +161,7 @@ export interface DBAdapterListener extends BaseListener {
|
|
|
206
161
|
* without the need for a major version bump
|
|
207
162
|
* The DB adapter can also batch update notifications if supported.
|
|
208
163
|
*/
|
|
209
|
-
tablesUpdated: (updateNotification: BatchedUpdateNotification
|
|
164
|
+
tablesUpdated: (updateNotification: BatchedUpdateNotification) => void;
|
|
210
165
|
}
|
|
211
166
|
|
|
212
167
|
/**
|
|
@@ -219,116 +174,92 @@ export interface DBLockOptions {
|
|
|
219
174
|
/**
|
|
220
175
|
* @public
|
|
221
176
|
*/
|
|
222
|
-
export
|
|
223
|
-
name: string;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
177
|
+
export abstract class DBAdapter extends BaseObserver<DBAdapterListener> implements SqlExecutor, DBGetUtils {
|
|
178
|
+
abstract get name(): string;
|
|
179
|
+
|
|
180
|
+
abstract close(): void | Promise<void>;
|
|
181
|
+
|
|
182
|
+
abstract readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
183
|
+
abstract writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
227
184
|
|
|
228
185
|
/**
|
|
229
186
|
* This method refreshes the schema information across all connections. This is for advanced use cases, and should generally not be needed.
|
|
230
187
|
*/
|
|
231
|
-
refreshSchema
|
|
232
|
-
}
|
|
188
|
+
abstract refreshSchema(): Promise<void>;
|
|
233
189
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
export interface DBAdapter extends ConnectionPool, SqlExecutor, DBGetUtils {
|
|
238
|
-
readTransaction: <T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
239
|
-
writeTransaction: <T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool#readLock} and
|
|
244
|
-
* {@link ConnectionPool#writeLock}.
|
|
245
|
-
*
|
|
246
|
-
* @internal
|
|
247
|
-
*/
|
|
248
|
-
export function DBAdapterDefaultMixin<TBase extends new (...args: any[]) => ConnectionPool>(Base: TBase) {
|
|
249
|
-
return class extends Base implements DBAdapter {
|
|
250
|
-
readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
251
|
-
return this.readLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
252
|
-
}
|
|
190
|
+
readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
191
|
+
return this.readLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
192
|
+
}
|
|
253
193
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
194
|
+
writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
195
|
+
return this.writeLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
196
|
+
}
|
|
257
197
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
198
|
+
getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
|
|
199
|
+
return this.readLock((ctx) => ctx.getAll(sql, parameters));
|
|
200
|
+
}
|
|
261
201
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
202
|
+
getOptional<T>(sql: string, parameters?: any[]): Promise<T | null> {
|
|
203
|
+
return this.readLock((ctx) => ctx.getOptional(sql, parameters));
|
|
204
|
+
}
|
|
265
205
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
206
|
+
get<T>(sql: string, parameters?: any[]): Promise<T> {
|
|
207
|
+
return this.readLock((ctx) => ctx.get(sql, parameters));
|
|
208
|
+
}
|
|
269
209
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
210
|
+
execute<T>(query: string, params?: any[]): Promise<QueryResult<T>> {
|
|
211
|
+
return this.writeLock((ctx) => ctx.execute(query, params));
|
|
212
|
+
}
|
|
273
213
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
214
|
+
executeRaw(query: string, params?: any[]): Promise<RawQueryResult> {
|
|
215
|
+
return this.writeLock((ctx) => ctx.executeRaw(query, params));
|
|
216
|
+
}
|
|
277
217
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
};
|
|
218
|
+
executeBatch(query: string, params?: any[][]): Promise<QueryResult<never>> {
|
|
219
|
+
return this.writeTransaction((tx) => tx.executeBatch(query, params));
|
|
220
|
+
}
|
|
282
221
|
}
|
|
283
222
|
|
|
284
|
-
class
|
|
223
|
+
class TransactionImplementation extends LockContext {
|
|
285
224
|
private finalized = false;
|
|
286
225
|
|
|
287
|
-
constructor(private inner:
|
|
226
|
+
constructor(private inner: LockContext) {
|
|
227
|
+
super();
|
|
228
|
+
}
|
|
288
229
|
|
|
289
|
-
async commit(): Promise<
|
|
230
|
+
async commit(): Promise<void> {
|
|
290
231
|
if (this.finalized) {
|
|
291
|
-
return
|
|
232
|
+
return;
|
|
292
233
|
}
|
|
293
234
|
this.finalized = true;
|
|
294
|
-
|
|
235
|
+
await this.inner.execute('COMMIT');
|
|
295
236
|
}
|
|
296
237
|
|
|
297
|
-
async rollback(): Promise<
|
|
238
|
+
async rollback(): Promise<void> {
|
|
298
239
|
if (this.finalized) {
|
|
299
|
-
return
|
|
240
|
+
return;
|
|
300
241
|
}
|
|
301
242
|
this.finalized = true;
|
|
302
|
-
|
|
243
|
+
await this.inner.execute('ROLLBACK');
|
|
303
244
|
}
|
|
304
245
|
|
|
305
|
-
execute(query: string, params?: any[] | undefined): Promise<QueryResult
|
|
246
|
+
execute<T>(query: string, params?: any[] | undefined): Promise<QueryResult<T>> {
|
|
306
247
|
return this.inner.execute(query, params);
|
|
307
248
|
}
|
|
308
249
|
|
|
309
|
-
executeRaw(query: string, params?: any[] | undefined): Promise<
|
|
250
|
+
executeRaw(query: string, params?: any[] | undefined): Promise<RawQueryResult> {
|
|
310
251
|
return this.inner.executeRaw(query, params);
|
|
311
252
|
}
|
|
312
253
|
|
|
313
|
-
executeBatch(query: string, params?: any[][]): Promise<QueryResult
|
|
254
|
+
executeBatch(query: string, params?: any[][]): Promise<QueryResult<never>> {
|
|
314
255
|
return this.inner.executeBatch(query, params);
|
|
315
256
|
}
|
|
316
|
-
}
|
|
317
257
|
|
|
318
|
-
class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction) {
|
|
319
258
|
static async runWith<T>(ctx: LockContext, fn: (tx: Transaction) => Promise<T>): Promise<T> {
|
|
320
259
|
let tx = new TransactionImplementation(ctx);
|
|
321
260
|
|
|
322
|
-
// For write transactions, use BEGIN IMMEDIATE to immediately obtain a write lock on the database (instead of doing
|
|
323
|
-
// that on the first statement). If we have a genuine read-only connection, we also use BEGIN IMMEDIATE there: In
|
|
324
|
-
// WAL mode, that ensures we pin the current state of the database (instead of the state at the first statement in
|
|
325
|
-
// the transaction). But if we have a "fake" read-only connection implemented through `pragma query_only = true`, we
|
|
326
|
-
// can't use this trick because it would attempt to lock the connection. So there, we use a regular `BEGIN`
|
|
327
|
-
// statement.
|
|
328
|
-
const useBeginImmediate = ctx.connectionType != 'queryOnly';
|
|
329
|
-
|
|
330
261
|
try {
|
|
331
|
-
await ctx.execute(
|
|
262
|
+
await ctx.execute('BEGIN IMMEDIATE');
|
|
332
263
|
|
|
333
264
|
const result = await fn(tx);
|
|
334
265
|
await tx.commit();
|
|
@@ -344,19 +275,3 @@ class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction)
|
|
|
344
275
|
}
|
|
345
276
|
}
|
|
346
277
|
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* @internal
|
|
350
|
-
*/
|
|
351
|
-
export function isBatchedUpdateNotification(
|
|
352
|
-
update: BatchedUpdateNotification | UpdateNotification
|
|
353
|
-
): update is BatchedUpdateNotification {
|
|
354
|
-
return 'tables' in update;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* @internal
|
|
359
|
-
*/
|
|
360
|
-
export function extractTableUpdates(update: BatchedUpdateNotification | UpdateNotification) {
|
|
361
|
-
return isBatchedUpdateNotification(update) ? update.tables : [update.table];
|
|
362
|
-
}
|