@powersync/service-module-mysql 0.10.2 → 0.12.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 +47 -0
- package/dist/api/MySQLRouteAPIAdapter.js +1 -1
- package/dist/api/MySQLRouteAPIAdapter.js.map +1 -1
- package/dist/common/check-source-configuration.js +12 -1
- package/dist/common/check-source-configuration.js.map +1 -1
- package/dist/replication/BinLogStream.js +14 -10
- package/dist/replication/BinLogStream.js.map +1 -1
- package/dist/types/types.d.ts +25 -0
- package/dist/types/types.js +45 -1
- package/dist/types/types.js.map +1 -1
- package/dist/utils/mysql-utils.js +6 -0
- package/dist/utils/mysql-utils.js.map +1 -1
- package/package.json +8 -8
- package/src/api/MySQLRouteAPIAdapter.ts +1 -1
- package/src/common/check-source-configuration.ts +16 -1
- package/src/replication/BinLogStream.ts +17 -10
- package/src/types/types.ts +68 -1
- package/src/utils/mysql-utils.ts +8 -0
- package/test/src/BinLogStream.test.ts +3 -1
- package/test/src/BinlogStreamUtils.ts +22 -5
- package/test/src/config.test.ts +165 -0
- package/test/src/schema-changes.test.ts +2 -1
- package/test/src/util.ts +9 -9
- package/tsconfig.tsbuildinfo +1 -1
package/src/types/types.ts
CHANGED
|
@@ -6,6 +6,18 @@ import * as urijs from 'uri-js';
|
|
|
6
6
|
|
|
7
7
|
export const MYSQL_CONNECTION_TYPE = 'mysql' as const;
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Connection parameters that can be parsed from the MySQL URI query string.
|
|
11
|
+
*
|
|
12
|
+
* All values are in milliseconds (for timeouts) or counts (for limits).
|
|
13
|
+
* MySQL uses camelCase naming convention.
|
|
14
|
+
*/
|
|
15
|
+
export interface MySQLConnectionParams {
|
|
16
|
+
connectTimeout?: number;
|
|
17
|
+
connectionLimit?: number;
|
|
18
|
+
queueLimit?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
9
21
|
export interface NormalizedMySQLConnectionConfig {
|
|
10
22
|
id: string;
|
|
11
23
|
tag: string;
|
|
@@ -25,6 +37,8 @@ export interface NormalizedMySQLConnectionConfig {
|
|
|
25
37
|
lookup?: LookupFunction;
|
|
26
38
|
|
|
27
39
|
binlog_queue_memory_limit: number;
|
|
40
|
+
|
|
41
|
+
connectionParams: MySQLConnectionParams;
|
|
28
42
|
}
|
|
29
43
|
|
|
30
44
|
export const MySQLConnectionConfig = service_types.configFile.DataSourceConfig.and(
|
|
@@ -105,6 +119,10 @@ export function normalizeConnectionConfig(options: MySQLConnectionConfig): Norma
|
|
|
105
119
|
|
|
106
120
|
const lookup = makeHostnameLookupFunction(hostname, { reject_ip_ranges: options.reject_ip_ranges ?? [] });
|
|
107
121
|
|
|
122
|
+
// Parse connection parameters from URL query string
|
|
123
|
+
const uriQuery = uri.query ? new URLSearchParams(uri.query) : undefined;
|
|
124
|
+
const connectionParams = parseMySQLConnectionParams(uriQuery);
|
|
125
|
+
|
|
108
126
|
return {
|
|
109
127
|
id: options.id ?? 'default',
|
|
110
128
|
tag: options.tag ?? 'default',
|
|
@@ -121,6 +139,55 @@ export function normalizeConnectionConfig(options: MySQLConnectionConfig): Norma
|
|
|
121
139
|
// Binlog processing queue memory limit before throttling is applied.
|
|
122
140
|
binlog_queue_memory_limit: options.binlog_queue_memory_limit ?? 50,
|
|
123
141
|
|
|
124
|
-
lookup
|
|
142
|
+
lookup,
|
|
143
|
+
|
|
144
|
+
connectionParams
|
|
125
145
|
};
|
|
126
146
|
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Parse a single numeric connection parameter from a URI query string value.
|
|
150
|
+
*
|
|
151
|
+
* Returns undefined if the value is missing, not a valid number, NaN, negative, zero, or Infinity.
|
|
152
|
+
*/
|
|
153
|
+
export function parseMySQLConnectionParam(value: string | null | undefined): number | undefined {
|
|
154
|
+
if (value == null) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
const parsed = Number(value);
|
|
158
|
+
if (isFinite(parsed) && parsed > 0) {
|
|
159
|
+
return parsed;
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Parse connection parameters from a MySQL URI's query string.
|
|
166
|
+
*
|
|
167
|
+
* MySQL uses camelCase naming convention.
|
|
168
|
+
* Invalid values (NaN, negative, non-numeric) are silently ignored.
|
|
169
|
+
*/
|
|
170
|
+
export function parseMySQLConnectionParams(searchParams: URLSearchParams | undefined): MySQLConnectionParams {
|
|
171
|
+
const params: MySQLConnectionParams = {};
|
|
172
|
+
|
|
173
|
+
if (searchParams == null) {
|
|
174
|
+
return params;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const connectTimeout = parseMySQLConnectionParam(searchParams.get('connectTimeout'));
|
|
178
|
+
if (connectTimeout != null) {
|
|
179
|
+
params.connectTimeout = connectTimeout;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const connectionLimit = parseMySQLConnectionParam(searchParams.get('connectionLimit'));
|
|
183
|
+
if (connectionLimit != null) {
|
|
184
|
+
params.connectionLimit = connectionLimit;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const queueLimit = parseMySQLConnectionParam(searchParams.get('queueLimit'));
|
|
188
|
+
if (queueLimit != null) {
|
|
189
|
+
params.queueLimit = queueLimit;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return params;
|
|
193
|
+
}
|
package/src/utils/mysql-utils.ts
CHANGED
|
@@ -37,6 +37,10 @@ export function createPool(config: types.NormalizedMySQLConnectionConfig, option
|
|
|
37
37
|
cert: config.client_certificate
|
|
38
38
|
};
|
|
39
39
|
const hasSSLOptions = Object.values(sslOptions).some((v) => !!v);
|
|
40
|
+
|
|
41
|
+
// URL connection parameters provide defaults; explicit options take precedence
|
|
42
|
+
const params = config.connectionParams;
|
|
43
|
+
|
|
40
44
|
// TODO: Use config.lookup for DNS resolution
|
|
41
45
|
return mysql.createPool({
|
|
42
46
|
host: config.hostname,
|
|
@@ -50,6 +54,10 @@ export function createPool(config: types.NormalizedMySQLConnectionConfig, option
|
|
|
50
54
|
timezone: 'Z', // Ensure no auto timezone manipulation of the dates occur
|
|
51
55
|
jsonStrings: true, // Return JSON columns as strings
|
|
52
56
|
dateStrings: true, // We parse and format them ourselves
|
|
57
|
+
// Apply URL connection parameters (explicit options override these via spread below)
|
|
58
|
+
...(params.connectTimeout != null ? { connectTimeout: params.connectTimeout } : {}),
|
|
59
|
+
...(params.connectionLimit != null ? { connectionLimit: params.connectionLimit } : {}),
|
|
60
|
+
...(params.queueLimit != null ? { queueLimit: params.queueLimit } : {}),
|
|
53
61
|
...(options || {})
|
|
54
62
|
});
|
|
55
63
|
}
|
|
@@ -18,7 +18,9 @@ describe('BinLogStream tests', () => {
|
|
|
18
18
|
describeWithStorage({ timeout: 20_000 }, defineBinlogStreamTests);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
function defineBinlogStreamTests(
|
|
21
|
+
function defineBinlogStreamTests(config: storage.TestStorageConfig) {
|
|
22
|
+
const factory = config.factory;
|
|
23
|
+
|
|
22
24
|
test('Replicate basic values', async () => {
|
|
23
25
|
await using context = await BinlogStreamTestContext.open(factory);
|
|
24
26
|
const { connectionManager } = context;
|
|
@@ -7,13 +7,15 @@ import {
|
|
|
7
7
|
createCoreReplicationMetrics,
|
|
8
8
|
initializeCoreReplicationMetrics,
|
|
9
9
|
InternalOpId,
|
|
10
|
+
LEGACY_STORAGE_VERSION,
|
|
10
11
|
OplogEntry,
|
|
11
12
|
ProtocolOpId,
|
|
12
13
|
ReplicationCheckpoint,
|
|
13
14
|
storage,
|
|
14
|
-
SyncRulesBucketStorage
|
|
15
|
+
SyncRulesBucketStorage,
|
|
16
|
+
updateSyncRulesFromYaml
|
|
15
17
|
} from '@powersync/service-core';
|
|
16
|
-
import { METRICS_HELPER, test_utils } from '@powersync/service-core-tests';
|
|
18
|
+
import { bucketRequest, METRICS_HELPER, test_utils } from '@powersync/service-core-tests';
|
|
17
19
|
import mysqlPromise from 'mysql2/promise';
|
|
18
20
|
import { clearTestDb, TEST_CONNECTION_OPTIONS } from './util.js';
|
|
19
21
|
import timers from 'timers/promises';
|
|
@@ -31,6 +33,7 @@ export class BinlogStreamTestContext {
|
|
|
31
33
|
private streamPromise?: Promise<void>;
|
|
32
34
|
public storage?: SyncRulesBucketStorage;
|
|
33
35
|
private replicationDone = false;
|
|
36
|
+
private syncRulesContent?: storage.PersistedSyncRulesContent;
|
|
34
37
|
|
|
35
38
|
static async open(factory: storage.TestStorageFactory, options?: { doNotClear?: boolean }) {
|
|
36
39
|
const f = await factory({ doNotClear: options?.doNotClear });
|
|
@@ -68,7 +71,10 @@ export class BinlogStreamTestContext {
|
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
async updateSyncRules(content: string): Promise<SyncRulesBucketStorage> {
|
|
71
|
-
const syncRules = await this.factory.updateSyncRules(
|
|
74
|
+
const syncRules = await this.factory.updateSyncRules(
|
|
75
|
+
updateSyncRulesFromYaml(content, { validate: true, storageVersion: LEGACY_STORAGE_VERSION })
|
|
76
|
+
);
|
|
77
|
+
this.syncRulesContent = syncRules;
|
|
72
78
|
this.storage = this.factory.getInstance(syncRules);
|
|
73
79
|
return this.storage!;
|
|
74
80
|
}
|
|
@@ -79,6 +85,7 @@ export class BinlogStreamTestContext {
|
|
|
79
85
|
throw new Error(`Next sync rules not available`);
|
|
80
86
|
}
|
|
81
87
|
|
|
88
|
+
this.syncRulesContent = syncRules;
|
|
82
89
|
this.storage = this.factory.getInstance(syncRules);
|
|
83
90
|
return this.storage!;
|
|
84
91
|
}
|
|
@@ -89,11 +96,19 @@ export class BinlogStreamTestContext {
|
|
|
89
96
|
throw new Error(`Active sync rules not available`);
|
|
90
97
|
}
|
|
91
98
|
|
|
99
|
+
this.syncRulesContent = syncRules;
|
|
92
100
|
this.storage = this.factory.getInstance(syncRules);
|
|
93
101
|
this.replicationDone = true;
|
|
94
102
|
return this.storage!;
|
|
95
103
|
}
|
|
96
104
|
|
|
105
|
+
private getSyncRulesContent(): storage.PersistedSyncRulesContent {
|
|
106
|
+
if (this.syncRulesContent == null) {
|
|
107
|
+
throw new Error('Sync rules not configured - call updateSyncRules() first');
|
|
108
|
+
}
|
|
109
|
+
return this.syncRulesContent;
|
|
110
|
+
}
|
|
111
|
+
|
|
97
112
|
get binlogStream(): BinLogStream {
|
|
98
113
|
if (this.storage == null) {
|
|
99
114
|
throw new Error('updateSyncRules() first');
|
|
@@ -150,7 +165,8 @@ export class BinlogStreamTestContext {
|
|
|
150
165
|
|
|
151
166
|
async getBucketsDataBatch(buckets: Record<string, InternalOpId>, options?: { timeout?: number }) {
|
|
152
167
|
const checkpoint = await this.getCheckpoint(options);
|
|
153
|
-
const
|
|
168
|
+
const syncRules = this.getSyncRulesContent();
|
|
169
|
+
const map = Object.entries(buckets).map(([bucket, start]) => bucketRequest(syncRules, bucket, start));
|
|
154
170
|
return test_utils.fromAsync(this.storage!.getBucketDataBatch(checkpoint, map));
|
|
155
171
|
}
|
|
156
172
|
|
|
@@ -163,8 +179,9 @@ export class BinlogStreamTestContext {
|
|
|
163
179
|
if (typeof start == 'string') {
|
|
164
180
|
start = BigInt(start);
|
|
165
181
|
}
|
|
182
|
+
const syncRules = this.getSyncRulesContent();
|
|
166
183
|
const checkpoint = await this.getCheckpoint(options);
|
|
167
|
-
const map =
|
|
184
|
+
const map = [bucketRequest(syncRules, bucket, start)];
|
|
168
185
|
const batch = this.storage!.getBucketDataBatch(checkpoint, map);
|
|
169
186
|
const batches = await test_utils.fromAsync(batch);
|
|
170
187
|
return batches[0]?.chunkData.data ?? [];
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
normalizeConnectionConfig,
|
|
4
|
+
parseMySQLConnectionParam,
|
|
5
|
+
parseMySQLConnectionParams
|
|
6
|
+
} from '@module/types/types.js';
|
|
7
|
+
|
|
8
|
+
describe('config', () => {
|
|
9
|
+
test('Should resolve database', () => {
|
|
10
|
+
const normalized = normalizeConnectionConfig({
|
|
11
|
+
type: 'mysql',
|
|
12
|
+
uri: 'mysql://user:pass@localhost:3306/mydb'
|
|
13
|
+
});
|
|
14
|
+
expect(normalized.database).equals('mydb');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('connection parameters', () => {
|
|
18
|
+
test('parses all connection parameters from URL query string', () => {
|
|
19
|
+
const normalized = normalizeConnectionConfig({
|
|
20
|
+
type: 'mysql',
|
|
21
|
+
uri: 'mysql://user:pass@localhost:3306/mydb?connectTimeout=5000&connectionLimit=20&queueLimit=100'
|
|
22
|
+
});
|
|
23
|
+
expect(normalized.connectionParams.connectTimeout).equals(5000);
|
|
24
|
+
expect(normalized.connectionParams.connectionLimit).equals(20);
|
|
25
|
+
expect(normalized.connectionParams.queueLimit).equals(100);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('URL without connection parameters returns empty connectionParams', () => {
|
|
29
|
+
const normalized = normalizeConnectionConfig({
|
|
30
|
+
type: 'mysql',
|
|
31
|
+
uri: 'mysql://user:pass@localhost:3306/mydb'
|
|
32
|
+
});
|
|
33
|
+
expect(normalized.connectionParams).toEqual({});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('parameters can be partially specified', () => {
|
|
37
|
+
const normalized = normalizeConnectionConfig({
|
|
38
|
+
type: 'mysql',
|
|
39
|
+
uri: 'mysql://user:pass@localhost:3306/mydb?connectTimeout=5000&queueLimit=50'
|
|
40
|
+
});
|
|
41
|
+
expect(normalized.connectionParams.connectTimeout).equals(5000);
|
|
42
|
+
expect(normalized.connectionParams.queueLimit).equals(50);
|
|
43
|
+
expect(normalized.connectionParams.connectionLimit).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('ignores invalid (non-numeric) connection parameter values', () => {
|
|
47
|
+
const normalized = normalizeConnectionConfig({
|
|
48
|
+
type: 'mysql',
|
|
49
|
+
uri: 'mysql://user:pass@localhost:3306/mydb?connectTimeout=abc&connectionLimit=xyz'
|
|
50
|
+
});
|
|
51
|
+
expect(normalized.connectionParams.connectTimeout).toBeUndefined();
|
|
52
|
+
expect(normalized.connectionParams.connectionLimit).toBeUndefined();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('ignores negative connection parameter values', () => {
|
|
56
|
+
const normalized = normalizeConnectionConfig({
|
|
57
|
+
type: 'mysql',
|
|
58
|
+
uri: 'mysql://user:pass@localhost:3306/mydb?connectTimeout=-5000&connectionLimit=-10'
|
|
59
|
+
});
|
|
60
|
+
expect(normalized.connectionParams.connectTimeout).toBeUndefined();
|
|
61
|
+
expect(normalized.connectionParams.connectionLimit).toBeUndefined();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('ignores zero connection parameter values', () => {
|
|
65
|
+
const normalized = normalizeConnectionConfig({
|
|
66
|
+
type: 'mysql',
|
|
67
|
+
uri: 'mysql://user:pass@localhost:3306/mydb?connectTimeout=0&connectionLimit=0&queueLimit=0'
|
|
68
|
+
});
|
|
69
|
+
expect(normalized.connectionParams.connectTimeout).toBeUndefined();
|
|
70
|
+
expect(normalized.connectionParams.connectionLimit).toBeUndefined();
|
|
71
|
+
expect(normalized.connectionParams.queueLimit).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('works without URI (config-only)', () => {
|
|
75
|
+
const normalized = normalizeConnectionConfig({
|
|
76
|
+
type: 'mysql',
|
|
77
|
+
hostname: 'localhost',
|
|
78
|
+
port: 3306,
|
|
79
|
+
database: 'mydb',
|
|
80
|
+
username: 'user',
|
|
81
|
+
password: 'pass'
|
|
82
|
+
});
|
|
83
|
+
expect(normalized.connectionParams).toEqual({});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('parseMySQLConnectionParam', () => {
|
|
89
|
+
test('returns undefined when no value provided', () => {
|
|
90
|
+
expect(parseMySQLConnectionParam(undefined)).toBeUndefined();
|
|
91
|
+
expect(parseMySQLConnectionParam(null)).toBeUndefined();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('parses valid numeric string', () => {
|
|
95
|
+
expect(parseMySQLConnectionParam('5000')).equals(5000);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('parses fractional values', () => {
|
|
99
|
+
expect(parseMySQLConnectionParam('1500.5')).equals(1500.5);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('ignores non-numeric string', () => {
|
|
103
|
+
expect(parseMySQLConnectionParam('abc')).toBeUndefined();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('ignores empty string', () => {
|
|
107
|
+
expect(parseMySQLConnectionParam('')).toBeUndefined();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('ignores negative value', () => {
|
|
111
|
+
expect(parseMySQLConnectionParam('-5000')).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('ignores zero', () => {
|
|
115
|
+
expect(parseMySQLConnectionParam('0')).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('ignores Infinity', () => {
|
|
119
|
+
expect(parseMySQLConnectionParam('Infinity')).toBeUndefined();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('ignores NaN', () => {
|
|
123
|
+
expect(parseMySQLConnectionParam('NaN')).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('parseMySQLConnectionParams', () => {
|
|
128
|
+
test('parses all supported parameters', () => {
|
|
129
|
+
const params = new URLSearchParams('connectTimeout=5000&connectionLimit=20&queueLimit=100');
|
|
130
|
+
const result = parseMySQLConnectionParams(params);
|
|
131
|
+
expect(result).toEqual({
|
|
132
|
+
connectTimeout: 5000,
|
|
133
|
+
connectionLimit: 20,
|
|
134
|
+
queueLimit: 100
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('returns empty object when no connection params present', () => {
|
|
139
|
+
const params = new URLSearchParams('someOther=value');
|
|
140
|
+
const result = parseMySQLConnectionParams(params);
|
|
141
|
+
expect(result).toEqual({});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('returns empty object for undefined searchParams', () => {
|
|
145
|
+
const result = parseMySQLConnectionParams(undefined);
|
|
146
|
+
expect(result).toEqual({});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('ignores invalid values and only includes valid ones', () => {
|
|
150
|
+
const params = new URLSearchParams('connectTimeout=5000&connectionLimit=abc&queueLimit=-10');
|
|
151
|
+
const result = parseMySQLConnectionParams(params);
|
|
152
|
+
expect(result).toEqual({
|
|
153
|
+
connectTimeout: 5000
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('handles partial parameter specification', () => {
|
|
158
|
+
const params = new URLSearchParams('connectTimeout=5000&queueLimit=100');
|
|
159
|
+
const result = parseMySQLConnectionParams(params);
|
|
160
|
+
expect(result).toEqual({
|
|
161
|
+
connectTimeout: 5000,
|
|
162
|
+
queueLimit: 100
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
@@ -26,7 +26,8 @@ const PUT_T3 = test_utils.putOp('test_data', { id: 't3', description: 'test3' })
|
|
|
26
26
|
const REMOVE_T1 = test_utils.removeOp('test_data', 't1');
|
|
27
27
|
const REMOVE_T2 = test_utils.removeOp('test_data', 't2');
|
|
28
28
|
|
|
29
|
-
function defineTests(
|
|
29
|
+
function defineTests(config: storage.TestStorageConfig) {
|
|
30
|
+
const factory = config.factory;
|
|
30
31
|
let isMySQL57: boolean = false;
|
|
31
32
|
|
|
32
33
|
beforeAll(async () => {
|
package/test/src/util.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
import * as common from '@module/common/common-index.js';
|
|
2
|
+
import { MySQLConnectionManager } from '@module/replication/MySQLConnectionManager.js';
|
|
3
|
+
import { BinLogEventHandler, BinLogListener, Row, SchemaChange } from '@module/replication/zongji/BinLogListener.js';
|
|
1
4
|
import * as types from '@module/types/types.js';
|
|
2
5
|
import { createRandomServerId, getMySQLVersion, isVersionAtLeast } from '@module/utils/mysql-utils.js';
|
|
6
|
+
import { TableMapEntry } from '@powersync/mysql-zongji';
|
|
7
|
+
import { TestStorageConfig } from '@powersync/service-core';
|
|
3
8
|
import * as mongo_storage from '@powersync/service-module-mongodb-storage';
|
|
4
9
|
import * as postgres_storage from '@powersync/service-module-postgres-storage';
|
|
10
|
+
import { TablePattern } from '@powersync/service-sync-rules';
|
|
5
11
|
import mysqlPromise from 'mysql2/promise';
|
|
6
|
-
import { env } from './env.js';
|
|
7
12
|
import { describe, TestOptions } from 'vitest';
|
|
8
|
-
import {
|
|
9
|
-
import { MySQLConnectionManager } from '@module/replication/MySQLConnectionManager.js';
|
|
10
|
-
import { BinLogEventHandler, BinLogListener, Row, SchemaChange } from '@module/replication/zongji/BinLogListener.js';
|
|
11
|
-
import { TableMapEntry } from '@powersync/mysql-zongji';
|
|
12
|
-
import * as common from '@module/common/common-index.js';
|
|
13
|
-
import { TablePattern } from '@powersync/service-sync-rules';
|
|
13
|
+
import { env } from './env.js';
|
|
14
14
|
|
|
15
15
|
export const TEST_URI = env.MYSQL_TEST_URI;
|
|
16
16
|
|
|
@@ -24,11 +24,11 @@ export const INITIALIZED_MONGO_STORAGE_FACTORY = mongo_storage.test_utils.mongoT
|
|
|
24
24
|
isCI: env.CI
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
export const INITIALIZED_POSTGRES_STORAGE_FACTORY = postgres_storage.test_utils.
|
|
27
|
+
export const INITIALIZED_POSTGRES_STORAGE_FACTORY = postgres_storage.test_utils.postgresTestSetup({
|
|
28
28
|
url: env.PG_STORAGE_TEST_URL
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
export function describeWithStorage(options: TestOptions, fn: (factory:
|
|
31
|
+
export function describeWithStorage(options: TestOptions, fn: (factory: TestStorageConfig) => void) {
|
|
32
32
|
describe.skipIf(!env.TEST_MONGO_STORAGE)(`mongodb storage`, options, function () {
|
|
33
33
|
fn(INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
34
34
|
});
|