@powersync/service-module-mssql 0.8.2 → 0.9.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/CHANGELOG.md +40 -0
- package/dist/api/MSSQLRouteAPIAdapter.d.ts +2 -2
- package/dist/api/MSSQLRouteAPIAdapter.js +7 -5
- package/dist/api/MSSQLRouteAPIAdapter.js.map +1 -1
- package/dist/module/MSSQLModule.js +2 -1
- package/dist/module/MSSQLModule.js.map +1 -1
- package/dist/types/types.d.ts +5 -0
- package/dist/types/types.js +19 -2
- package/dist/types/types.js.map +1 -1
- package/dist/utils/schema.js +4 -1
- package/dist/utils/schema.js.map +1 -1
- package/package.json +9 -9
- package/src/api/MSSQLRouteAPIAdapter.ts +9 -13
- package/src/module/MSSQLModule.ts +2 -1
- package/src/types/types.ts +26 -2
- package/src/utils/schema.ts +8 -1
- package/test/src/CDCStreamTestContext.ts +2 -2
- package/test/src/config.test.ts +34 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @powersync/service-module-mssql
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 087b61e: Configurable heartbeat_interval_seconds for MongoDB, Postgres, SQL Server.
|
|
8
|
+
- 2189250: Add `/sync/checkpoint-request` for client-supplied checkpoint request ids, previously called write checkpoint ids. The route returns the stored `checkpoint_request_id`, storage now treats managed request ids as monotonic per user/client, custom checkpoint request ids continue to use the existing `checkpoint` field for backwards compatibility, and `checkpoint_requested_at` metadata lets compact jobs remove expired request-derived checkpoint records.
|
|
9
|
+
|
|
10
|
+
This release includes storage migrations for the checkpoint request metadata. Self-hosters should run migrations as part of the upgrade.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- be42e25: Throw a clear error (`PSYNC_R2201`) when a schema wildcard is used in a table pattern with MongoDB, MySQL, SQL Server or Convex connections, instead of silently discovering no tables.
|
|
15
|
+
- Updated dependencies [087b61e]
|
|
16
|
+
- Updated dependencies [2189250]
|
|
17
|
+
- Updated dependencies [922f974]
|
|
18
|
+
- Updated dependencies [c4860c9]
|
|
19
|
+
- Updated dependencies [483415d]
|
|
20
|
+
- Updated dependencies [8daa300]
|
|
21
|
+
- Updated dependencies [aab068b]
|
|
22
|
+
- Updated dependencies [37591e9]
|
|
23
|
+
- Updated dependencies [be42e25]
|
|
24
|
+
- Updated dependencies [be42e25]
|
|
25
|
+
- Updated dependencies [cb4c627]
|
|
26
|
+
- @powersync/service-core@1.24.0
|
|
27
|
+
- @powersync/lib-services-framework@0.10.0
|
|
28
|
+
- @powersync/service-types@0.17.0
|
|
29
|
+
- @powersync/service-sync-rules@0.40.0
|
|
30
|
+
- @powersync/service-errors@0.5.0
|
|
31
|
+
|
|
32
|
+
## 0.8.3
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [ea71bf3]
|
|
37
|
+
- Updated dependencies [ea31f64]
|
|
38
|
+
- Updated dependencies [edc6ed4]
|
|
39
|
+
- @powersync/service-sync-rules@0.39.0
|
|
40
|
+
- @powersync/service-core@1.23.3
|
|
41
|
+
- @powersync/lib-services-framework@0.9.8
|
|
42
|
+
|
|
3
43
|
## 0.8.2
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { api, ParseSyncConfigOptions, PatternResult,
|
|
1
|
+
import { api, ParseSyncConfigOptions, PatternResult, ReplicationLagOptions } from '@powersync/service-core';
|
|
2
2
|
import { SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
|
|
3
3
|
import * as service_types from '@powersync/service-types';
|
|
4
4
|
import { MSSQLConnectionManager } from '../replication/MSSQLConnectionManager.js';
|
|
@@ -7,7 +7,7 @@ export declare class MSSQLRouteAPIAdapter implements api.RouteAPI {
|
|
|
7
7
|
protected config: types.ResolvedMSSQLConnectionConfig;
|
|
8
8
|
protected connectionManager: MSSQLConnectionManager;
|
|
9
9
|
constructor(config: types.ResolvedMSSQLConnectionConfig);
|
|
10
|
-
createReplicationHead<T>(callback: ReplicationHeadCallback<T>): Promise<T>;
|
|
10
|
+
createReplicationHead<T>(callback: api.ReplicationHeadCallback<T>): Promise<T>;
|
|
11
11
|
executeQuery(query: string, params: any[]): Promise<service_types.internal_routes.ExecuteSqlResponse>;
|
|
12
12
|
getConnectionSchema(): Promise<service_types.DatabaseSchema[]>;
|
|
13
13
|
getConnectionStatus(): Promise<service_types.ConnectionStatusV2>;
|
|
@@ -13,11 +13,13 @@ export class MSSQLRouteAPIAdapter {
|
|
|
13
13
|
this.connectionManager = new MSSQLConnectionManager(config, {});
|
|
14
14
|
}
|
|
15
15
|
async createReplicationHead(callback) {
|
|
16
|
-
const currentLSN = await getLatestLSN(this.connectionManager);
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const currentLSN = (await getLatestLSN(this.connectionManager)).toString();
|
|
17
|
+
const { response, shouldAdvance } = await callback(currentLSN);
|
|
18
|
+
if (shouldAdvance) {
|
|
19
|
+
// Updates the powersync checkpoints table on the source database, ensuring that an update with a newer LSN will be captured by the CDC.
|
|
20
|
+
await createCheckpoint(this.connectionManager);
|
|
21
|
+
}
|
|
22
|
+
return response;
|
|
21
23
|
}
|
|
22
24
|
async executeQuery(query, params) {
|
|
23
25
|
return service_types.internal_routes.ExecuteSqlResponse.encode({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MSSQLRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/MSSQLRouteAPIAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MSSQLRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/MSSQLRouteAPIAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,7 +29,8 @@ export class MSSQLModule extends replication.ReplicationModule {
|
|
|
29
29
|
metricsEngine: context.metricsEngine,
|
|
30
30
|
connectionFactory: connectionFactory,
|
|
31
31
|
rateLimiter: new MSSQLErrorRateLimiter(),
|
|
32
|
-
additionalConfig: normalisedConfig.additionalConfig
|
|
32
|
+
additionalConfig: normalisedConfig.additionalConfig,
|
|
33
|
+
heartbeatIntervalSeconds: normalisedConfig.heartbeat_interval_seconds
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MSSQLModule.js","sourceRoot":"","sources":["../../src/module/MSSQLModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kCAAkC,EAElC,WAAW,EAGZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,MAAM,OAAO,WAAY,SAAQ,WAAW,CAAC,iBAA8C;IACzF;QACE,KAAK,CAAC;YACJ,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,KAAK,CAAC,qBAAqB;YACjC,YAAY,EAAE,KAAK,CAAC,qBAAqB;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAuC,IAAkB,CAAC;IAEpE,qBAAqB;QAC7B,OAAO,IAAI,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC,CAAC;IAC3E,CAAC;IAES,gBAAgB,CAAC,OAA8B;QACvD,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;QACjE,MAAM,gBAAgB,GAAG,IAAI,kCAAkC,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAClG,MAAM,iBAAiB,GAAG,IAAI,6BAA6B,CAAC,gBAAgB,CAAC,CAAC;QAE9E,OAAO,IAAI,aAAa,CAAC;YACvB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CAAC;YAChD,gBAAgB,EAAE,gBAAgB;YAClC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,iBAAiB,EAAE,iBAAiB;YACpC,WAAW,EAAE,IAAI,qBAAqB,EAAE;YACxC,gBAAgB,EAAE,gBAAgB,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"MSSQLModule.js","sourceRoot":"","sources":["../../src/module/MSSQLModule.ts"],"names":[],"mappings":"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"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -107,6 +107,7 @@ export interface NormalizedMSSQLConnectionConfig {
|
|
|
107
107
|
authentication?: Authentication;
|
|
108
108
|
lookup?: LookupFunction;
|
|
109
109
|
additionalConfig: AdditionalConfig;
|
|
110
|
+
heartbeat_interval_seconds: number;
|
|
110
111
|
}
|
|
111
112
|
export declare const MSSQLConnectionConfig: t.Intersection<t.Codec<{
|
|
112
113
|
type: string;
|
|
@@ -164,6 +165,10 @@ export declare const MSSQLConnectionConfig: t.Intersection<t.Codec<{
|
|
|
164
165
|
pollingBatchSize?: number | undefined;
|
|
165
166
|
trustServerCertificate?: boolean | undefined;
|
|
166
167
|
}, string, t.CodecProps>>;
|
|
168
|
+
/**
|
|
169
|
+
* Interval in seconds between source connection heartbeats. Null or omitted uses the default.
|
|
170
|
+
*/
|
|
171
|
+
heartbeat_interval_seconds: t.OptionalCodec<t.Codec<number | null, number | null, string, t.CodecProps>>;
|
|
167
172
|
}>>;
|
|
168
173
|
/**
|
|
169
174
|
* Config input specified when starting services
|
package/dist/types/types.js
CHANGED
|
@@ -5,6 +5,9 @@ import * as urijs from 'uri-js';
|
|
|
5
5
|
export const DEFAULT_POLLING_BATCH_SIZE = 10;
|
|
6
6
|
export const DEFAULT_POLLING_INTERVAL_MS = 1000;
|
|
7
7
|
export const MSSQL_CONNECTION_TYPE = 'mssql';
|
|
8
|
+
const DEFAULT_HEARTBEAT_INTERVAL_SECONDS = 60;
|
|
9
|
+
const MIN_HEARTBEAT_INTERVAL_SECONDS = 5;
|
|
10
|
+
const MAX_HEARTBEAT_INTERVAL_SECONDS = 60;
|
|
8
11
|
export const AzureActiveDirectoryServicePrincipalSecret = t.object({
|
|
9
12
|
type: t.literal('azure-active-directory-service-principal-secret'),
|
|
10
13
|
options: t.object({
|
|
@@ -62,7 +65,11 @@ export const MSSQLConnectionConfig = service_types.configFile.DataSourceConfig.a
|
|
|
62
65
|
port: service_types.configFile.portCodec.optional(),
|
|
63
66
|
authentication: Authentication.optional(),
|
|
64
67
|
reject_ip_ranges: t.array(t.string).optional(),
|
|
65
|
-
additionalConfig: AdditionalConfig.optional()
|
|
68
|
+
additionalConfig: AdditionalConfig.optional(),
|
|
69
|
+
/**
|
|
70
|
+
* Interval in seconds between source connection heartbeats. Null or omitted uses the default.
|
|
71
|
+
*/
|
|
72
|
+
heartbeat_interval_seconds: t.number.or(t.Null).optional()
|
|
66
73
|
}));
|
|
67
74
|
/**
|
|
68
75
|
* Validate and normalize connection options.
|
|
@@ -113,9 +120,19 @@ export function normalizeConnectionConfig(options) {
|
|
|
113
120
|
pollingIntervalMs: options.additionalConfig?.pollingIntervalMs ?? DEFAULT_POLLING_INTERVAL_MS,
|
|
114
121
|
pollingBatchSize: options.additionalConfig?.pollingBatchSize ?? DEFAULT_POLLING_BATCH_SIZE,
|
|
115
122
|
trustServerCertificate: options.additionalConfig?.trustServerCertificate ?? false
|
|
116
|
-
}
|
|
123
|
+
},
|
|
124
|
+
heartbeat_interval_seconds: normalizeHeartbeatInterval(options.heartbeat_interval_seconds)
|
|
117
125
|
};
|
|
118
126
|
}
|
|
127
|
+
function normalizeHeartbeatInterval(value) {
|
|
128
|
+
if (value == null) {
|
|
129
|
+
return DEFAULT_HEARTBEAT_INTERVAL_SECONDS;
|
|
130
|
+
}
|
|
131
|
+
if (!Number.isFinite(value) || value < MIN_HEARTBEAT_INTERVAL_SECONDS || value > MAX_HEARTBEAT_INTERVAL_SECONDS) {
|
|
132
|
+
throw new ServiceError(ErrorCode.PSYNC_S1109, `MSSQL connection: heartbeat_interval_seconds must be between ${MIN_HEARTBEAT_INTERVAL_SECONDS} and ${MAX_HEARTBEAT_INTERVAL_SECONDS} seconds`);
|
|
133
|
+
}
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
119
136
|
export function baseUri(config) {
|
|
120
137
|
return `mssql://${config.hostname}:${config.port}/${config.database}`;
|
|
121
138
|
}
|
package/dist/types/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACxG,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAC9B,OAAO,KAAK,KAAK,MAAM,QAAQ,CAAC;AAEhC,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAgB,CAAC;AAEtD,MAAM,CAAC,MAAM,0CAA0C,GAAG,CAAC,CAAC,MAAM,CAAC;IACjE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iDAAiD,CAAC;IAClE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB;;WAEG;QACH,QAAQ,EAAE,CAAC,CAAC,MAAM;QAClB;;WAEG;QACH,YAAY,EAAE,CAAC,CAAC,MAAM;QACtB;;WAEG;QACH,QAAQ,EAAE,CAAC,CAAC,MAAM;KACnB,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB;;WAEG;QACH,QAAQ,EAAE,CAAC,CAAC,MAAM;QAClB;;WAEG;QACH,QAAQ,EAAE,CAAC,CAAC,MAAM;KACnB,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,cAAc,GAAG,qBAAqB,CAAC,EAAE,CAAC,0CAA0C,CAAC,CAAC;AAGnG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC;;OAEG;IACH,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;IACtC;;OAEG;IACH,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;IAErC;;;OAGG;IACH,sBAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { logger } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, logger, ServiceError } from '@powersync/lib-services-framework';
|
|
2
2
|
import sql from 'mssql';
|
|
3
3
|
async function getColumns(options) {
|
|
4
4
|
const { connectionManager, schema, tableName } = options;
|
|
@@ -98,6 +98,9 @@ export async function getReplicationIdentityColumns(options) {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
export async function getTablesFromPattern(connectionManager, tablePattern) {
|
|
101
|
+
if (tablePattern.isSchemaWildcard) {
|
|
102
|
+
throw new ServiceError(ErrorCode.PSYNC_R2201, 'Schema wildcards ("%") in table patterns are not supported for SQL Server connections.');
|
|
103
|
+
}
|
|
101
104
|
if (tablePattern.isWildcard) {
|
|
102
105
|
const { recordset: tableResults } = await connectionManager.query(`
|
|
103
106
|
SELECT
|
package/dist/utils/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEpF,OAAO,GAAG,MAAM,OAAO,CAAC;AAUxB,KAAK,UAAU,UAAU,CAAC,OAA0B;IAClD,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAEzD,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAChE;;;;;;;;;;;;;OAaG,EACH;QACE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;QAC7D,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE;KACpE,CACF,CAAC;IAEF,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/B,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,OAAO;YACnB,UAAU,EAAE,GAAG,CAAC,YAAY;SAC7B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAaD,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAA6C;IAE7C,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACzD,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,CACpE;;;;;;;;;;;;;;;OAeG,EACH;QACE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;QAC7D,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE;KACpE,CACF,CAAC;IAEF,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,OAAO;gBACnB,UAAU,EAAE,GAAG,CAAC,YAAY;aAC7B,CAAC,CAAC;YACH,QAAQ,EAAE,SAAS;SACpB,CAAC;IACJ,CAAC;IAED,kFAAkF;IAClF,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,CACnE;;;;;;;;;;;;;;;OAeG,EACH;QACE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;QAC7D,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE;KACpE,CACF,CAAC;IAEF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACtC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,OAAO;gBACnB,UAAU,EAAE,GAAG,CAAC,YAAY;aAC7B,CAAC,CAAC;YACH,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IAE7C,OAAO;QACL,OAAO,EAAE,UAAU;QACnB,QAAQ,EAAE,MAAM;KACjB,CAAC;AACJ,CAAC;AAUD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,iBAAyC,EACzC,YAA0B;IAE1B,IAAI,YAAY,CAAC,gBAAgB,EAAE,CAAC;QAClC,MAAM,IAAI,YAAY,CACpB,SAAS,CAAC,WAAW,EACrB,wFAAwF,CACzF,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,UAAU,EAAE,CAAC;QAC5B,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAC/D;;;;;;;;;OASC,EACD;YACE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE;YAC1E,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,YAAY,EAAE;SACvF,CACF,CAAC;QAEF,OAAO,YAAY;aAChB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACX,OAAO;gBACL,QAAQ,EAAE,GAAG,CAAC,SAAS;gBACvB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,KAAK;aAChB,CAAC;QACJ,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAC/D;;;;;;;;;OASC,EACD;YACE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE;YAC1E,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,YAAY,EAAE;SACvF,CACF,CAAC;QAEF,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC9B,OAAO;gBACL,QAAQ,EAAE,GAAG,CAAC,SAAS;gBACvB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,KAAK;aAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAOD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAuC;IACnF,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,4BAA4B,EAAE;YAC3F,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE;SACrF,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,oGAAoG;YACpG,MAAM,CAAC,IAAI,CAAC,4DAA4D,mBAAmB,IAAI,CAAC,CAAC;YACjG,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACpE,qEAAqE;QACrE,OAAQ,KAA6B,CAAC,MAAM,KAAK,KAAK,CAAC;IACzD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,iBAAyC;IAC1F,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,qDAAqD,EAAE;QAClH,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;KACnD,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/service-module-mssql",
|
|
3
3
|
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"license": "FSL-1.1-ALv2",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"publishConfig": {
|
|
@@ -17,20 +17,20 @@
|
|
|
17
17
|
"ts-codec": "^1.3.0",
|
|
18
18
|
"uri-js": "^4.4.1",
|
|
19
19
|
"uuid": "^14.0.0",
|
|
20
|
-
"@powersync/lib-services-framework": "0.
|
|
21
|
-
"@powersync/service-core": "1.
|
|
22
|
-
"@powersync/service-errors": "0.
|
|
20
|
+
"@powersync/lib-services-framework": "0.10.0",
|
|
21
|
+
"@powersync/service-core": "1.24.0",
|
|
22
|
+
"@powersync/service-errors": "0.5.0",
|
|
23
23
|
"@powersync/service-jsonbig": "0.17.13",
|
|
24
|
-
"@powersync/service-sync-rules": "0.
|
|
25
|
-
"@powersync/service-types": "0.
|
|
24
|
+
"@powersync/service-sync-rules": "0.40.0",
|
|
25
|
+
"@powersync/service-types": "0.17.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/mssql": "^9.1.9",
|
|
29
29
|
"@types/semver": "^7.7.1",
|
|
30
30
|
"@types/uuid": "^11.0.0",
|
|
31
|
-
"@powersync/service-core-tests": "0.
|
|
32
|
-
"@powersync/service-module-mongodb-storage": "0.
|
|
33
|
-
"@powersync/service-module-postgres-storage": "0.
|
|
31
|
+
"@powersync/service-core-tests": "0.18.0",
|
|
32
|
+
"@powersync/service-module-mongodb-storage": "0.19.0",
|
|
33
|
+
"@powersync/service-module-postgres-storage": "0.17.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsc -b",
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
api,
|
|
3
|
-
ParseSyncConfigOptions,
|
|
4
|
-
PatternResult,
|
|
5
|
-
ReplicationHeadCallback,
|
|
6
|
-
ReplicationLagOptions
|
|
7
|
-
} from '@powersync/service-core';
|
|
1
|
+
import { api, ParseSyncConfigOptions, PatternResult, ReplicationLagOptions } from '@powersync/service-core';
|
|
8
2
|
import { SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
|
|
9
3
|
import * as service_types from '@powersync/service-types';
|
|
10
4
|
import sql from 'mssql';
|
|
@@ -27,14 +21,16 @@ export class MSSQLRouteAPIAdapter implements api.RouteAPI {
|
|
|
27
21
|
this.connectionManager = new MSSQLConnectionManager(config, {});
|
|
28
22
|
}
|
|
29
23
|
|
|
30
|
-
async createReplicationHead<T>(callback: ReplicationHeadCallback<T>): Promise<T> {
|
|
31
|
-
const currentLSN = await getLatestLSN(this.connectionManager);
|
|
32
|
-
const
|
|
24
|
+
async createReplicationHead<T>(callback: api.ReplicationHeadCallback<T>): Promise<T> {
|
|
25
|
+
const currentLSN = (await getLatestLSN(this.connectionManager)).toString();
|
|
26
|
+
const { response, shouldAdvance } = await callback(currentLSN);
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
if (shouldAdvance) {
|
|
29
|
+
// Updates the powersync checkpoints table on the source database, ensuring that an update with a newer LSN will be captured by the CDC.
|
|
30
|
+
await createCheckpoint(this.connectionManager);
|
|
31
|
+
}
|
|
36
32
|
|
|
37
|
-
return
|
|
33
|
+
return response;
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
async executeQuery(query: string, params: any[]): Promise<service_types.internal_routes.ExecuteSqlResponse> {
|
|
@@ -41,7 +41,8 @@ export class MSSQLModule extends replication.ReplicationModule<types.MSSQLConnec
|
|
|
41
41
|
metricsEngine: context.metricsEngine,
|
|
42
42
|
connectionFactory: connectionFactory,
|
|
43
43
|
rateLimiter: new MSSQLErrorRateLimiter(),
|
|
44
|
-
additionalConfig: normalisedConfig.additionalConfig
|
|
44
|
+
additionalConfig: normalisedConfig.additionalConfig,
|
|
45
|
+
heartbeatIntervalSeconds: normalisedConfig.heartbeat_interval_seconds
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
|
package/src/types/types.ts
CHANGED
|
@@ -8,6 +8,10 @@ export const DEFAULT_POLLING_BATCH_SIZE = 10;
|
|
|
8
8
|
export const DEFAULT_POLLING_INTERVAL_MS = 1000;
|
|
9
9
|
export const MSSQL_CONNECTION_TYPE = 'mssql' as const;
|
|
10
10
|
|
|
11
|
+
const DEFAULT_HEARTBEAT_INTERVAL_SECONDS = 60;
|
|
12
|
+
const MIN_HEARTBEAT_INTERVAL_SECONDS = 5;
|
|
13
|
+
const MAX_HEARTBEAT_INTERVAL_SECONDS = 60;
|
|
14
|
+
|
|
11
15
|
export const AzureActiveDirectoryServicePrincipalSecret = t.object({
|
|
12
16
|
type: t.literal('azure-active-directory-service-principal-secret'),
|
|
13
17
|
options: t.object({
|
|
@@ -94,6 +98,8 @@ export interface NormalizedMSSQLConnectionConfig {
|
|
|
94
98
|
lookup?: LookupFunction;
|
|
95
99
|
|
|
96
100
|
additionalConfig: AdditionalConfig;
|
|
101
|
+
|
|
102
|
+
heartbeat_interval_seconds: number;
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
export const MSSQLConnectionConfig = service_types.configFile.DataSourceConfig.and(
|
|
@@ -110,7 +116,11 @@ export const MSSQLConnectionConfig = service_types.configFile.DataSourceConfig.a
|
|
|
110
116
|
authentication: Authentication.optional(),
|
|
111
117
|
|
|
112
118
|
reject_ip_ranges: t.array(t.string).optional(),
|
|
113
|
-
additionalConfig: AdditionalConfig.optional()
|
|
119
|
+
additionalConfig: AdditionalConfig.optional(),
|
|
120
|
+
/**
|
|
121
|
+
* Interval in seconds between source connection heartbeats. Null or omitted uses the default.
|
|
122
|
+
*/
|
|
123
|
+
heartbeat_interval_seconds: t.number.or(t.Null).optional()
|
|
114
124
|
})
|
|
115
125
|
);
|
|
116
126
|
|
|
@@ -188,10 +198,24 @@ export function normalizeConnectionConfig(options: MSSQLConnectionConfig): Norma
|
|
|
188
198
|
pollingIntervalMs: options.additionalConfig?.pollingIntervalMs ?? DEFAULT_POLLING_INTERVAL_MS,
|
|
189
199
|
pollingBatchSize: options.additionalConfig?.pollingBatchSize ?? DEFAULT_POLLING_BATCH_SIZE,
|
|
190
200
|
trustServerCertificate: options.additionalConfig?.trustServerCertificate ?? false
|
|
191
|
-
}
|
|
201
|
+
},
|
|
202
|
+
heartbeat_interval_seconds: normalizeHeartbeatInterval(options.heartbeat_interval_seconds)
|
|
192
203
|
} satisfies NormalizedMSSQLConnectionConfig;
|
|
193
204
|
}
|
|
194
205
|
|
|
206
|
+
function normalizeHeartbeatInterval(value: number | null | undefined): number {
|
|
207
|
+
if (value == null) {
|
|
208
|
+
return DEFAULT_HEARTBEAT_INTERVAL_SECONDS;
|
|
209
|
+
}
|
|
210
|
+
if (!Number.isFinite(value) || value < MIN_HEARTBEAT_INTERVAL_SECONDS || value > MAX_HEARTBEAT_INTERVAL_SECONDS) {
|
|
211
|
+
throw new ServiceError(
|
|
212
|
+
ErrorCode.PSYNC_S1109,
|
|
213
|
+
`MSSQL connection: heartbeat_interval_seconds must be between ${MIN_HEARTBEAT_INTERVAL_SECONDS} and ${MAX_HEARTBEAT_INTERVAL_SECONDS} seconds`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
|
|
195
219
|
export function baseUri(config: ResolvedMSSQLConnectionConfig) {
|
|
196
220
|
return `mssql://${config.hostname}:${config.port}/${config.database}`;
|
|
197
221
|
}
|
package/src/utils/schema.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { logger } from '@powersync/lib-services-framework';
|
|
1
|
+
import { ErrorCode, logger, ServiceError } from '@powersync/lib-services-framework';
|
|
2
2
|
import { TablePattern } from '@powersync/service-sync-rules';
|
|
3
3
|
import sql from 'mssql';
|
|
4
4
|
import { MSSQLConnectionManager } from '../replication/MSSQLConnectionManager.js';
|
|
@@ -150,6 +150,13 @@ export async function getTablesFromPattern(
|
|
|
150
150
|
connectionManager: MSSQLConnectionManager,
|
|
151
151
|
tablePattern: TablePattern
|
|
152
152
|
): Promise<ResolvedTable[]> {
|
|
153
|
+
if (tablePattern.isSchemaWildcard) {
|
|
154
|
+
throw new ServiceError(
|
|
155
|
+
ErrorCode.PSYNC_R2201,
|
|
156
|
+
'Schema wildcards ("%") in table patterns are not supported for SQL Server connections.'
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
153
160
|
if (tablePattern.isWildcard) {
|
|
154
161
|
const { recordset: tableResults } = await connectionManager.query(
|
|
155
162
|
`
|
|
@@ -203,7 +203,7 @@ export class CDCStreamTestContext implements AsyncDisposable {
|
|
|
203
203
|
while (true) {
|
|
204
204
|
const batch = this.storage!.getBucketDataBatch(checkpoint, map);
|
|
205
205
|
|
|
206
|
-
const batches = await test_utils.
|
|
206
|
+
const batches = await test_utils.getBatchArray(batch);
|
|
207
207
|
data = data.concat(batches[0]?.chunkData.data ?? []);
|
|
208
208
|
if (batches.length == 0 || !batches[0]!.chunkData.has_more) {
|
|
209
209
|
break;
|
|
@@ -230,7 +230,7 @@ export class CDCStreamTestContext implements AsyncDisposable {
|
|
|
230
230
|
const syncConfigContent = this.getSyncConfigContent();
|
|
231
231
|
const map = [bucketRequest(syncConfigContent, bucket, start)];
|
|
232
232
|
const batch = this.storage!.getBucketDataBatch(checkpoint, map);
|
|
233
|
-
const batches = await test_utils.
|
|
233
|
+
const batches = await test_utils.getBatchArray(batch);
|
|
234
234
|
return batches[0]?.chunkData.data ?? [];
|
|
235
235
|
}
|
|
236
236
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { normalizeConnectionConfig } from '@module/types/types.js';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
|
|
4
|
+
const BASE_CONFIG = {
|
|
5
|
+
type: 'mssql' as const,
|
|
6
|
+
uri: 'mssql://user:password@localhost:1433/powersync_test'
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
describe('SQL Server connection config', () => {
|
|
10
|
+
test('defaults heartbeat_interval_seconds to 60 seconds', () => {
|
|
11
|
+
expect(normalizeConnectionConfig(BASE_CONFIG).heartbeat_interval_seconds).toBe(60);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('uses the default for a null heartbeat_interval_seconds', () => {
|
|
15
|
+
expect(
|
|
16
|
+
normalizeConnectionConfig({ ...BASE_CONFIG, heartbeat_interval_seconds: null }).heartbeat_interval_seconds
|
|
17
|
+
).toBe(60);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('allows the SQL Server maximum heartbeat interval', () => {
|
|
21
|
+
expect(
|
|
22
|
+
normalizeConnectionConfig({ ...BASE_CONFIG, heartbeat_interval_seconds: 60 }).heartbeat_interval_seconds
|
|
23
|
+
).toBe(60);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test.each([0, 4, 61, Number.NaN, Number.POSITIVE_INFINITY])(
|
|
27
|
+
'rejects invalid heartbeat_interval_seconds: %s',
|
|
28
|
+
(heartbeat_interval_seconds) => {
|
|
29
|
+
expect(() => normalizeConnectionConfig({ ...BASE_CONFIG, heartbeat_interval_seconds })).toThrow(
|
|
30
|
+
'heartbeat_interval_seconds'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
});
|