@powersync/service-module-mysql 0.7.4 → 0.8.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 +30 -0
- package/dev/docker/mysql/init-scripts/my.cnf +1 -3
- package/dist/api/MySQLRouteAPIAdapter.js +11 -3
- package/dist/api/MySQLRouteAPIAdapter.js.map +1 -1
- package/dist/common/ReplicatedGTID.js +4 -0
- package/dist/common/ReplicatedGTID.js.map +1 -1
- package/dist/common/common-index.d.ts +1 -2
- package/dist/common/common-index.js +1 -2
- package/dist/common/common-index.js.map +1 -1
- package/dist/common/mysql-to-sqlite.js +4 -0
- package/dist/common/mysql-to-sqlite.js.map +1 -1
- package/dist/common/schema-utils.d.ts +20 -0
- package/dist/common/{get-replication-columns.js → schema-utils.js} +73 -30
- package/dist/common/schema-utils.js.map +1 -0
- package/dist/replication/BinLogStream.d.ts +9 -6
- package/dist/replication/BinLogStream.js +99 -70
- package/dist/replication/BinLogStream.js.map +1 -1
- package/dist/replication/zongji/BinLogListener.d.ts +52 -5
- package/dist/replication/zongji/BinLogListener.js +302 -85
- package/dist/replication/zongji/BinLogListener.js.map +1 -1
- package/dist/replication/zongji/zongji-utils.d.ts +2 -1
- package/dist/replication/zongji/zongji-utils.js +3 -0
- package/dist/replication/zongji/zongji-utils.js.map +1 -1
- package/dist/types/node-sql-parser-extended-types.d.ts +31 -0
- package/dist/types/node-sql-parser-extended-types.js +2 -0
- package/dist/types/node-sql-parser-extended-types.js.map +1 -0
- package/dist/utils/mysql-utils.d.ts +4 -2
- package/dist/utils/mysql-utils.js +15 -3
- package/dist/utils/mysql-utils.js.map +1 -1
- package/dist/utils/parser-utils.d.ts +16 -0
- package/dist/utils/parser-utils.js +58 -0
- package/dist/utils/parser-utils.js.map +1 -0
- package/package.json +9 -8
- package/src/api/MySQLRouteAPIAdapter.ts +11 -3
- package/src/common/ReplicatedGTID.ts +6 -1
- package/src/common/common-index.ts +1 -2
- package/src/common/mysql-to-sqlite.ts +3 -0
- package/src/common/{get-replication-columns.ts → schema-utils.ts} +96 -37
- package/src/replication/BinLogStream.ts +119 -91
- package/src/replication/zongji/BinLogListener.ts +370 -93
- package/src/replication/zongji/zongji-utils.ts +6 -1
- package/src/types/node-sql-parser-extended-types.ts +25 -0
- package/src/utils/mysql-utils.ts +19 -4
- package/src/utils/parser-utils.ts +73 -0
- package/test/src/BinLogListener.test.ts +415 -32
- package/test/src/BinLogStream.test.ts +128 -52
- package/test/src/BinlogStreamUtils.ts +12 -2
- package/test/src/parser-utils.test.ts +24 -0
- package/test/src/schema-changes.test.ts +663 -0
- package/test/src/util.ts +6 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/common/get-replication-columns.d.ts +0 -12
- package/dist/common/get-replication-columns.js.map +0 -1
- package/dist/common/get-tables-from-pattern.d.ts +0 -7
- package/dist/common/get-tables-from-pattern.js +0 -28
- package/dist/common/get-tables-from-pattern.js.map +0 -1
- package/src/common/get-tables-from-pattern.ts +0 -44
|
@@ -2,26 +2,45 @@ import * as common from '../../common/common-index.js';
|
|
|
2
2
|
import async from 'async';
|
|
3
3
|
import * as zongji_utils from './zongji-utils.js';
|
|
4
4
|
import { logger as defaultLogger } from '@powersync/lib-services-framework';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import timers from 'timers/promises';
|
|
6
|
+
import pkg from 'node-sql-parser';
|
|
7
|
+
import { isAlterTable, isColumnExpression, isConstraintExpression, isCreateUniqueIndex, isDropIndex, isDropTable, isRenameExpression, isRenameTable, isTruncate, matchedSchemaChangeQuery } from '../../utils/parser-utils.js';
|
|
8
|
+
const { Parser } = pkg;
|
|
9
|
+
/**
|
|
10
|
+
* Schema changes that are detectable by inspecting query events.
|
|
11
|
+
* Create table statements are not included here, since new tables are automatically detected when row events
|
|
12
|
+
* are received for them.
|
|
13
|
+
*/
|
|
14
|
+
export var SchemaChangeType;
|
|
15
|
+
(function (SchemaChangeType) {
|
|
16
|
+
SchemaChangeType["RENAME_TABLE"] = "Rename Table";
|
|
17
|
+
SchemaChangeType["DROP_TABLE"] = "Drop Table";
|
|
18
|
+
SchemaChangeType["TRUNCATE_TABLE"] = "Truncate Table";
|
|
19
|
+
SchemaChangeType["ALTER_TABLE_COLUMN"] = "Alter Table Column";
|
|
20
|
+
SchemaChangeType["REPLICATION_IDENTITY"] = "Alter Replication Identity";
|
|
21
|
+
})(SchemaChangeType || (SchemaChangeType = {}));
|
|
8
22
|
/**
|
|
9
23
|
* Wrapper class for the Zongji BinLog listener. Internally handles the creation and management of the listener and posts
|
|
10
24
|
* events on the provided BinLogEventHandler.
|
|
11
25
|
*/
|
|
12
26
|
export class BinLogListener {
|
|
13
27
|
options;
|
|
28
|
+
sqlParser;
|
|
14
29
|
connectionManager;
|
|
15
30
|
eventHandler;
|
|
16
31
|
binLogPosition;
|
|
17
32
|
currentGTID;
|
|
18
33
|
logger;
|
|
34
|
+
listenerError;
|
|
35
|
+
databaseFilter;
|
|
19
36
|
zongji;
|
|
20
37
|
processingQueue;
|
|
38
|
+
isStopped = false;
|
|
39
|
+
isStopping = false;
|
|
21
40
|
/**
|
|
22
41
|
* The combined size in bytes of all the binlog events currently in the processing queue.
|
|
23
42
|
*/
|
|
24
|
-
queueMemoryUsage;
|
|
43
|
+
queueMemoryUsage = 0;
|
|
25
44
|
constructor(options) {
|
|
26
45
|
this.options = options;
|
|
27
46
|
this.logger = options.logger ?? defaultLogger;
|
|
@@ -29,9 +48,11 @@ export class BinLogListener {
|
|
|
29
48
|
this.eventHandler = options.eventHandler;
|
|
30
49
|
this.binLogPosition = options.startPosition;
|
|
31
50
|
this.currentGTID = null;
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
51
|
+
this.sqlParser = new Parser();
|
|
52
|
+
this.processingQueue = this.createProcessingQueue();
|
|
34
53
|
this.zongji = this.createZongjiListener();
|
|
54
|
+
this.listenerError = null;
|
|
55
|
+
this.databaseFilter = this.createDatabaseFilter(options.sourceTables);
|
|
35
56
|
}
|
|
36
57
|
/**
|
|
37
58
|
* The queue memory limit in bytes as defined in the connection options.
|
|
@@ -40,107 +61,128 @@ export class BinLogListener {
|
|
|
40
61
|
get queueMemoryLimit() {
|
|
41
62
|
return this.connectionManager.options.binlog_queue_memory_limit * 1024 * 1024;
|
|
42
63
|
}
|
|
43
|
-
async start() {
|
|
64
|
+
async start(isRestart = false) {
|
|
44
65
|
if (this.isStopped) {
|
|
45
66
|
return;
|
|
46
67
|
}
|
|
47
|
-
this.logger.info(
|
|
68
|
+
this.logger.info(`${isRestart ? 'Restarting' : 'Starting'} BinLog Listener with replica client id:${this.options.serverId}...`);
|
|
69
|
+
// Set a heartbeat interval for the Zongji replication connection
|
|
70
|
+
// Zongji does not explicitly handle the heartbeat events - they are categorized as event:unknown
|
|
71
|
+
// The heartbeat events are enough to keep the connection alive for setTimeout to work on the socket.
|
|
72
|
+
// The heartbeat needs to be set before starting the listener, since the replication connection is locked once replicating
|
|
73
|
+
await new Promise((resolve, reject) => {
|
|
74
|
+
this.zongji.connection.query(
|
|
75
|
+
// In nanoseconds, 10^9 = 1s
|
|
76
|
+
'set @master_heartbeat_period=28*1000000000', (error, results, _fields) => {
|
|
77
|
+
if (error) {
|
|
78
|
+
reject(error);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.logger.info('Successfully set up replication connection heartbeat.');
|
|
82
|
+
resolve(results);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
// The _socket member is only set after a query is run on the connection, so we set the timeout after setting the heartbeat.
|
|
87
|
+
// The timeout here must be greater than the master_heartbeat_period.
|
|
88
|
+
const socket = this.zongji.connection._socket;
|
|
89
|
+
socket.setTimeout(60_000, () => {
|
|
90
|
+
this.logger.info('Destroying socket due to replication connection timeout.');
|
|
91
|
+
socket.destroy(new Error('Replication connection timeout.'));
|
|
92
|
+
});
|
|
48
93
|
this.zongji.start({
|
|
49
94
|
// We ignore the unknown/heartbeat event since it currently serves no purpose other than to keep the connection alive
|
|
50
95
|
// tablemap events always need to be included for the other row events to work
|
|
51
|
-
includeEvents: ['tablemap', 'writerows', 'updaterows', 'deleterows', 'xid', 'rotate', 'gtidlog'],
|
|
52
|
-
includeSchema:
|
|
96
|
+
includeEvents: ['tablemap', 'writerows', 'updaterows', 'deleterows', 'xid', 'rotate', 'gtidlog', 'query'],
|
|
97
|
+
includeSchema: this.databaseFilter,
|
|
53
98
|
filename: this.binLogPosition.filename,
|
|
54
99
|
position: this.binLogPosition.offset,
|
|
55
100
|
serverId: this.options.serverId
|
|
56
101
|
});
|
|
57
|
-
return new Promise((resolve
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.logger.info('BinLog listener was stopped before startup completed.');
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
this.zongji.once('ready', () => {
|
|
104
|
+
this.logger.info(`BinLog Listener ${isRestart ? 'restarted' : 'started'}. Listening for events from position: ${this.binLogPosition.filename}:${this.binLogPosition.offset}`);
|
|
61
105
|
resolve();
|
|
62
|
-
}
|
|
63
|
-
this.zongji.on('error', (error) => {
|
|
64
|
-
if (!this.isStopped) {
|
|
65
|
-
this.logger.error('Binlog listener error:', error);
|
|
66
|
-
this.stop();
|
|
67
|
-
reject(error);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
this.logger.warn('Binlog listener error during shutdown:', error);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
this.processingQueue.error((error) => {
|
|
74
|
-
if (!this.isStopped) {
|
|
75
|
-
this.logger.error('BinlogEvent processing error:', error);
|
|
76
|
-
this.stop();
|
|
77
|
-
reject(error);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
this.logger.warn('BinlogEvent processing error during shutdown:', error);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
this.zongji.on('stopped', () => {
|
|
84
|
-
resolve();
|
|
85
|
-
this.logger.info('BinLog listener stopped. Replication ended.');
|
|
86
106
|
});
|
|
87
107
|
});
|
|
88
108
|
}
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
this.zongji.
|
|
109
|
+
async restartZongji() {
|
|
110
|
+
if (this.zongji.stopped) {
|
|
111
|
+
this.zongji = this.createZongjiListener();
|
|
112
|
+
await this.start(true);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async stopZongji() {
|
|
116
|
+
if (!this.zongji.stopped) {
|
|
117
|
+
this.logger.info('Stopping BinLog Listener...');
|
|
118
|
+
await new Promise((resolve) => {
|
|
119
|
+
this.zongji.once('stopped', () => {
|
|
120
|
+
resolve();
|
|
121
|
+
});
|
|
122
|
+
this.zongji.stop();
|
|
123
|
+
});
|
|
124
|
+
this.logger.info('BinLog Listener stopped.');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async stop() {
|
|
128
|
+
if (!(this.isStopped || this.isStopping)) {
|
|
129
|
+
this.isStopping = true;
|
|
130
|
+
await this.stopZongji();
|
|
92
131
|
this.processingQueue.kill();
|
|
132
|
+
this.isStopped = true;
|
|
93
133
|
}
|
|
94
134
|
}
|
|
95
|
-
|
|
96
|
-
|
|
135
|
+
async replicateUntilStopped() {
|
|
136
|
+
while (!this.isStopped) {
|
|
137
|
+
await timers.setTimeout(1_000);
|
|
138
|
+
}
|
|
139
|
+
if (this.listenerError) {
|
|
140
|
+
this.logger.error('BinLog Listener stopped due to an error:', this.listenerError);
|
|
141
|
+
throw this.listenerError;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
createProcessingQueue() {
|
|
145
|
+
const queue = async.queue(this.createQueueWorker(), 1);
|
|
146
|
+
queue.error((error) => {
|
|
147
|
+
if (!(this.isStopped || this.isStopping)) {
|
|
148
|
+
this.listenerError = error;
|
|
149
|
+
this.stop();
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
this.logger.warn('Error processing BinLog event during shutdown:', error);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return queue;
|
|
97
156
|
}
|
|
98
157
|
createZongjiListener() {
|
|
99
158
|
const zongji = this.connectionManager.createBinlogListener();
|
|
100
159
|
zongji.on('binlog', async (evt) => {
|
|
101
|
-
this.logger.
|
|
160
|
+
this.logger.debug(`Received BinLog event:${evt.getEventName()}`);
|
|
102
161
|
this.processingQueue.push(evt);
|
|
103
162
|
this.queueMemoryUsage += evt.size;
|
|
104
163
|
// When the processing queue grows past the threshold, we pause the binlog listener
|
|
105
164
|
if (this.isQueueOverCapacity()) {
|
|
106
|
-
this.logger.info(`
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
await Promise.race([this.processingQueue.empty(), resumeTimeoutPromise]);
|
|
112
|
-
this.logger.info(`Binlog processing queue backlog cleared. Resuming Binlog listener.`);
|
|
113
|
-
zongji.resume();
|
|
165
|
+
this.logger.info(`BinLog processing queue has reached its memory limit of [${this.connectionManager.options.binlog_queue_memory_limit}MB]. Pausing BinLog Listener.`);
|
|
166
|
+
await this.stopZongji();
|
|
167
|
+
await this.processingQueue.drain();
|
|
168
|
+
this.logger.info(`BinLog processing queue backlog cleared. Resuming BinLog Listener.`);
|
|
169
|
+
await this.restartZongji();
|
|
114
170
|
}
|
|
115
171
|
});
|
|
116
|
-
zongji.on('
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (error) {
|
|
125
|
-
reject(error);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
this.logger.info('Successfully set up replication connection heartbeat...');
|
|
129
|
-
resolve(results);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
// The _socket member is only set after a query is run on the connection, so we set the timeout after setting the heartbeat.
|
|
134
|
-
// The timeout here must be greater than the master_heartbeat_period.
|
|
135
|
-
const socket = this.zongji.connection._socket;
|
|
136
|
-
socket.setTimeout(60_000, () => {
|
|
137
|
-
this.logger.info('Destroying socket due to replication connection timeout.');
|
|
138
|
-
socket.destroy(new Error('Replication connection timeout.'));
|
|
139
|
-
});
|
|
140
|
-
this.logger.info(`BinLog listener setup complete. Reading binlog from: ${this.binLogPosition.filename}:${this.binLogPosition.offset}`);
|
|
172
|
+
zongji.on('error', (error) => {
|
|
173
|
+
if (!(this.isStopped || this.isStopping)) {
|
|
174
|
+
this.listenerError = error;
|
|
175
|
+
this.stop();
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
this.logger.warn('Ignored BinLog Listener error during shutdown:', error);
|
|
179
|
+
}
|
|
141
180
|
});
|
|
142
181
|
return zongji;
|
|
143
182
|
}
|
|
183
|
+
isQueueOverCapacity() {
|
|
184
|
+
return this.queueMemoryUsage >= this.queueMemoryLimit;
|
|
185
|
+
}
|
|
144
186
|
createQueueWorker() {
|
|
145
187
|
return async (evt) => {
|
|
146
188
|
switch (true) {
|
|
@@ -155,38 +197,213 @@ export class BinLogListener {
|
|
|
155
197
|
offset: evt.nextPosition
|
|
156
198
|
}
|
|
157
199
|
});
|
|
200
|
+
this.binLogPosition.offset = evt.nextPosition;
|
|
158
201
|
await this.eventHandler.onTransactionStart({ timestamp: new Date(evt.timestamp) });
|
|
202
|
+
this.logger.info(`Processed GTID event: ${this.currentGTID.comparable}`);
|
|
159
203
|
break;
|
|
160
204
|
case zongji_utils.eventIsRotation(evt):
|
|
205
|
+
const newFile = this.binLogPosition.filename !== evt.binlogName;
|
|
161
206
|
this.binLogPosition.filename = evt.binlogName;
|
|
162
|
-
this.binLogPosition.offset = evt.position;
|
|
163
207
|
await this.eventHandler.onRotate();
|
|
208
|
+
if (newFile) {
|
|
209
|
+
this.logger.info(`Processed Rotate event. New BinLog file is: ${this.binLogPosition.filename}:${this.binLogPosition.offset}`);
|
|
210
|
+
}
|
|
164
211
|
break;
|
|
165
212
|
case zongji_utils.eventIsWriteMutation(evt):
|
|
166
|
-
|
|
213
|
+
const tableMap = evt.tableMap[evt.tableId];
|
|
214
|
+
await this.eventHandler.onWrite(evt.rows, tableMap);
|
|
215
|
+
this.logger.info(`Processed Write event for table [${tableMap.parentSchema}.${tableMap.tableName}]. ${evt.rows.length} row(s) inserted.`);
|
|
167
216
|
break;
|
|
168
217
|
case zongji_utils.eventIsUpdateMutation(evt):
|
|
169
218
|
await this.eventHandler.onUpdate(evt.rows.map((row) => row.after), evt.rows.map((row) => row.before), evt.tableMap[evt.tableId]);
|
|
219
|
+
this.logger.info(`Processed Update event for table [${evt.tableMap[evt.tableId].tableName}]. ${evt.rows.length} row(s) updated.`);
|
|
170
220
|
break;
|
|
171
221
|
case zongji_utils.eventIsDeleteMutation(evt):
|
|
172
222
|
await this.eventHandler.onDelete(evt.rows, evt.tableMap[evt.tableId]);
|
|
223
|
+
this.logger.info(`Processed Delete event for table [${evt.tableMap[evt.tableId].tableName}]. ${evt.rows.length} row(s) deleted.`);
|
|
173
224
|
break;
|
|
174
225
|
case zongji_utils.eventIsXid(evt):
|
|
226
|
+
this.binLogPosition.offset = evt.nextPosition;
|
|
175
227
|
const LSN = new common.ReplicatedGTID({
|
|
176
228
|
raw_gtid: this.currentGTID.raw,
|
|
177
|
-
position:
|
|
178
|
-
filename: this.binLogPosition.filename,
|
|
179
|
-
offset: evt.nextPosition
|
|
180
|
-
}
|
|
229
|
+
position: this.binLogPosition
|
|
181
230
|
}).comparable;
|
|
182
231
|
await this.eventHandler.onCommit(LSN);
|
|
232
|
+
this.logger.info(`Processed Xid event - transaction complete. LSN: ${LSN}.`);
|
|
233
|
+
break;
|
|
234
|
+
case zongji_utils.eventIsQuery(evt):
|
|
235
|
+
await this.processQueryEvent(evt);
|
|
183
236
|
break;
|
|
184
237
|
}
|
|
238
|
+
// Update the binlog position after processing the event
|
|
239
|
+
this.binLogPosition.offset = evt.nextPosition;
|
|
185
240
|
this.queueMemoryUsage -= evt.size;
|
|
186
241
|
};
|
|
187
242
|
}
|
|
188
|
-
|
|
189
|
-
|
|
243
|
+
async processQueryEvent(event) {
|
|
244
|
+
const { query, nextPosition } = event;
|
|
245
|
+
// BEGIN query events mark the start of a transaction before any row events. They are not relevant for schema changes
|
|
246
|
+
if (query === 'BEGIN') {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const schemaChanges = this.toSchemaChanges(query, event.schema);
|
|
250
|
+
if (schemaChanges.length > 0) {
|
|
251
|
+
// Since handling the schema changes can take a long time, we need to stop the Zongji listener instead of pausing it.
|
|
252
|
+
await this.stopZongji();
|
|
253
|
+
for (const change of schemaChanges) {
|
|
254
|
+
this.logger.info(`Processing schema change ${change.type} for table [${change.schema}.${change.table}]`);
|
|
255
|
+
await this.eventHandler.onSchemaChange(change);
|
|
256
|
+
}
|
|
257
|
+
// DDL queries are auto commited, but do not come with a corresponding Xid event.
|
|
258
|
+
// This is problematic for DDL queries which result in row events because the checkpoint is not moved on,
|
|
259
|
+
// so we manually commit here.
|
|
260
|
+
this.binLogPosition.offset = nextPosition;
|
|
261
|
+
const LSN = new common.ReplicatedGTID({
|
|
262
|
+
raw_gtid: this.currentGTID.raw,
|
|
263
|
+
position: this.binLogPosition
|
|
264
|
+
}).comparable;
|
|
265
|
+
await this.eventHandler.onCommit(LSN);
|
|
266
|
+
this.logger.info(`Successfully processed ${schemaChanges.length} schema change(s).`);
|
|
267
|
+
// If there are still events in the processing queue, we need to process those before restarting Zongji
|
|
268
|
+
if (!this.processingQueue.idle()) {
|
|
269
|
+
this.logger.info(`Processing [${this.processingQueue.length()}] events(s) before resuming...`);
|
|
270
|
+
this.processingQueue.drain(async () => {
|
|
271
|
+
await this.restartZongji();
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
await this.restartZongji();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Function that interprets a DDL query for any applicable schema changes.
|
|
281
|
+
* If the query does not contain any relevant schema changes, an empty array is returned.
|
|
282
|
+
* The defaultSchema is derived from the database set on the MySQL Node.js connection client.
|
|
283
|
+
* It is used as a fallback when the schema/database cannot be determined from the query DDL.
|
|
284
|
+
*
|
|
285
|
+
* @param query
|
|
286
|
+
* @param defaultSchema
|
|
287
|
+
*/
|
|
288
|
+
toSchemaChanges(query, defaultSchema) {
|
|
289
|
+
let statements = [];
|
|
290
|
+
try {
|
|
291
|
+
const ast = this.sqlParser.astify(query, { database: 'MySQL' });
|
|
292
|
+
statements = Array.isArray(ast) ? ast : [ast];
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
if (matchedSchemaChangeQuery(query, Object.values(this.databaseFilter))) {
|
|
296
|
+
this.logger.warn(`Failed to parse query: [${query}].
|
|
297
|
+
Please review for the schema changes and manually redeploy the sync rules if required.`);
|
|
298
|
+
}
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
const changes = [];
|
|
302
|
+
for (const statement of statements) {
|
|
303
|
+
if (isTruncate(statement)) {
|
|
304
|
+
const truncateStatement = statement;
|
|
305
|
+
// Truncate statements can apply to multiple tables
|
|
306
|
+
for (const entity of truncateStatement.name) {
|
|
307
|
+
changes.push({
|
|
308
|
+
type: SchemaChangeType.TRUNCATE_TABLE,
|
|
309
|
+
table: entity.table,
|
|
310
|
+
schema: entity.db ?? defaultSchema
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
else if (isDropTable(statement)) {
|
|
315
|
+
for (const entity of statement.name) {
|
|
316
|
+
changes.push({ type: SchemaChangeType.DROP_TABLE, table: entity.table, schema: entity.db ?? defaultSchema });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else if (isDropIndex(statement)) {
|
|
320
|
+
const dropStatement = statement;
|
|
321
|
+
changes.push({
|
|
322
|
+
type: SchemaChangeType.REPLICATION_IDENTITY,
|
|
323
|
+
table: dropStatement.table.table,
|
|
324
|
+
schema: dropStatement.table.db ?? defaultSchema
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else if (isCreateUniqueIndex(statement)) {
|
|
328
|
+
// Potential change to the replication identity if the table has no prior unique constraint
|
|
329
|
+
changes.push({
|
|
330
|
+
type: SchemaChangeType.REPLICATION_IDENTITY,
|
|
331
|
+
// @ts-ignore - The type definitions for node-sql-parser do not reflect the correct structure here
|
|
332
|
+
table: statement.table.table,
|
|
333
|
+
// @ts-ignore
|
|
334
|
+
schema: statement.table.db ?? defaultSchema
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
else if (isRenameTable(statement)) {
|
|
338
|
+
const renameStatement = statement;
|
|
339
|
+
// Rename statements can apply to multiple tables
|
|
340
|
+
for (const table of renameStatement.table) {
|
|
341
|
+
const schema = table[0].db ?? defaultSchema;
|
|
342
|
+
const isNewTableIncluded = this.databaseFilter[schema](table[1].table);
|
|
343
|
+
changes.push({
|
|
344
|
+
type: SchemaChangeType.RENAME_TABLE,
|
|
345
|
+
table: table[0].table,
|
|
346
|
+
newTable: isNewTableIncluded ? table[1].table : undefined,
|
|
347
|
+
schema
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else if (isAlterTable(statement)) {
|
|
352
|
+
const fromTable = statement.table[0];
|
|
353
|
+
for (const expression of statement.expr) {
|
|
354
|
+
if (isRenameExpression(expression)) {
|
|
355
|
+
changes.push({
|
|
356
|
+
type: SchemaChangeType.RENAME_TABLE,
|
|
357
|
+
table: fromTable.table,
|
|
358
|
+
newTable: expression.table,
|
|
359
|
+
schema: fromTable.db ?? defaultSchema
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
else if (isColumnExpression(expression)) {
|
|
363
|
+
changes.push({
|
|
364
|
+
type: SchemaChangeType.ALTER_TABLE_COLUMN,
|
|
365
|
+
table: fromTable.table,
|
|
366
|
+
schema: fromTable.db ?? defaultSchema
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
else if (isConstraintExpression(expression)) {
|
|
370
|
+
// Potential changes to the replication identity
|
|
371
|
+
changes.push({
|
|
372
|
+
type: SchemaChangeType.REPLICATION_IDENTITY,
|
|
373
|
+
table: fromTable.table,
|
|
374
|
+
schema: fromTable.db ?? defaultSchema
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// Filter out schema changes that are not relevant to the included tables
|
|
381
|
+
return changes.filter((change) => this.isTableIncluded(change.table, change.schema) ||
|
|
382
|
+
(change.newTable && this.isTableIncluded(change.newTable, change.schema)));
|
|
383
|
+
}
|
|
384
|
+
isTableIncluded(tableName, schema) {
|
|
385
|
+
return this.databaseFilter[schema] && this.databaseFilter[schema](tableName);
|
|
386
|
+
}
|
|
387
|
+
createDatabaseFilter(sourceTables) {
|
|
388
|
+
// Group sync rule tables by schema
|
|
389
|
+
const schemaMap = new Map();
|
|
390
|
+
for (const table of sourceTables) {
|
|
391
|
+
if (!schemaMap.has(table.schema)) {
|
|
392
|
+
const tables = [table];
|
|
393
|
+
schemaMap.set(table.schema, tables);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
schemaMap.get(table.schema).push(table);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const databaseFilter = {};
|
|
400
|
+
for (const entry of schemaMap.entries()) {
|
|
401
|
+
const [schema, sourceTables] = entry;
|
|
402
|
+
databaseFilter[schema] = (table) => sourceTables.findIndex((sourceTable) => sourceTable.isWildcard
|
|
403
|
+
? table.startsWith(sourceTable.tablePattern.substring(0, sourceTable.tablePattern.length - 1))
|
|
404
|
+
: table === sourceTable.name) !== -1;
|
|
405
|
+
}
|
|
406
|
+
return databaseFilter;
|
|
190
407
|
}
|
|
191
408
|
}
|
|
192
409
|
//# sourceMappingURL=BinLogListener.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BinLogListener.js","sourceRoot":"","sources":["../../../src/replication/zongji/BinLogListener.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BinLogListener.js","sourceRoot":"","sources":["../../../src/replication/zongji/BinLogListener.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BinLogEvent, BinLogGTIDLogEvent, BinLogRowEvent, BinLogRotationEvent, BinLogTableMapEvent, BinLogRowUpdateEvent, BinLogXidEvent } from '@powersync/mysql-zongji';
|
|
1
|
+
import { BinLogEvent, BinLogGTIDLogEvent, BinLogRowEvent, BinLogRotationEvent, BinLogTableMapEvent, BinLogRowUpdateEvent, BinLogXidEvent, BinLogQueryEvent } from '@powersync/mysql-zongji';
|
|
2
2
|
export declare function eventIsGTIDLog(event: BinLogEvent): event is BinLogGTIDLogEvent;
|
|
3
3
|
export declare function eventIsTableMap(event: BinLogEvent): event is BinLogTableMapEvent;
|
|
4
4
|
export declare function eventIsXid(event: BinLogEvent): event is BinLogXidEvent;
|
|
@@ -6,3 +6,4 @@ export declare function eventIsRotation(event: BinLogEvent): event is BinLogRota
|
|
|
6
6
|
export declare function eventIsWriteMutation(event: BinLogEvent): event is BinLogRowEvent;
|
|
7
7
|
export declare function eventIsDeleteMutation(event: BinLogEvent): event is BinLogRowEvent;
|
|
8
8
|
export declare function eventIsUpdateMutation(event: BinLogEvent): event is BinLogRowUpdateEvent;
|
|
9
|
+
export declare function eventIsQuery(event: BinLogEvent): event is BinLogQueryEvent;
|
|
@@ -19,4 +19,7 @@ export function eventIsDeleteMutation(event) {
|
|
|
19
19
|
export function eventIsUpdateMutation(event) {
|
|
20
20
|
return event.getEventName() == 'updaterows';
|
|
21
21
|
}
|
|
22
|
+
export function eventIsQuery(event) {
|
|
23
|
+
return event.getEventName() == 'query';
|
|
24
|
+
}
|
|
22
25
|
//# sourceMappingURL=zongji-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zongji-utils.js","sourceRoot":"","sources":["../../../src/replication/zongji/zongji-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"zongji-utils.js","sourceRoot":"","sources":["../../../src/replication/zongji/zongji-utils.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,SAAS,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,KAAK,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,QAAQ,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAkB;IACrD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,WAAW,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAkB;IAC7C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,OAAO,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import 'node-sql-parser';
|
|
2
|
+
/**
|
|
3
|
+
* Missing Type definitions for the node-sql-parser
|
|
4
|
+
*/
|
|
5
|
+
declare module 'node-sql-parser' {
|
|
6
|
+
interface RenameStatement {
|
|
7
|
+
type: 'rename';
|
|
8
|
+
table: {
|
|
9
|
+
db: string | null;
|
|
10
|
+
table: string;
|
|
11
|
+
}[][];
|
|
12
|
+
}
|
|
13
|
+
interface TruncateStatement {
|
|
14
|
+
type: 'truncate';
|
|
15
|
+
keyword: 'table';
|
|
16
|
+
name: {
|
|
17
|
+
db: string | null;
|
|
18
|
+
table: string;
|
|
19
|
+
as: string | null;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
interface DropIndexStatement {
|
|
23
|
+
type: 'drop';
|
|
24
|
+
keyword: 'index';
|
|
25
|
+
table: {
|
|
26
|
+
db: string | null;
|
|
27
|
+
table: string;
|
|
28
|
+
};
|
|
29
|
+
name: any[];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-sql-parser-extended-types.js","sourceRoot":"","sources":["../../src/types/node-sql-parser-extended-types.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import mysql from 'mysql2';
|
|
2
2
|
import mysqlPromise from 'mysql2/promise';
|
|
3
3
|
import * as types from '../types/types.js';
|
|
4
|
-
import {
|
|
4
|
+
import { SourceEntityDescriptor } from '@powersync/service-core';
|
|
5
5
|
export type RetriedQueryOptions = {
|
|
6
6
|
connection: mysqlPromise.Connection;
|
|
7
7
|
query: string;
|
|
@@ -29,4 +29,6 @@ export declare function getMySQLVersion(connection: mysqlPromise.Connection): Pr
|
|
|
29
29
|
* @param minimumVersion
|
|
30
30
|
*/
|
|
31
31
|
export declare function isVersionAtLeast(version: string, minimumVersion: string): boolean;
|
|
32
|
-
export declare function
|
|
32
|
+
export declare function satisfiesVersion(version: string, targetVersion: string): boolean;
|
|
33
|
+
export declare function qualifiedMySQLTable(table: SourceEntityDescriptor): string;
|
|
34
|
+
export declare function qualifiedMySQLTable(table: string, schema: string): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { logger } from '@powersync/lib-services-framework';
|
|
2
2
|
import mysql from 'mysql2';
|
|
3
|
-
import { coerce, gte } from 'semver';
|
|
3
|
+
import { coerce, gte, satisfies } from 'semver';
|
|
4
4
|
/**
|
|
5
5
|
* Retry a simple query - up to 2 attempts total.
|
|
6
6
|
*/
|
|
@@ -69,7 +69,19 @@ export function isVersionAtLeast(version, minimumVersion) {
|
|
|
69
69
|
const coercedMinimumVersion = coerce(minimumVersion);
|
|
70
70
|
return gte(coercedVersion, coercedMinimumVersion, { loose: true });
|
|
71
71
|
}
|
|
72
|
-
export function
|
|
73
|
-
|
|
72
|
+
export function satisfiesVersion(version, targetVersion) {
|
|
73
|
+
const coercedVersion = coerce(version);
|
|
74
|
+
return satisfies(coercedVersion, targetVersion, { loose: true });
|
|
75
|
+
}
|
|
76
|
+
export function qualifiedMySQLTable(table, schema) {
|
|
77
|
+
if (typeof table === 'object') {
|
|
78
|
+
return `\`${table.schema.replaceAll('`', '``')}\`.\`${table.name.replaceAll('`', '``')}\``;
|
|
79
|
+
}
|
|
80
|
+
else if (schema) {
|
|
81
|
+
return `\`${schema.replaceAll('`', '``')}\`.\`${table.replaceAll('`', '``')}\``;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return `\`${table.replaceAll('`', '``')}\``;
|
|
85
|
+
}
|
|
74
86
|
}
|
|
75
87
|
//# sourceMappingURL=mysql-utils.js.map
|