@powersync/service-module-mssql 0.9.0 → 0.10.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/CHANGELOG.md +113 -0
- package/dist/api/MSSQLRouteAPIAdapter.js +26 -34
- 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/replication/CDCPoller.d.ts +13 -36
- package/dist/replication/CDCPoller.js +173 -129
- package/dist/replication/CDCPoller.js.map +1 -1
- package/dist/replication/CDCStream.d.ts +11 -14
- package/dist/replication/CDCStream.js +115 -106
- 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 +8 -0
- package/dist/types/types.js +10 -1
- 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 +40 -45
- package/dist/utils/schema.js.map +1 -1
- package/package.json +8 -8
- package/src/api/MSSQLRouteAPIAdapter.ts +27 -33
- package/src/common/MSSQLSourceTable.ts +32 -4
- package/src/replication/CDCPoller.ts +206 -162
- package/src/replication/CDCStream.ts +148 -154
- 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 +22 -1
- package/src/utils/mssql.ts +1 -1
- package/src/utils/schema.ts +57 -58
- package/test/src/CDCPoller.test.ts +382 -0
- package/test/src/CDCStream.test.ts +6 -2
- package/test/src/CDCStreamTestContext.ts +7 -0
- package/test/src/CaptureReconciler.test.ts +171 -0
- package/test/src/MSSQLSourceTable.test.ts +30 -0
- package/test/src/config.test.ts +37 -0
- package/test/src/schema-changes.test.ts +513 -249
- package/test/src/schema.test.ts +17 -0
- package/test/src/util.ts +70 -6
- 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, ReplicationCheckpoint, TestStorageConfig } from '@powersync/service-core';
|
|
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';
|
|
@@ -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
|
+
}
|