@powersync/service-module-mssql 0.0.0-dev-20260602073133 → 0.0.0-dev-20260909133214
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/CHANGELOG.md +209 -4
- package/dist/api/MSSQLRouteAPIAdapter.d.ts +4 -5
- package/dist/api/MSSQLRouteAPIAdapter.js +33 -39
- package/dist/api/MSSQLRouteAPIAdapter.js.map +1 -1
- package/dist/common/MSSQLSourceTable.d.ts +12 -2
- package/dist/common/MSSQLSourceTable.js +30 -4
- package/dist/common/MSSQLSourceTable.js.map +1 -1
- package/dist/module/MSSQLModule.js +2 -1
- package/dist/module/MSSQLModule.js.map +1 -1
- package/dist/replication/CDCPoller.d.ts +13 -36
- package/dist/replication/CDCPoller.js +173 -129
- package/dist/replication/CDCPoller.js.map +1 -1
- package/dist/replication/CDCReplicationJob.js +1 -1
- package/dist/replication/CDCReplicationJob.js.map +1 -1
- package/dist/replication/CDCReplicator.js +1 -1
- package/dist/replication/CDCReplicator.js.map +1 -1
- package/dist/replication/CDCStream.d.ts +11 -14
- package/dist/replication/CDCStream.js +124 -115
- package/dist/replication/CDCStream.js.map +1 -1
- package/dist/replication/CaptureReconciler.d.ts +47 -0
- package/dist/replication/CaptureReconciler.js +155 -0
- package/dist/replication/CaptureReconciler.js.map +1 -0
- package/dist/replication/MSSQLConnectionManager.d.ts +1 -0
- package/dist/replication/MSSQLConnectionManager.js +19 -14
- package/dist/replication/MSSQLConnectionManager.js.map +1 -1
- package/dist/replication/MSSQLTableReconciliationContext.d.ts +21 -0
- package/dist/replication/MSSQLTableReconciliationContext.js +7 -0
- package/dist/replication/MSSQLTableReconciliationContext.js.map +1 -0
- package/dist/replication/SchemaChange.d.ts +67 -0
- package/dist/replication/SchemaChange.js +31 -0
- package/dist/replication/SchemaChange.js.map +1 -0
- package/dist/types/types.d.ts +13 -0
- package/dist/types/types.js +28 -2
- package/dist/types/types.js.map +1 -1
- package/dist/utils/mssql.js +1 -1
- package/dist/utils/schema.d.ts +14 -1
- package/dist/utils/schema.js +43 -45
- package/dist/utils/schema.js.map +1 -1
- package/package.json +11 -21
- package/src/api/MSSQLRouteAPIAdapter.ts +38 -49
- package/src/common/MSSQLSourceTable.ts +32 -4
- package/src/module/MSSQLModule.ts +2 -1
- package/src/replication/CDCPoller.ts +206 -162
- package/src/replication/CDCReplicationJob.ts +1 -1
- package/src/replication/CDCReplicator.ts +1 -1
- package/src/replication/CDCStream.ts +157 -163
- package/src/replication/CaptureReconciler.ts +186 -0
- package/src/replication/MSSQLConnectionManager.ts +23 -14
- package/src/replication/MSSQLTableReconciliationContext.ts +29 -0
- package/src/replication/SchemaChange.ts +79 -0
- package/src/types/types.ts +47 -2
- package/src/utils/mssql.ts +1 -1
- package/src/utils/schema.ts +60 -54
- package/test/src/CDCPoller.test.ts +382 -0
- package/test/src/CDCStream.test.ts +6 -2
- package/test/src/CDCStreamTestContext.ts +30 -23
- package/test/src/CaptureReconciler.test.ts +171 -0
- package/test/src/MSSQLSourceTable.test.ts +30 -0
- package/test/src/config.test.ts +71 -0
- package/test/src/schema-changes.test.ts +513 -249
- package/test/src/schema.test.ts +17 -0
- package/test/src/util.ts +73 -9
- package/tsconfig.json +0 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { unsupportedTablePatternMessage } from '@module/utils/schema.js';
|
|
2
|
+
import { TablePattern } from '@powersync/service-sync-rules';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
|
|
5
|
+
describe('unsupportedTablePatternMessage', () => {
|
|
6
|
+
it('accepts an exact table pattern', () => {
|
|
7
|
+
expect(unsupportedTablePatternMessage(new TablePattern('dbo', 'users'))).toBeNull();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('rejects a table wildcard', () => {
|
|
11
|
+
expect(unsupportedTablePatternMessage(new TablePattern('dbo', 'test_data%'))).toMatch(/Table wildcards/);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('rejects a schema wildcard', () => {
|
|
15
|
+
expect(unsupportedTablePatternMessage(new TablePattern('dbo%', 'users'))).toMatch(/Schema wildcards/);
|
|
16
|
+
});
|
|
17
|
+
});
|
package/test/src/util.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as types from '@module/types/types.js';
|
|
2
2
|
import { logger } from '@powersync/lib-services-framework';
|
|
3
|
-
import { BucketStorageFactory,
|
|
4
|
-
|
|
3
|
+
import { BucketStorageFactory, ReplicationCheckpoint, storage, TestStorageConfig } from '@powersync/service-core';
|
|
5
4
|
import * as mongo_storage from '@powersync/service-module-mongodb-storage';
|
|
6
5
|
import * as postgres_storage from '@powersync/service-module-postgres-storage';
|
|
7
6
|
|
|
7
|
+
import { CaptureInstance } from '@module/common/CaptureInstance.js';
|
|
8
8
|
import { LSN } from '@module/common/LSN.js';
|
|
9
|
+
import { MSSQLSourceMetadata } from '@module/replication/CaptureReconciler.js';
|
|
9
10
|
import { MSSQLConnectionManager } from '@module/replication/MSSQLConnectionManager.js';
|
|
10
11
|
import { createCheckpoint, escapeIdentifier, getLatestLSN, toQualifiedTableName } from '@module/utils/mssql.js';
|
|
11
12
|
import sql from 'mssql';
|
|
@@ -194,7 +195,7 @@ export async function getClientCheckpoint(
|
|
|
194
195
|
connectionManager: MSSQLConnectionManager,
|
|
195
196
|
storageFactory: BucketStorageFactory,
|
|
196
197
|
options?: { timeout?: number }
|
|
197
|
-
): Promise<
|
|
198
|
+
): Promise<ReplicationCheckpoint> {
|
|
198
199
|
const start = Date.now();
|
|
199
200
|
|
|
200
201
|
const lsn = await getLatestLSN(connectionManager);
|
|
@@ -208,13 +209,13 @@ export async function getClientCheckpoint(
|
|
|
208
209
|
|
|
209
210
|
logger.info(`Test Assertion: Waiting for LSN checkpoint: ${lsn}`);
|
|
210
211
|
while (Date.now() - start < timeout) {
|
|
211
|
-
const storage = await storageFactory.
|
|
212
|
+
const storage = (await storageFactory.getActiveSyncConfig())?.storage;
|
|
212
213
|
const cp = await storage?.getCheckpoint();
|
|
213
214
|
if (cp != null) {
|
|
214
215
|
lastCp = cp;
|
|
215
216
|
if (cp.lsn != null && cp.lsn >= lsn.toString()) {
|
|
216
217
|
logger.info(`Test Assertion: Got write checkpoint: ${lsn} : ${cp.checkpoint}`);
|
|
217
|
-
return cp
|
|
218
|
+
return cp;
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
221
|
|
|
@@ -242,24 +243,87 @@ export interface EnableCDCForTableOptions {
|
|
|
242
243
|
connectionManager: MSSQLConnectionManager;
|
|
243
244
|
table: string;
|
|
244
245
|
captureInstance?: string;
|
|
246
|
+
/**
|
|
247
|
+
* Columns to capture. SQL Server captures all columns by default.
|
|
248
|
+
*/
|
|
249
|
+
capturedColumns?: string[];
|
|
245
250
|
}
|
|
246
251
|
|
|
247
252
|
export async function enableCDCForTable(options: EnableCDCForTableOptions): Promise<void> {
|
|
248
|
-
const { connectionManager, table, captureInstance } = options;
|
|
253
|
+
const { connectionManager, table, captureInstance, capturedColumns } = options;
|
|
249
254
|
|
|
250
255
|
await connectionManager.execute('sys.sp_cdc_enable_table', [
|
|
251
256
|
{ name: 'source_schema', value: connectionManager.schema },
|
|
252
257
|
{ name: 'source_name', value: table },
|
|
253
258
|
{ name: 'role_name', value: 'cdc_reader' },
|
|
254
259
|
{ name: 'supports_net_changes', value: 0 },
|
|
255
|
-
...(captureInstance !== undefined ? [{ name: 'capture_instance', value: captureInstance }] : [])
|
|
260
|
+
...(captureInstance !== undefined ? [{ name: 'capture_instance', value: captureInstance }] : []),
|
|
261
|
+
...(capturedColumns !== undefined ? [{ name: 'captured_column_list', value: capturedColumns.join(',') }] : [])
|
|
256
262
|
]);
|
|
257
263
|
}
|
|
258
264
|
|
|
259
|
-
|
|
265
|
+
/**
|
|
266
|
+
* Disable one capture instance, or all instances by default.
|
|
267
|
+
*/
|
|
268
|
+
export async function disableCDCForTable(
|
|
269
|
+
connectionManager: MSSQLConnectionManager,
|
|
270
|
+
tableName: string,
|
|
271
|
+
captureInstance: string = 'all'
|
|
272
|
+
) {
|
|
260
273
|
await connectionManager.execute('sys.sp_cdc_disable_table', [
|
|
261
274
|
{ name: 'source_schema', value: connectionManager.schema },
|
|
262
275
|
{ name: 'source_name', value: tableName },
|
|
263
|
-
{ name: 'capture_instance', value:
|
|
276
|
+
{ name: 'capture_instance', value: captureInstance }
|
|
264
277
|
]);
|
|
265
278
|
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Create a capture instance with the given capture-table object id.
|
|
282
|
+
*/
|
|
283
|
+
export function createCaptureInstance(objectId: number): CaptureInstance {
|
|
284
|
+
return {
|
|
285
|
+
name: `dbo_users_${objectId}`,
|
|
286
|
+
objectId,
|
|
287
|
+
minLSN: LSN.fromString(LSN.ZERO),
|
|
288
|
+
createDate: new Date(),
|
|
289
|
+
pendingSchemaChanges: []
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Build a persisted source-table candidate with optional capture metadata.
|
|
294
|
+
*/
|
|
295
|
+
export function createSourceTableCandidate(
|
|
296
|
+
id: string,
|
|
297
|
+
metadata?: MSSQLSourceMetadata,
|
|
298
|
+
overrides: Partial<ConstructorParameters<typeof storage.SourceTable>[0]> = {}
|
|
299
|
+
): storage.SourceTable {
|
|
300
|
+
const descriptor = createSourceDescriptor();
|
|
301
|
+
|
|
302
|
+
return new storage.SourceTable({
|
|
303
|
+
id,
|
|
304
|
+
ref: descriptor,
|
|
305
|
+
objectId: descriptor.objectId,
|
|
306
|
+
replicaIdColumns: descriptor.replicaIdColumns,
|
|
307
|
+
snapshotComplete: true,
|
|
308
|
+
bucketDataSources: [],
|
|
309
|
+
parameterLookupSources: [],
|
|
310
|
+
sourceMetadata: metadata,
|
|
311
|
+
...overrides
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Create a source descriptor with optional identity overrides.
|
|
317
|
+
*/
|
|
318
|
+
export function createSourceDescriptor(
|
|
319
|
+
overrides: Partial<storage.SourceEntityDescriptor> = {}
|
|
320
|
+
): storage.SourceEntityDescriptor {
|
|
321
|
+
return {
|
|
322
|
+
connectionTag: 'default',
|
|
323
|
+
schema: 'dbo',
|
|
324
|
+
name: 'users',
|
|
325
|
+
objectId: 100,
|
|
326
|
+
replicaIdColumns: [{ name: 'id', type: 'int', typeId: 56 }],
|
|
327
|
+
...overrides
|
|
328
|
+
};
|
|
329
|
+
}
|