@remix-run/data-table-mysql 0.1.0 → 0.2.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.
@@ -1,10 +1,17 @@
1
1
  import { getTablePrimaryKey } from '@remix-run/data-table';
2
- import { compileMysqlStatement } from "./sql-compiler.js";
2
+ import { isDataManipulationOperation as isDataManipulationOperationHelper, quoteLiteral as quoteLiteralHelper, quoteTableRef as quoteTableRefHelper, } from '@remix-run/data-table/sql-helpers';
3
+ import { compileMysqlOperation } from "./sql-compiler.js";
3
4
  /**
4
5
  * `DatabaseAdapter` implementation for mysql-compatible clients.
5
6
  */
6
7
  export class MysqlDatabaseAdapter {
8
+ /**
9
+ * The SQL dialect identifier reported by this adapter.
10
+ */
7
11
  dialect = 'mysql';
12
+ /**
13
+ * Feature flags describing the mysql behaviors supported by this adapter.
14
+ */
8
15
  capabilities;
9
16
  #client;
10
17
  #transactions = new Map();
@@ -15,22 +22,42 @@ export class MysqlDatabaseAdapter {
15
22
  returning: options?.capabilities?.returning ?? false,
16
23
  savepoints: options?.capabilities?.savepoints ?? true,
17
24
  upsert: options?.capabilities?.upsert ?? true,
25
+ transactionalDdl: options?.capabilities?.transactionalDdl ?? false,
26
+ migrationLock: options?.capabilities?.migrationLock ?? true,
18
27
  };
19
28
  }
29
+ /**
30
+ * Compiles a data or migration operation to mysql SQL statements.
31
+ * @param operation Operation to compile.
32
+ * @returns Compiled SQL statements.
33
+ */
34
+ compileSql(operation) {
35
+ if (isDataManipulationOperation(operation)) {
36
+ let compiled = compileMysqlOperation(operation);
37
+ return [{ text: compiled.text, values: compiled.values }];
38
+ }
39
+ return compileMysqlMigrationOperations(operation);
40
+ }
41
+ /**
42
+ * Executes a mysql data-manipulation request.
43
+ * @param request Request to execute.
44
+ * @returns Execution result.
45
+ */
20
46
  async execute(request) {
21
- if (request.statement.kind === 'insertMany' && request.statement.values.length === 0) {
47
+ if (request.operation.kind === 'insertMany' && request.operation.values.length === 0) {
22
48
  return {
23
49
  affectedRows: 0,
24
50
  insertId: undefined,
25
- rows: request.statement.returning ? [] : undefined,
51
+ rows: request.operation.returning ? [] : undefined,
26
52
  };
27
53
  }
28
- let statement = compileMysqlStatement(request.statement);
54
+ let statements = this.compileSql(request.operation);
55
+ let statement = statements[0];
29
56
  let client = this.#resolveClient(request.transaction);
30
57
  let [result] = await client.query(statement.text, statement.values);
31
58
  if (isRowsResult(result)) {
32
59
  let rows = normalizeRows(result);
33
- if (request.statement.kind === 'count' || request.statement.kind === 'exists') {
60
+ if (request.operation.kind === 'count' || request.operation.kind === 'exists') {
34
61
  rows = normalizeCountRows(rows);
35
62
  }
36
63
  return { rows };
@@ -38,9 +65,68 @@ export class MysqlDatabaseAdapter {
38
65
  let header = normalizeHeader(result);
39
66
  return {
40
67
  affectedRows: header.affectedRows,
41
- insertId: normalizeInsertId(request.statement.kind, request.statement, header),
68
+ insertId: normalizeInsertId(request.operation.kind, request.operation, header),
69
+ };
70
+ }
71
+ /**
72
+ * Executes mysql migration operations.
73
+ * @param request Migration request to execute.
74
+ * @returns Migration result.
75
+ */
76
+ async migrate(request) {
77
+ let statements = this.compileSql(request.operation);
78
+ let client = this.#resolveClient(request.transaction);
79
+ for (let statement of statements) {
80
+ await client.query(statement.text, statement.values);
81
+ }
82
+ return {
83
+ affectedOperations: statements.length,
42
84
  };
43
85
  }
86
+ /**
87
+ * Checks whether a table exists in mysql.
88
+ * @param table Table reference to inspect.
89
+ * @param transaction Optional transaction token.
90
+ * @returns `true` when the table exists.
91
+ */
92
+ async hasTable(table, transaction) {
93
+ let schema = table.schema;
94
+ let sql = schema
95
+ ? 'select exists(select 1 from information_schema.tables where table_schema = ? and table_name = ?) as `exists`'
96
+ : 'select exists(select 1 from information_schema.tables where table_schema = database() and table_name = ?) as `exists`';
97
+ let values = schema ? [schema, table.name] : [table.name];
98
+ let client = this.#resolveClient(transaction);
99
+ let [result] = await client.query(sql, values);
100
+ if (!isRowsResult(result)) {
101
+ return false;
102
+ }
103
+ return toBooleanExists(result[0]?.exists);
104
+ }
105
+ /**
106
+ * Checks whether a column exists in mysql.
107
+ * @param table Table reference to inspect.
108
+ * @param column Column name to look up.
109
+ * @param transaction Optional transaction token.
110
+ * @returns `true` when the column exists.
111
+ */
112
+ async hasColumn(table, column, transaction) {
113
+ let schema = table.schema;
114
+ let sql = schema
115
+ ? 'select exists(select 1 from information_schema.columns where table_schema = ? and table_name = ? and column_name = ?) as `exists`'
116
+ : 'select exists(select 1 from information_schema.columns where table_schema = database() and table_name = ? and column_name = ?) as `exists`';
117
+ let values = schema ? [schema, table.name, column] : [table.name, column];
118
+ let client = this.#resolveClient(transaction);
119
+ let [result] = await client.query(sql, values);
120
+ if (!isRowsResult(result)) {
121
+ return false;
122
+ }
123
+ return toBooleanExists(result[0]?.exists);
124
+ }
125
+ /**
126
+ * Starts a mysql transaction.
127
+ * @param options Transaction options.
128
+ * @returns Transaction token.
129
+ */
44
130
  async beginTransaction(options) {
45
131
  let releaseOnClose = false;
46
132
  let connection;
@@ -66,6 +152,11 @@ export class MysqlDatabaseAdapter {
66
152
  });
67
153
  return token;
68
154
  }
155
+ /**
156
+ * Commits an open mysql transaction.
157
+ * @param token Transaction token to commit.
158
+ * @returns A promise that resolves when the transaction is committed.
159
+ */
69
160
  async commitTransaction(token) {
70
161
  let transaction = this.#transactions.get(token.id);
71
162
  if (!transaction) {
@@ -76,11 +167,16 @@ export class MysqlDatabaseAdapter {
76
167
  }
77
168
  finally {
78
169
  this.#transactions.delete(token.id);
79
- if (transaction.releaseOnClose) {
80
- transaction.connection.release?.();
170
+ if (transaction.releaseOnClose && isMysqlPoolConnection(transaction.connection)) {
171
+ transaction.connection.release();
81
172
  }
82
173
  }
83
174
  }
175
+ /**
176
+ * Rolls back an open mysql transaction.
177
+ * @param token Transaction token to roll back.
178
+ * @returns A promise that resolves when the transaction is rolled back.
179
+ */
84
180
  async rollbackTransaction(token) {
85
181
  let transaction = this.#transactions.get(token.id);
86
182
  if (!transaction) {
@@ -91,23 +187,55 @@ export class MysqlDatabaseAdapter {
91
187
  }
92
188
  finally {
93
189
  this.#transactions.delete(token.id);
94
- if (transaction.releaseOnClose) {
95
- transaction.connection.release?.();
190
+ if (transaction.releaseOnClose && isMysqlPoolConnection(transaction.connection)) {
191
+ transaction.connection.release();
96
192
  }
97
193
  }
98
194
  }
195
+ /**
196
+ * Creates a savepoint in an open mysql transaction.
197
+ * @param token Transaction token to use.
198
+ * @param name Savepoint name.
199
+ * @returns A promise that resolves when the savepoint is created.
200
+ */
99
201
  async createSavepoint(token, name) {
100
202
  let connection = this.#transactionConnection(token);
101
203
  await connection.query('savepoint ' + quoteIdentifier(name));
102
204
  }
205
+ /**
206
+ * Rolls back to a savepoint in an open mysql transaction.
207
+ * @param token Transaction token to use.
208
+ * @param name Savepoint name.
209
+ * @returns A promise that resolves when the rollback completes.
210
+ */
103
211
  async rollbackToSavepoint(token, name) {
104
212
  let connection = this.#transactionConnection(token);
105
213
  await connection.query('rollback to savepoint ' + quoteIdentifier(name));
106
214
  }
215
+ /**
216
+ * Releases a savepoint in an open mysql transaction.
217
+ * @param token Transaction token to use.
218
+ * @param name Savepoint name.
219
+ * @returns A promise that resolves when the savepoint is released.
220
+ */
107
221
  async releaseSavepoint(token, name) {
108
222
  let connection = this.#transactionConnection(token);
109
223
  await connection.query('release savepoint ' + quoteIdentifier(name));
110
224
  }
225
+ /**
226
+ * Acquires the mysql migration lock.
227
+ * @returns A promise that resolves when the lock is acquired.
228
+ */
229
+ async acquireMigrationLock() {
230
+ await this.#client.query('select get_lock(?, 60)', ['data_table_migrations']);
231
+ }
232
+ /**
233
+ * Releases the mysql migration lock.
234
+ * @returns A promise that resolves when the lock is released.
235
+ */
236
+ async releaseMigrationLock() {
237
+ await this.#client.query('select release_lock(?)', ['data_table_migrations']);
238
+ }
111
239
  #resolveClient(token) {
112
240
  if (!token) {
113
241
  return this.#client;
@@ -127,16 +255,44 @@ export class MysqlDatabaseAdapter {
127
255
  * @param client Mysql pool or connection.
128
256
  * @param options Optional adapter capability overrides.
129
257
  * @returns A configured mysql adapter.
258
+ * @example
259
+ * ```ts
260
+ * import { createPool } from 'mysql2/promise'
261
+ * import { createDatabase } from 'remix/data-table'
262
+ * import { createMysqlDatabaseAdapter } from 'remix/data-table-mysql'
263
+ *
264
+ * let pool = createPool({ uri: process.env.DATABASE_URL })
265
+ * let adapter = createMysqlDatabaseAdapter(pool)
266
+ * let db = createDatabase(adapter)
267
+ * ```
130
268
  */
131
269
  export function createMysqlDatabaseAdapter(client, options) {
132
270
  return new MysqlDatabaseAdapter(client, options);
133
271
  }
134
272
  function isMysqlPool(client) {
135
- return typeof client.getConnection === 'function';
273
+ return 'getConnection' in client && typeof client.getConnection === 'function';
274
+ }
275
+ function isMysqlPoolConnection(connection) {
276
+ return 'release' in connection && typeof connection.release === 'function';
136
277
  }
137
278
  function isRowsResult(result) {
138
279
  return Array.isArray(result) && (result.length === 0 || !Array.isArray(result[0]));
139
280
  }
281
+ function toBooleanExists(value) {
282
+ if (typeof value === 'boolean') {
283
+ return value;
284
+ }
285
+ if (typeof value === 'number') {
286
+ return value > 0;
287
+ }
288
+ if (typeof value === 'bigint') {
289
+ return value > 0n;
290
+ }
291
+ if (typeof value === 'string') {
292
+ return value === '1' || value.toLowerCase() === 'true';
293
+ }
294
+ return false;
295
+ }
140
296
  function normalizeRows(rows) {
141
297
  return rows.map((row) => ({ ...row }));
142
298
  }
@@ -174,11 +330,11 @@ function normalizeCountRows(rows) {
174
330
  return row;
175
331
  });
176
332
  }
177
- function normalizeInsertId(kind, statement, header) {
178
- if (!isInsertStatementKind(kind) || !isInsertStatement(statement)) {
333
+ function normalizeInsertId(kind, operation, header) {
334
+ if (!isInsertOperationKind(kind) || !isInsertOperation(operation)) {
179
335
  return undefined;
180
336
  }
181
- if (getTablePrimaryKey(statement.table).length !== 1) {
337
+ if (getTablePrimaryKey(operation.table).length !== 1) {
182
338
  return undefined;
183
339
  }
184
340
  return header.insertId;
@@ -186,9 +342,383 @@ function normalizeInsertId(kind, statement, header) {
186
342
  function quoteIdentifier(value) {
187
343
  return '`' + value.replace(/`/g, '``') + '`';
188
344
  }
189
- function isInsertStatementKind(kind) {
345
+ function quoteTableRef(table) {
346
+ return quoteTableRefHelper(table, quoteIdentifier);
347
+ }
348
+ function quoteLiteral(value) {
349
+ return quoteLiteralHelper(value);
350
+ }
351
+ function isInsertOperationKind(kind) {
190
352
  return kind === 'insert' || kind === 'insertMany' || kind === 'upsert';
191
353
  }
192
- function isInsertStatement(statement) {
193
- return (statement.kind === 'insert' || statement.kind === 'insertMany' || statement.kind === 'upsert');
354
+ function isInsertOperation(operation) {
355
+ return (operation.kind === 'insert' || operation.kind === 'insertMany' || operation.kind === 'upsert');
356
+ }
357
+ function isDataManipulationOperation(operation) {
358
+ return isDataManipulationOperationHelper(operation);
359
+ }
360
+ function compileMysqlMigrationOperations(operation) {
361
+ if (operation.kind === 'raw') {
362
+ return [{ text: operation.sql.text, values: [...operation.sql.values] }];
363
+ }
364
+ if (operation.kind === 'createTable') {
365
+ let columns = Object.keys(operation.columns).map((columnName) => quoteIdentifier(columnName) + ' ' + compileMysqlColumn(operation.columns[columnName]));
366
+ let constraints = [];
367
+ if (operation.primaryKey) {
368
+ constraints.push('constraint ' +
369
+ quoteIdentifier(operation.primaryKey.name) +
370
+ ' primary key (' +
371
+ operation.primaryKey.columns.map((column) => quoteIdentifier(column)).join(', ') +
372
+ ')');
373
+ }
374
+ for (let unique of operation.uniques ?? []) {
375
+ constraints.push('constraint ' +
376
+ quoteIdentifier(unique.name) +
377
+ ' ' +
378
+ 'unique (' +
379
+ unique.columns.map((column) => quoteIdentifier(column)).join(', ') +
380
+ ')');
381
+ }
382
+ for (let check of operation.checks ?? []) {
383
+ constraints.push('constraint ' + quoteIdentifier(check.name) + ' ' + 'check (' + check.expression + ')');
384
+ }
385
+ for (let foreignKey of operation.foreignKeys ?? []) {
386
+ let clause = 'constraint ' +
387
+ quoteIdentifier(foreignKey.name) +
388
+ ' ' +
389
+ 'foreign key (' +
390
+ foreignKey.columns.map((column) => quoteIdentifier(column)).join(', ') +
391
+ ') references ' +
392
+ quoteTableRef(foreignKey.references.table) +
393
+ ' (' +
394
+ foreignKey.references.columns.map((column) => quoteIdentifier(column)).join(', ') +
395
+ ')';
396
+ if (foreignKey.onDelete) {
397
+ clause += ' on delete ' + foreignKey.onDelete;
398
+ }
399
+ if (foreignKey.onUpdate) {
400
+ clause += ' on update ' + foreignKey.onUpdate;
401
+ }
402
+ constraints.push(clause);
403
+ }
404
+ let sql = 'create table ' +
405
+ (operation.ifNotExists ? 'if not exists ' : '') +
406
+ quoteTableRef(operation.table) +
407
+ ' (' +
408
+ [...columns, ...constraints].join(', ') +
409
+ ')';
410
+ let statements = [{ text: sql, values: [] }];
411
+ if (operation.comment) {
412
+ statements.push({
413
+ text: 'alter table ' +
414
+ quoteTableRef(operation.table) +
415
+ ' comment = ' +
416
+ quoteLiteral(operation.comment),
417
+ values: [],
418
+ });
419
+ }
420
+ return statements;
421
+ }
422
+ if (operation.kind === 'alterTable') {
423
+ let statements = [];
424
+ for (let change of operation.changes) {
425
+ let sql = 'alter table ' + quoteTableRef(operation.table) + ' ';
426
+ if (change.kind === 'addColumn') {
427
+ sql +=
428
+ 'add column ' +
429
+ quoteIdentifier(change.column) +
430
+ ' ' +
431
+ compileMysqlColumn(change.definition);
432
+ }
433
+ else if (change.kind === 'changeColumn') {
434
+ sql +=
435
+ 'modify column ' +
436
+ quoteIdentifier(change.column) +
437
+ ' ' +
438
+ compileMysqlColumn(change.definition);
439
+ }
440
+ else if (change.kind === 'renameColumn') {
441
+ sql += 'rename column ' + quoteIdentifier(change.from) + ' to ' + quoteIdentifier(change.to);
442
+ }
443
+ else if (change.kind === 'dropColumn') {
444
+ sql += 'drop column ' + quoteIdentifier(change.column);
445
+ }
446
+ else if (change.kind === 'addPrimaryKey') {
447
+ sql +=
448
+ 'add primary key (' +
449
+ change.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
450
+ ')';
451
+ }
452
+ else if (change.kind === 'dropPrimaryKey') {
453
+ sql += 'drop primary key';
454
+ }
455
+ else if (change.kind === 'addUnique') {
456
+ sql +=
457
+ 'add ' +
458
+ 'constraint ' +
459
+ quoteIdentifier(change.constraint.name) +
460
+ ' ' +
461
+ 'unique (' +
462
+ change.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
463
+ ')';
464
+ }
465
+ else if (change.kind === 'dropUnique') {
466
+ sql += 'drop index ' + quoteIdentifier(change.name);
467
+ }
468
+ else if (change.kind === 'addForeignKey') {
469
+ sql +=
470
+ 'add ' +
471
+ 'constraint ' +
472
+ quoteIdentifier(change.constraint.name) +
473
+ ' ' +
474
+ 'foreign key (' +
475
+ change.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
476
+ ') references ' +
477
+ quoteTableRef(change.constraint.references.table) +
478
+ ' (' +
479
+ change.constraint.references.columns.map((column) => quoteIdentifier(column)).join(', ') +
480
+ ')';
481
+ }
482
+ else if (change.kind === 'dropForeignKey') {
483
+ sql += 'drop foreign key ' + quoteIdentifier(change.name);
484
+ }
485
+ else if (change.kind === 'addCheck') {
486
+ sql +=
487
+ 'add ' +
488
+ 'constraint ' +
489
+ quoteIdentifier(change.constraint.name) +
490
+ ' ' +
491
+ 'check (' +
492
+ change.constraint.expression +
493
+ ')';
494
+ }
495
+ else if (change.kind === 'dropCheck') {
496
+ sql += 'drop check ' + quoteIdentifier(change.name);
497
+ }
498
+ else if (change.kind === 'setTableComment') {
499
+ sql += 'comment = ' + quoteLiteral(change.comment);
500
+ }
501
+ else {
502
+ continue;
503
+ }
504
+ statements.push({ text: sql, values: [] });
505
+ }
506
+ return statements;
507
+ }
508
+ if (operation.kind === 'renameTable') {
509
+ return [
510
+ {
511
+ text: 'rename table ' + quoteTableRef(operation.from) + ' to ' + quoteTableRef(operation.to),
512
+ values: [],
513
+ },
514
+ ];
515
+ }
516
+ if (operation.kind === 'dropTable') {
517
+ return [
518
+ {
519
+ text: 'drop table ' + (operation.ifExists ? 'if exists ' : '') + quoteTableRef(operation.table),
520
+ values: [],
521
+ },
522
+ ];
523
+ }
524
+ if (operation.kind === 'createIndex') {
525
+ return [
526
+ {
527
+ text: 'create ' +
528
+ (operation.index.unique ? 'unique ' : '') +
529
+ 'index ' +
530
+ quoteIdentifier(operation.index.name) +
531
+ ' on ' +
532
+ quoteTableRef(operation.index.table) +
533
+ (operation.index.using ? ' using ' + operation.index.using : '') +
534
+ ' (' +
535
+ operation.index.columns.map((column) => quoteIdentifier(column)).join(', ') +
536
+ ')' +
537
+ (operation.index.where ? ' where ' + operation.index.where : ''),
538
+ values: [],
539
+ },
540
+ ];
541
+ }
542
+ if (operation.kind === 'dropIndex') {
543
+ return [
544
+ {
545
+ text: 'drop index ' + quoteIdentifier(operation.name) + ' on ' + quoteTableRef(operation.table),
546
+ values: [],
547
+ },
548
+ ];
549
+ }
550
+ if (operation.kind === 'renameIndex') {
551
+ return [
552
+ {
553
+ text: 'alter table ' +
554
+ quoteTableRef(operation.table) +
555
+ ' rename index ' +
556
+ quoteIdentifier(operation.from) +
557
+ ' to ' +
558
+ quoteIdentifier(operation.to),
559
+ values: [],
560
+ },
561
+ ];
562
+ }
563
+ if (operation.kind === 'addForeignKey') {
564
+ return [
565
+ {
566
+ text: 'alter table ' +
567
+ quoteTableRef(operation.table) +
568
+ ' add ' +
569
+ 'constraint ' +
570
+ quoteIdentifier(operation.constraint.name) +
571
+ ' ' +
572
+ 'foreign key (' +
573
+ operation.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
574
+ ') references ' +
575
+ quoteTableRef(operation.constraint.references.table) +
576
+ ' (' +
577
+ operation.constraint.references.columns
578
+ .map((column) => quoteIdentifier(column))
579
+ .join(', ') +
580
+ ')' +
581
+ (operation.constraint.onDelete ? ' on delete ' + operation.constraint.onDelete : '') +
582
+ (operation.constraint.onUpdate ? ' on update ' + operation.constraint.onUpdate : ''),
583
+ values: [],
584
+ },
585
+ ];
586
+ }
587
+ if (operation.kind === 'dropForeignKey') {
588
+ return [
589
+ {
590
+ text: 'alter table ' +
591
+ quoteTableRef(operation.table) +
592
+ ' drop foreign key ' +
593
+ quoteIdentifier(operation.name),
594
+ values: [],
595
+ },
596
+ ];
597
+ }
598
+ if (operation.kind === 'addCheck') {
599
+ return [
600
+ {
601
+ text: 'alter table ' +
602
+ quoteTableRef(operation.table) +
603
+ ' add ' +
604
+ 'constraint ' +
605
+ quoteIdentifier(operation.constraint.name) +
606
+ ' ' +
607
+ 'check (' +
608
+ operation.constraint.expression +
609
+ ')',
610
+ values: [],
611
+ },
612
+ ];
613
+ }
614
+ if (operation.kind === 'dropCheck') {
615
+ return [
616
+ {
617
+ text: 'alter table ' +
618
+ quoteTableRef(operation.table) +
619
+ ' drop check ' +
620
+ quoteIdentifier(operation.name),
621
+ values: [],
622
+ },
623
+ ];
624
+ }
625
+ throw new Error('Unsupported data migration operation kind');
626
+ }
627
+ function compileMysqlColumn(definition) {
628
+ let parts = [compileMysqlColumnType(definition)];
629
+ if (definition.nullable === false) {
630
+ parts.push('not null');
631
+ }
632
+ if (definition.default) {
633
+ if (definition.default.kind === 'now') {
634
+ parts.push('default current_timestamp');
635
+ }
636
+ else if (definition.default.kind === 'sql') {
637
+ parts.push('default ' + definition.default.expression);
638
+ }
639
+ else {
640
+ parts.push('default ' + quoteLiteral(definition.default.value));
641
+ }
642
+ }
643
+ if (definition.autoIncrement) {
644
+ parts.push('auto_increment');
645
+ }
646
+ if (definition.primaryKey) {
647
+ parts.push('primary key');
648
+ }
649
+ if (definition.unique) {
650
+ parts.push('unique');
651
+ }
652
+ if (definition.computed) {
653
+ parts.push('generated always as (' + definition.computed.expression + ')');
654
+ parts.push(definition.computed.stored ? 'stored' : 'virtual');
655
+ }
656
+ if (definition.references) {
657
+ let clause = 'references ' +
658
+ quoteTableRef(definition.references.table) +
659
+ ' (' +
660
+ definition.references.columns.map((column) => quoteIdentifier(column)).join(', ') +
661
+ ')';
662
+ if (definition.references.onDelete) {
663
+ clause += ' on delete ' + definition.references.onDelete;
664
+ }
665
+ if (definition.references.onUpdate) {
666
+ clause += ' on update ' + definition.references.onUpdate;
667
+ }
668
+ parts.push(clause);
669
+ }
670
+ if (definition.checks && definition.checks.length > 0) {
671
+ for (let check of definition.checks) {
672
+ parts.push('check (' + check.expression + ')');
673
+ }
674
+ }
675
+ return parts.join(' ');
676
+ }
677
+ function compileMysqlColumnType(definition) {
678
+ if (definition.type === 'varchar') {
679
+ return 'varchar(' + String(definition.length ?? 255) + ')';
680
+ }
681
+ if (definition.type === 'text') {
682
+ return 'text';
683
+ }
684
+ if (definition.type === 'integer') {
685
+ return definition.unsigned ? 'int unsigned' : 'int';
686
+ }
687
+ if (definition.type === 'bigint') {
688
+ return definition.unsigned ? 'bigint unsigned' : 'bigint';
689
+ }
690
+ if (definition.type === 'decimal') {
691
+ if (definition.precision !== undefined && definition.scale !== undefined) {
692
+ return 'decimal(' + String(definition.precision) + ', ' + String(definition.scale) + ')';
693
+ }
694
+ return 'decimal';
695
+ }
696
+ if (definition.type === 'boolean') {
697
+ return 'boolean';
698
+ }
699
+ if (definition.type === 'uuid') {
700
+ return 'char(36)';
701
+ }
702
+ if (definition.type === 'date') {
703
+ return 'date';
704
+ }
705
+ if (definition.type === 'time') {
706
+ return 'time';
707
+ }
708
+ if (definition.type === 'timestamp') {
709
+ return 'timestamp';
710
+ }
711
+ if (definition.type === 'json') {
712
+ return 'json';
713
+ }
714
+ if (definition.type === 'binary') {
715
+ return 'blob';
716
+ }
717
+ if (definition.type === 'enum') {
718
+ if (definition.enumValues && definition.enumValues.length > 0) {
719
+ return 'enum(' + definition.enumValues.map((value) => quoteLiteral(value)).join(', ') + ')';
720
+ }
721
+ return 'text';
722
+ }
723
+ return 'text';
194
724
  }
@@ -1,8 +1,3 @@
1
- import type { AdapterStatement } from '@remix-run/data-table';
2
- type CompiledSql = {
3
- text: string;
4
- values: unknown[];
5
- };
6
- export declare function compileMysqlStatement(statement: AdapterStatement): CompiledSql;
7
- export {};
1
+ import type { DataManipulationOperation, SqlStatement } from '@remix-run/data-table';
2
+ export declare function compileMysqlOperation(operation: DataManipulationOperation): SqlStatement;
8
3
  //# sourceMappingURL=sql-compiler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-compiler.d.ts","sourceRoot":"","sources":["../../src/lib/sql-compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,uBAAuB,CAAA;AAMxE,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,EAAE,CAAA;CAClB,CAAA;AAMD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,gBAAgB,GAAG,WAAW,CAgG9E"}
1
+ {"version":3,"file":"sql-compiler.d.ts","sourceRoot":"","sources":["../../src/lib/sql-compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAa,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAe/F,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,yBAAyB,GAAG,YAAY,CAgGxF"}