@anthonyalayo/drizzle-kit 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/.gitignore +25 -0
  2. package/README.md +79 -0
  3. package/build.dev.ts +51 -0
  4. package/build.ts +112 -0
  5. package/imports-checker/analyze.ts +78 -0
  6. package/imports-checker/checker.ts +296 -0
  7. package/imports-checker/grammar/grammar.ohm +121 -0
  8. package/imports-checker/grammar/grammar.ohm-bundle.d.ts +164 -0
  9. package/imports-checker/grammar/grammar.ohm-bundle.js +753 -0
  10. package/imports-checker/index.ts +48 -0
  11. package/package.json +142 -0
  12. package/patches/difflib@0.2.4.patch +31 -0
  13. package/src/@types/utils.ts +58 -0
  14. package/src/api.ts +504 -0
  15. package/src/cli/commands/_es5.ts +2 -0
  16. package/src/cli/commands/check.ts +52 -0
  17. package/src/cli/commands/drop.ts +60 -0
  18. package/src/cli/commands/introspect.ts +772 -0
  19. package/src/cli/commands/libSqlPushUtils.ts +355 -0
  20. package/src/cli/commands/migrate.ts +1526 -0
  21. package/src/cli/commands/mysqlIntrospect.ts +53 -0
  22. package/src/cli/commands/mysqlPushUtils.ts +352 -0
  23. package/src/cli/commands/mysqlUp.ts +102 -0
  24. package/src/cli/commands/pgIntrospect.ts +55 -0
  25. package/src/cli/commands/pgPushUtils.ts +269 -0
  26. package/src/cli/commands/pgUp.ts +217 -0
  27. package/src/cli/commands/push.ts +637 -0
  28. package/src/cli/commands/singlestoreIntrospect.ts +53 -0
  29. package/src/cli/commands/singlestorePushUtils.ts +456 -0
  30. package/src/cli/commands/singlestoreUp.ts +1 -0
  31. package/src/cli/commands/sqliteIntrospect.ts +96 -0
  32. package/src/cli/commands/sqlitePushUtils.ts +322 -0
  33. package/src/cli/commands/sqliteUp.ts +52 -0
  34. package/src/cli/commands/utils.ts +858 -0
  35. package/src/cli/connections.ts +914 -0
  36. package/src/cli/index.ts +48 -0
  37. package/src/cli/schema.ts +794 -0
  38. package/src/cli/selector-ui.ts +38 -0
  39. package/src/cli/utils.ts +112 -0
  40. package/src/cli/validations/cli.ts +79 -0
  41. package/src/cli/validations/common.ts +193 -0
  42. package/src/cli/validations/libsql.ts +27 -0
  43. package/src/cli/validations/mysql.ts +61 -0
  44. package/src/cli/validations/outputs.ts +91 -0
  45. package/src/cli/validations/postgres.ts +83 -0
  46. package/src/cli/validations/singlestore.ts +61 -0
  47. package/src/cli/validations/sqlite.ts +104 -0
  48. package/src/cli/validations/studio.ts +24 -0
  49. package/src/cli/views.ts +658 -0
  50. package/src/extensions/getTablesFilterByExtensions.ts +16 -0
  51. package/src/extensions/vector.ts +10 -0
  52. package/src/global.ts +61 -0
  53. package/src/index.ts +326 -0
  54. package/src/introspect-mysql.ts +1030 -0
  55. package/src/introspect-pg.ts +1435 -0
  56. package/src/introspect-singlestore.ts +913 -0
  57. package/src/introspect-sqlite.ts +533 -0
  58. package/src/jsonDiffer.js +882 -0
  59. package/src/jsonStatements.ts +3590 -0
  60. package/src/loader.mjs +57 -0
  61. package/src/migrationPreparator.ts +217 -0
  62. package/src/schemaValidator.ts +23 -0
  63. package/src/serializer/index.ts +142 -0
  64. package/src/serializer/mysqlImports.ts +38 -0
  65. package/src/serializer/mysqlSchema.ts +423 -0
  66. package/src/serializer/mysqlSerializer.ts +999 -0
  67. package/src/serializer/pgImports.ts +106 -0
  68. package/src/serializer/pgSchema.ts +937 -0
  69. package/src/serializer/pgSerializer.ts +2223 -0
  70. package/src/serializer/singlestoreImports.ts +38 -0
  71. package/src/serializer/singlestoreSchema.ts +257 -0
  72. package/src/serializer/singlestoreSerializer.ts +767 -0
  73. package/src/serializer/sqliteImports.ts +41 -0
  74. package/src/serializer/sqliteSchema.ts +352 -0
  75. package/src/serializer/sqliteSerializer.ts +931 -0
  76. package/src/serializer/studio.ts +694 -0
  77. package/src/serializer/utils.ts +45 -0
  78. package/src/simulator.ts +157 -0
  79. package/src/snapshotsDiffer.ts +4398 -0
  80. package/src/sqlgenerator.ts +4212 -0
  81. package/src/statementCombiner.ts +597 -0
  82. package/src/utils/certs.ts +44 -0
  83. package/src/utils/words.ts +1333 -0
  84. package/src/utils.ts +370 -0
  85. package/tests/bin.test.ts +58 -0
  86. package/tests/cli/d1http.config.ts +12 -0
  87. package/tests/cli/drizzle.config.ts +9 -0
  88. package/tests/cli/durable-sqlite.config.ts +7 -0
  89. package/tests/cli/expo.config.ts +7 -0
  90. package/tests/cli/postgres.config.ts +13 -0
  91. package/tests/cli/postgres2.config.ts +17 -0
  92. package/tests/cli/schema.ts +1 -0
  93. package/tests/cli/turso.config.ts +10 -0
  94. package/tests/cli-export.test.ts +79 -0
  95. package/tests/cli-generate.test.ts +259 -0
  96. package/tests/cli-migrate.test.ts +103 -0
  97. package/tests/cli-push.test.ts +126 -0
  98. package/tests/common.ts +15 -0
  99. package/tests/indexes/common.ts +21 -0
  100. package/tests/indexes/pg.test.ts +245 -0
  101. package/tests/introspect/libsql.test.ts +35 -0
  102. package/tests/introspect/mysql.test.ts +319 -0
  103. package/tests/introspect/pg.test.ts +894 -0
  104. package/tests/introspect/singlestore.test.ts +275 -0
  105. package/tests/introspect/sqlite.test.ts +122 -0
  106. package/tests/libsql-checks.test.ts +308 -0
  107. package/tests/libsql-statements.test.ts +989 -0
  108. package/tests/libsql-views.test.ts +218 -0
  109. package/tests/migrate/libsq-schema.ts +6 -0
  110. package/tests/migrate/libsql-migrate.test.ts +58 -0
  111. package/tests/migrate/migrations/0000_little_blizzard.sql +4 -0
  112. package/tests/migrate/migrations/0001_nebulous_storm.sql +10 -0
  113. package/tests/migrate/migrations/meta/0000_snapshot.json +40 -0
  114. package/tests/migrate/migrations/meta/0001_snapshot.json +40 -0
  115. package/tests/migrate/migrations/meta/_journal.json +20 -0
  116. package/tests/mysql-checks.test.ts +291 -0
  117. package/tests/mysql-generated.test.ts +1290 -0
  118. package/tests/mysql-schemas.test.ts +156 -0
  119. package/tests/mysql-views.test.ts +553 -0
  120. package/tests/mysql.test.ts +863 -0
  121. package/tests/pg-array.test.ts +368 -0
  122. package/tests/pg-checks.test.ts +329 -0
  123. package/tests/pg-columns.test.ts +484 -0
  124. package/tests/pg-domains.test.ts +306 -0
  125. package/tests/pg-enums.test.ts +751 -0
  126. package/tests/pg-generated.test.ts +529 -0
  127. package/tests/pg-identity.test.ts +447 -0
  128. package/tests/pg-schemas.test.ts +105 -0
  129. package/tests/pg-sequences.test.ts +298 -0
  130. package/tests/pg-tables.test.ts +1021 -0
  131. package/tests/pg-views.test.ts +1929 -0
  132. package/tests/push/common.ts +58 -0
  133. package/tests/push/libsql.test.ts +1400 -0
  134. package/tests/push/mysql-push.test.ts +345 -0
  135. package/tests/push/mysql.test.ts +788 -0
  136. package/tests/push/pg.test.ts +4341 -0
  137. package/tests/push/singlestore-push.test.ts +894 -0
  138. package/tests/push/singlestore.test.ts +444 -0
  139. package/tests/push/sqlite.test.ts +1613 -0
  140. package/tests/rls/pg-policy.test.ts +1656 -0
  141. package/tests/rls/pg-role.test.ts +234 -0
  142. package/tests/schemaDiffer.ts +2852 -0
  143. package/tests/singlestore-generated.test.ts +1290 -0
  144. package/tests/singlestore-schemas.test.ts +155 -0
  145. package/tests/singlestore.test.ts +978 -0
  146. package/tests/sqlite-checks.test.ts +308 -0
  147. package/tests/sqlite-columns.test.ts +1049 -0
  148. package/tests/sqlite-generated.test.ts +1726 -0
  149. package/tests/sqlite-tables.test.ts +637 -0
  150. package/tests/sqlite-views.test.ts +218 -0
  151. package/tests/statements-combiner/libsql-statements-combiner.test.ts +1812 -0
  152. package/tests/statements-combiner/singlestore-statements-combiner.test.ts +882 -0
  153. package/tests/statements-combiner/sqlite-statements-combiner.test.ts +1211 -0
  154. package/tests/test/sqlite.test.ts +39 -0
  155. package/tests/testsinglestore.ts +29 -0
  156. package/tests/validations.test.ts +869 -0
  157. package/tests/wrap-param.test.ts +16 -0
  158. package/tsconfig.build.json +4 -0
  159. package/tsconfig.cli-types.json +9 -0
  160. package/tsconfig.json +28 -0
  161. package/vitest.config.ts +34 -0
@@ -0,0 +1,4212 @@
1
+ import { BREAKPOINT } from './cli/commands/migrate';
2
+ import {
3
+ JsonAddColumnStatement,
4
+ JsonAddValueToEnumStatement,
5
+ JsonAlterColumnAlterGeneratedStatement,
6
+ JsonAlterColumnAlterIdentityStatement,
7
+ JsonAlterColumnDropAutoincrementStatement,
8
+ JsonAlterColumnDropDefaultStatement,
9
+ JsonAlterColumnDropGeneratedStatement,
10
+ JsonAlterColumnDropIdentityStatement,
11
+ JsonAlterColumnDropNotNullStatement,
12
+ JsonAlterColumnDropOnUpdateStatement,
13
+ JsonAlterColumnDropPrimaryKeyStatement,
14
+ JsonAlterColumnSetAutoincrementStatement,
15
+ JsonAlterColumnSetDefaultStatement,
16
+ JsonAlterColumnSetGeneratedStatement,
17
+ JsonAlterColumnSetIdentityStatement,
18
+ JsonAlterColumnSetNotNullStatement,
19
+ JsonAlterColumnSetOnUpdateStatement,
20
+ JsonAlterColumnSetPrimaryKeyStatement,
21
+ JsonAlterColumnTypeStatement,
22
+ JsonAlterCompositePK,
23
+ JsonAlterDomainStatement,
24
+ JsonAlterIndPolicyStatement,
25
+ JsonAlterMySqlViewStatement,
26
+ JsonAlterPolicyStatement,
27
+ JsonAlterReferenceStatement,
28
+ JsonAlterRoleStatement,
29
+ JsonAlterSequenceStatement,
30
+ JsonAlterTableRemoveFromSchema,
31
+ JsonAlterTableSetNewSchema,
32
+ JsonAlterTableSetSchema,
33
+ JsonAlterViewAddWithOptionStatement,
34
+ JsonAlterViewAlterSchemaStatement,
35
+ JsonAlterViewAlterTablespaceStatement,
36
+ JsonAlterViewAlterUsingStatement,
37
+ JsonAlterViewDropWithOptionStatement,
38
+ JsonCreateCheckConstraint,
39
+ JsonCreateCompositePK,
40
+ JsonCreateDomainStatement,
41
+ JsonCreateEnumStatement,
42
+ JsonCreateIndexStatement,
43
+ JsonCreateIndPolicyStatement,
44
+ JsonCreateMySqlViewStatement,
45
+ JsonCreatePgViewStatement,
46
+ JsonCreatePolicyStatement,
47
+ JsonCreateReferenceStatement,
48
+ JsonCreateRoleStatement,
49
+ JsonCreateSchema,
50
+ JsonCreateSequenceStatement,
51
+ JsonCreateSqliteViewStatement,
52
+ JsonCreateTableStatement,
53
+ JsonCreateUniqueConstraint,
54
+ JsonDeleteCheckConstraint,
55
+ JsonDeleteCompositePK,
56
+ JsonDeleteReferenceStatement,
57
+ JsonDeleteUniqueConstraint,
58
+ JsonDisableRLSStatement,
59
+ JsonDropColumnStatement,
60
+ JsonDropDomainStatement,
61
+ JsonDropEnumStatement,
62
+ JsonDropIndexStatement,
63
+ JsonDropIndPolicyStatement,
64
+ JsonDropPolicyStatement,
65
+ JsonDropRoleStatement,
66
+ JsonDropSequenceStatement,
67
+ JsonDropTableStatement,
68
+ JsonDropValueFromEnumStatement,
69
+ JsonDropViewStatement,
70
+ JsonEnableRLSStatement,
71
+ JsonIndRenamePolicyStatement,
72
+ JsonMoveEnumStatement,
73
+ JsonMoveSequenceStatement,
74
+ JsonPgCreateIndexStatement,
75
+ JsonRecreateSingleStoreTableStatement,
76
+ JsonRecreateTableStatement,
77
+ JsonRenameColumnStatement,
78
+ JsonRenameEnumStatement,
79
+ JsonRenamePolicyStatement,
80
+ JsonRenameRoleStatement,
81
+ JsonRenameSchema,
82
+ JsonRenameSequenceStatement,
83
+ JsonRenameTableStatement,
84
+ JsonRenameViewStatement,
85
+ JsonSqliteAddColumnStatement,
86
+ JsonSqliteCreateTableStatement,
87
+ JsonStatement,
88
+ } from './jsonStatements';
89
+ import { Dialect } from './schemaValidator';
90
+ import { MySqlSquasher } from './serializer/mysqlSchema';
91
+ import { PgSquasher, policy } from './serializer/pgSchema';
92
+ import { SingleStoreSquasher } from './serializer/singlestoreSchema';
93
+ import { SQLiteSchemaSquashed, SQLiteSquasher } from './serializer/sqliteSchema';
94
+
95
+ import { escapeSingleQuotes } from './utils';
96
+
97
+ const parseType = (schemaPrefix: string, type: string) => {
98
+ const pgNativeTypes = [
99
+ 'uuid',
100
+ 'smallint',
101
+ 'integer',
102
+ 'bigint',
103
+ 'boolean',
104
+ 'text',
105
+ 'varchar',
106
+ 'serial',
107
+ 'bigserial',
108
+ 'decimal',
109
+ 'numeric',
110
+ 'real',
111
+ 'json',
112
+ 'jsonb',
113
+ 'time',
114
+ 'time with time zone',
115
+ 'time without time zone',
116
+ 'time',
117
+ 'timestamp',
118
+ 'timestamp with time zone',
119
+ 'timestamp without time zone',
120
+ 'date',
121
+ 'interval',
122
+ 'bigint',
123
+ 'bigserial',
124
+ 'double precision',
125
+ 'interval year',
126
+ 'interval month',
127
+ 'interval day',
128
+ 'interval hour',
129
+ 'interval minute',
130
+ 'interval second',
131
+ 'interval year to month',
132
+ 'interval day to hour',
133
+ 'interval day to minute',
134
+ 'interval day to second',
135
+ 'interval hour to minute',
136
+ 'interval hour to second',
137
+ 'interval minute to second',
138
+ 'char',
139
+ 'vector',
140
+ 'geometry',
141
+ ];
142
+ const arrayDefinitionRegex = /\[\d*(?:\[\d*\])*\]/g;
143
+ const arrayDefinition = (type.match(arrayDefinitionRegex) ?? []).join('');
144
+ const withoutArrayDefinition = type.replace(arrayDefinitionRegex, '');
145
+ return pgNativeTypes.some((it) => type.startsWith(it))
146
+ ? `${withoutArrayDefinition}${arrayDefinition}`
147
+ : `${schemaPrefix}"${withoutArrayDefinition}"${arrayDefinition}`;
148
+ };
149
+
150
+ abstract class Convertor {
151
+ abstract can(
152
+ statement: JsonStatement,
153
+ dialect: Dialect,
154
+ ): boolean;
155
+ abstract convert(
156
+ statement: JsonStatement,
157
+ json2?: SQLiteSchemaSquashed,
158
+ action?: 'push',
159
+ ): string | string[];
160
+ }
161
+
162
+ class PgCreateRoleConvertor extends Convertor {
163
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
164
+ return statement.type === 'create_role' && dialect === 'postgresql';
165
+ }
166
+ override convert(statement: JsonCreateRoleStatement): string | string[] {
167
+ return `CREATE ROLE "${statement.name}"${
168
+ statement.values.createDb || statement.values.createRole || !statement.values.inherit
169
+ ? ` WITH${statement.values.createDb ? ' CREATEDB' : ''}${statement.values.createRole ? ' CREATEROLE' : ''}${
170
+ statement.values.inherit ? '' : ' NOINHERIT'
171
+ }`
172
+ : ''
173
+ };`;
174
+ }
175
+ }
176
+
177
+ class PgDropRoleConvertor extends Convertor {
178
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
179
+ return statement.type === 'drop_role' && dialect === 'postgresql';
180
+ }
181
+ override convert(statement: JsonDropRoleStatement): string | string[] {
182
+ return `DROP ROLE "${statement.name}";`;
183
+ }
184
+ }
185
+
186
+ class PgRenameRoleConvertor extends Convertor {
187
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
188
+ return statement.type === 'rename_role' && dialect === 'postgresql';
189
+ }
190
+ override convert(statement: JsonRenameRoleStatement): string | string[] {
191
+ return `ALTER ROLE "${statement.nameFrom}" RENAME TO "${statement.nameTo}";`;
192
+ }
193
+ }
194
+
195
+ class PgAlterRoleConvertor extends Convertor {
196
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
197
+ return statement.type === 'alter_role' && dialect === 'postgresql';
198
+ }
199
+ override convert(statement: JsonAlterRoleStatement): string | string[] {
200
+ return `ALTER ROLE "${statement.name}"${` WITH${statement.values.createDb ? ' CREATEDB' : ' NOCREATEDB'}${
201
+ statement.values.createRole ? ' CREATEROLE' : ' NOCREATEROLE'
202
+ }${statement.values.inherit ? ' INHERIT' : ' NOINHERIT'}`};`;
203
+ }
204
+ }
205
+
206
+ /////
207
+
208
+ class PgCreatePolicyConvertor extends Convertor {
209
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
210
+ return statement.type === 'create_policy' && dialect === 'postgresql';
211
+ }
212
+ override convert(statement: JsonCreatePolicyStatement): string | string[] {
213
+ const policy = statement.data;
214
+
215
+ const tableNameWithSchema = statement.schema
216
+ ? `"${statement.schema}"."${statement.tableName}"`
217
+ : `"${statement.tableName}"`;
218
+
219
+ const usingPart = policy.using ? ` USING (${policy.using})` : '';
220
+
221
+ const withCheckPart = policy.withCheck ? ` WITH CHECK (${policy.withCheck})` : '';
222
+
223
+ const policyToPart = policy.to?.map((v) =>
224
+ ['current_user', 'current_role', 'session_user', 'public'].includes(v) ? v : `"${v}"`
225
+ ).join(', ');
226
+
227
+ return `CREATE POLICY "${policy.name}" ON ${tableNameWithSchema} AS ${policy.as?.toUpperCase()} FOR ${policy.for?.toUpperCase()} TO ${policyToPart}${usingPart}${withCheckPart};`;
228
+ }
229
+ }
230
+
231
+ class PgDropPolicyConvertor extends Convertor {
232
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
233
+ return statement.type === 'drop_policy' && dialect === 'postgresql';
234
+ }
235
+ override convert(statement: JsonDropPolicyStatement): string | string[] {
236
+ const policy = statement.data;
237
+
238
+ const tableNameWithSchema = statement.schema
239
+ ? `"${statement.schema}"."${statement.tableName}"`
240
+ : `"${statement.tableName}"`;
241
+
242
+ return `DROP POLICY "${policy.name}" ON ${tableNameWithSchema} CASCADE;`;
243
+ }
244
+ }
245
+
246
+ class PgRenamePolicyConvertor extends Convertor {
247
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
248
+ return statement.type === 'rename_policy' && dialect === 'postgresql';
249
+ }
250
+ override convert(statement: JsonRenamePolicyStatement): string | string[] {
251
+ const tableNameWithSchema = statement.schema
252
+ ? `"${statement.schema}"."${statement.tableName}"`
253
+ : `"${statement.tableName}"`;
254
+
255
+ return `ALTER POLICY "${statement.oldName}" ON ${tableNameWithSchema} RENAME TO "${statement.newName}";`;
256
+ }
257
+ }
258
+
259
+ class PgAlterPolicyConvertor extends Convertor {
260
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
261
+ return statement.type === 'alter_policy' && dialect === 'postgresql';
262
+ }
263
+ override convert(statement: JsonAlterPolicyStatement, _dialect: any, action?: string): string | string[] {
264
+ const newPolicy = action === 'push'
265
+ ? PgSquasher.unsquashPolicyPush(statement.newData)
266
+ : PgSquasher.unsquashPolicy(statement.newData);
267
+ const oldPolicy = action === 'push'
268
+ ? PgSquasher.unsquashPolicyPush(statement.oldData)
269
+ : PgSquasher.unsquashPolicy(statement.oldData);
270
+
271
+ const tableNameWithSchema = statement.schema
272
+ ? `"${statement.schema}"."${statement.tableName}"`
273
+ : `"${statement.tableName}"`;
274
+
275
+ const usingPart = newPolicy.using
276
+ ? ` USING (${newPolicy.using})`
277
+ : oldPolicy.using
278
+ ? ` USING (${oldPolicy.using})`
279
+ : '';
280
+
281
+ const withCheckPart = newPolicy.withCheck
282
+ ? ` WITH CHECK (${newPolicy.withCheck})`
283
+ : oldPolicy.withCheck
284
+ ? ` WITH CHECK (${oldPolicy.withCheck})`
285
+ : '';
286
+
287
+ return `ALTER POLICY "${oldPolicy.name}" ON ${tableNameWithSchema} TO ${newPolicy.to}${usingPart}${withCheckPart};`;
288
+ }
289
+ }
290
+
291
+ ////
292
+
293
+ class PgCreateIndPolicyConvertor extends Convertor {
294
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
295
+ return statement.type === 'create_ind_policy' && dialect === 'postgresql';
296
+ }
297
+ override convert(statement: JsonCreateIndPolicyStatement): string | string[] {
298
+ const policy = statement.data;
299
+
300
+ const usingPart = policy.using ? ` USING (${policy.using})` : '';
301
+
302
+ const withCheckPart = policy.withCheck ? ` WITH CHECK (${policy.withCheck})` : '';
303
+
304
+ const policyToPart = policy.to?.map((v) =>
305
+ ['current_user', 'current_role', 'session_user', 'public'].includes(v) ? v : `"${v}"`
306
+ ).join(', ');
307
+
308
+ return `CREATE POLICY "${policy.name}" ON ${policy.on} AS ${policy.as?.toUpperCase()} FOR ${policy.for?.toUpperCase()} TO ${policyToPart}${usingPart}${withCheckPart};`;
309
+ }
310
+ }
311
+
312
+ class PgDropIndPolicyConvertor extends Convertor {
313
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
314
+ return statement.type === 'drop_ind_policy' && dialect === 'postgresql';
315
+ }
316
+ override convert(statement: JsonDropIndPolicyStatement): string | string[] {
317
+ const policy = statement.data;
318
+
319
+ return `DROP POLICY "${policy.name}" ON ${policy.on} CASCADE;`;
320
+ }
321
+ }
322
+
323
+ class PgRenameIndPolicyConvertor extends Convertor {
324
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
325
+ return statement.type === 'rename_ind_policy' && dialect === 'postgresql';
326
+ }
327
+ override convert(statement: JsonIndRenamePolicyStatement): string | string[] {
328
+ return `ALTER POLICY "${statement.oldName}" ON ${statement.tableKey} RENAME TO "${statement.newName}";`;
329
+ }
330
+ }
331
+
332
+ class PgAlterIndPolicyConvertor extends Convertor {
333
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
334
+ return statement.type === 'alter_ind_policy' && dialect === 'postgresql';
335
+ }
336
+ override convert(statement: JsonAlterIndPolicyStatement): string | string[] {
337
+ const newPolicy = statement.newData;
338
+ const oldPolicy = statement.oldData;
339
+
340
+ const usingPart = newPolicy.using
341
+ ? ` USING (${newPolicy.using})`
342
+ : oldPolicy.using
343
+ ? ` USING (${oldPolicy.using})`
344
+ : '';
345
+
346
+ const withCheckPart = newPolicy.withCheck
347
+ ? ` WITH CHECK (${newPolicy.withCheck})`
348
+ : oldPolicy.withCheck
349
+ ? ` WITH CHECK (${oldPolicy.withCheck})`
350
+ : '';
351
+
352
+ return `ALTER POLICY "${oldPolicy.name}" ON ${oldPolicy.on} TO ${newPolicy.to}${usingPart}${withCheckPart};`;
353
+ }
354
+ }
355
+
356
+ ////
357
+
358
+ class PgEnableRlsConvertor extends Convertor {
359
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
360
+ return statement.type === 'enable_rls' && dialect === 'postgresql';
361
+ }
362
+ override convert(statement: JsonEnableRLSStatement): string {
363
+ const tableNameWithSchema = statement.schema
364
+ ? `"${statement.schema}"."${statement.tableName}"`
365
+ : `"${statement.tableName}"`;
366
+
367
+ return `ALTER TABLE ${tableNameWithSchema} ENABLE ROW LEVEL SECURITY;`;
368
+ }
369
+ }
370
+
371
+ class PgDisableRlsConvertor extends Convertor {
372
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
373
+ return statement.type === 'disable_rls' && dialect === 'postgresql';
374
+ }
375
+ override convert(statement: JsonDisableRLSStatement): string {
376
+ const tableNameWithSchema = statement.schema
377
+ ? `"${statement.schema}"."${statement.tableName}"`
378
+ : `"${statement.tableName}"`;
379
+
380
+ return `ALTER TABLE ${tableNameWithSchema} DISABLE ROW LEVEL SECURITY;`;
381
+ }
382
+ }
383
+
384
+ class PgCreateTableConvertor extends Convertor {
385
+ can(statement: JsonStatement, dialect: Dialect): boolean {
386
+ return statement.type === 'create_table' && dialect === 'postgresql';
387
+ }
388
+
389
+ convert(st: JsonCreateTableStatement) {
390
+ const { tableName, schema, columns, compositePKs, uniqueConstraints, checkConstraints, policies, isRLSEnabled } =
391
+ st;
392
+
393
+ let statement = '';
394
+ const name = schema ? `"${schema}"."${tableName}"` : `"${tableName}"`;
395
+
396
+ statement += `CREATE TABLE ${name} (\n`;
397
+ for (let i = 0; i < columns.length; i++) {
398
+ const column = columns[i];
399
+
400
+ const primaryKeyStatement = column.primaryKey ? ' PRIMARY KEY' : '';
401
+ const notNullStatement = column.notNull && !column.identity ? ' NOT NULL' : '';
402
+ const defaultStatement = column.default !== undefined ? ` DEFAULT ${column.default}` : '';
403
+
404
+ const uniqueConstraint = column.isUnique
405
+ ? ` CONSTRAINT "${column.uniqueName}" UNIQUE${column.nullsNotDistinct ? ' NULLS NOT DISTINCT' : ''}`
406
+ : '';
407
+
408
+ const schemaPrefix = column.typeSchema && column.typeSchema !== 'public'
409
+ ? `"${column.typeSchema}".`
410
+ : '';
411
+
412
+ const type = parseType(schemaPrefix, column.type);
413
+ const generated = column.generated;
414
+
415
+ const generatedStatement = generated ? ` GENERATED ALWAYS AS (${generated?.as}) STORED` : '';
416
+
417
+ const unsquashedIdentity = column.identity
418
+ ? PgSquasher.unsquashIdentity(column.identity)
419
+ : undefined;
420
+
421
+ const identityWithSchema = schema
422
+ ? `"${schema}"."${unsquashedIdentity?.name}"`
423
+ : `"${unsquashedIdentity?.name}"`;
424
+
425
+ const identity = unsquashedIdentity
426
+ ? ` GENERATED ${
427
+ unsquashedIdentity.type === 'always' ? 'ALWAYS' : 'BY DEFAULT'
428
+ } AS IDENTITY (sequence name ${identityWithSchema}${
429
+ unsquashedIdentity.increment
430
+ ? ` INCREMENT BY ${unsquashedIdentity.increment}`
431
+ : ''
432
+ }${
433
+ unsquashedIdentity.minValue
434
+ ? ` MINVALUE ${unsquashedIdentity.minValue}`
435
+ : ''
436
+ }${
437
+ unsquashedIdentity.maxValue
438
+ ? ` MAXVALUE ${unsquashedIdentity.maxValue}`
439
+ : ''
440
+ }${
441
+ unsquashedIdentity.startWith
442
+ ? ` START WITH ${unsquashedIdentity.startWith}`
443
+ : ''
444
+ }${unsquashedIdentity.cache ? ` CACHE ${unsquashedIdentity.cache}` : ''}${
445
+ unsquashedIdentity.cycle ? ` CYCLE` : ''
446
+ })`
447
+ : '';
448
+
449
+ statement += '\t'
450
+ + `"${column.name}" ${type}${primaryKeyStatement}${defaultStatement}${generatedStatement}${notNullStatement}${uniqueConstraint}${identity}`;
451
+ statement += i === columns.length - 1 ? '' : ',\n';
452
+ }
453
+
454
+ if (typeof compositePKs !== 'undefined' && compositePKs.length > 0) {
455
+ statement += ',\n';
456
+ const compositePK = PgSquasher.unsquashPK(compositePKs[0]);
457
+ statement += `\tCONSTRAINT "${st.compositePkName}" PRIMARY KEY(\"${compositePK.columns.join(`","`)}\")`;
458
+ // statement += `\n`;
459
+ }
460
+
461
+ if (
462
+ typeof uniqueConstraints !== 'undefined'
463
+ && uniqueConstraints.length > 0
464
+ ) {
465
+ for (const uniqueConstraint of uniqueConstraints) {
466
+ statement += ',\n';
467
+ const unsquashedUnique = PgSquasher.unsquashUnique(uniqueConstraint);
468
+ statement += `\tCONSTRAINT "${unsquashedUnique.name}" UNIQUE${
469
+ unsquashedUnique.nullsNotDistinct ? ' NULLS NOT DISTINCT' : ''
470
+ }(\"${unsquashedUnique.columns.join(`","`)}\")`;
471
+ // statement += `\n`;
472
+ }
473
+ }
474
+
475
+ if (typeof checkConstraints !== 'undefined' && checkConstraints.length > 0) {
476
+ for (const checkConstraint of checkConstraints) {
477
+ statement += ',\n';
478
+ const unsquashedCheck = PgSquasher.unsquashCheck(checkConstraint);
479
+
480
+ if (unsquashedCheck.name) {
481
+ statement += `\tCONSTRAINT "${unsquashedCheck.name}" CHECK (${unsquashedCheck.value})`;
482
+ } else {
483
+ statement += `\tCHECK (${unsquashedCheck.value})`;
484
+ }
485
+ }
486
+ }
487
+
488
+ statement += `\n);`;
489
+ statement += `\n`;
490
+
491
+ const enableRls = new PgEnableRlsConvertor().convert({
492
+ type: 'enable_rls',
493
+ tableName,
494
+ schema,
495
+ });
496
+
497
+ return [statement, ...(policies && policies.length > 0 || isRLSEnabled ? [enableRls] : [])];
498
+ }
499
+ }
500
+
501
+ class MySqlCreateTableConvertor extends Convertor {
502
+ can(statement: JsonStatement, dialect: Dialect): boolean {
503
+ return statement.type === 'create_table' && dialect === 'mysql';
504
+ }
505
+
506
+ convert(st: JsonCreateTableStatement) {
507
+ const {
508
+ tableName,
509
+ columns,
510
+ schema,
511
+ checkConstraints,
512
+ compositePKs,
513
+ uniqueConstraints,
514
+ internals,
515
+ } = st;
516
+
517
+ let statement = '';
518
+ statement += `CREATE TABLE \`${tableName}\` (\n`;
519
+ for (let i = 0; i < columns.length; i++) {
520
+ const column = columns[i];
521
+
522
+ const primaryKeyStatement = column.primaryKey ? ' PRIMARY KEY' : '';
523
+ const notNullStatement = column.notNull ? ' NOT NULL' : '';
524
+ const defaultStatement = column.default !== undefined ? ` DEFAULT ${column.default}` : '';
525
+
526
+ const onUpdateStatement = column.onUpdate
527
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
528
+ : '';
529
+
530
+ const autoincrementStatement = column.autoincrement
531
+ ? ' AUTO_INCREMENT'
532
+ : '';
533
+
534
+ const generatedStatement = column.generated
535
+ ? ` GENERATED ALWAYS AS (${column.generated?.as}) ${column.generated?.type.toUpperCase()}`
536
+ : '';
537
+
538
+ statement += '\t'
539
+ + `\`${column.name}\` ${column.type}${autoincrementStatement}${primaryKeyStatement}${generatedStatement}${notNullStatement}${defaultStatement}${onUpdateStatement}`;
540
+ statement += i === columns.length - 1 ? '' : ',\n';
541
+ }
542
+
543
+ if (typeof compositePKs !== 'undefined' && compositePKs.length > 0) {
544
+ statement += ',\n';
545
+ const compositePK = MySqlSquasher.unsquashPK(compositePKs[0]);
546
+ statement += `\tCONSTRAINT \`${st.compositePkName}\` PRIMARY KEY(\`${compositePK.columns.join(`\`,\``)}\`)`;
547
+ }
548
+
549
+ if (
550
+ typeof uniqueConstraints !== 'undefined'
551
+ && uniqueConstraints.length > 0
552
+ ) {
553
+ for (const uniqueConstraint of uniqueConstraints) {
554
+ statement += ',\n';
555
+ const unsquashedUnique = MySqlSquasher.unsquashUnique(uniqueConstraint);
556
+
557
+ const uniqueString = unsquashedUnique.columns
558
+ .map((it) => {
559
+ return internals?.indexes
560
+ ? internals?.indexes[unsquashedUnique.name]?.columns[it]
561
+ ?.isExpression
562
+ ? it
563
+ : `\`${it}\``
564
+ : `\`${it}\``;
565
+ })
566
+ .join(',');
567
+
568
+ statement += `\tCONSTRAINT \`${unsquashedUnique.name}\` UNIQUE(${uniqueString})`;
569
+ }
570
+ }
571
+
572
+ if (typeof checkConstraints !== 'undefined' && checkConstraints.length > 0) {
573
+ for (const checkConstraint of checkConstraints) {
574
+ statement += ',\n';
575
+ const unsquashedCheck = MySqlSquasher.unsquashCheck(checkConstraint);
576
+
577
+ statement += `\tCONSTRAINT \`${unsquashedCheck.name}\` CHECK(${unsquashedCheck.value})`;
578
+ }
579
+ }
580
+
581
+ statement += `\n);`;
582
+ statement += `\n`;
583
+ return statement;
584
+ }
585
+ }
586
+ export class SingleStoreCreateTableConvertor extends Convertor {
587
+ can(statement: JsonStatement, dialect: Dialect): boolean {
588
+ return statement.type === 'create_table' && dialect === 'singlestore';
589
+ }
590
+
591
+ convert(st: JsonCreateTableStatement) {
592
+ const {
593
+ tableName,
594
+ columns,
595
+ schema,
596
+ compositePKs,
597
+ uniqueConstraints,
598
+ internals,
599
+ } = st;
600
+
601
+ let statement = '';
602
+ statement += `CREATE TABLE \`${tableName}\` (\n`;
603
+ for (let i = 0; i < columns.length; i++) {
604
+ const column = columns[i];
605
+
606
+ const primaryKeyStatement = column.primaryKey ? ' PRIMARY KEY' : '';
607
+ const notNullStatement = column.notNull ? ' NOT NULL' : '';
608
+ const defaultStatement = column.default !== undefined ? ` DEFAULT ${column.default}` : '';
609
+
610
+ const onUpdateStatement = column.onUpdate
611
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
612
+ : '';
613
+
614
+ const autoincrementStatement = column.autoincrement
615
+ ? ' AUTO_INCREMENT'
616
+ : '';
617
+
618
+ const generatedStatement = column.generated
619
+ ? ` GENERATED ALWAYS AS (${column.generated?.as}) ${column.generated?.type.toUpperCase()}`
620
+ : '';
621
+
622
+ statement += '\t'
623
+ + `\`${column.name}\` ${column.type}${autoincrementStatement}${primaryKeyStatement}${notNullStatement}${defaultStatement}${onUpdateStatement}${generatedStatement}`;
624
+ statement += i === columns.length - 1 ? '' : ',\n';
625
+ }
626
+
627
+ if (typeof compositePKs !== 'undefined' && compositePKs.length > 0) {
628
+ statement += ',\n';
629
+ const compositePK = SingleStoreSquasher.unsquashPK(compositePKs[0]);
630
+ statement += `\tCONSTRAINT \`${compositePK.name}\` PRIMARY KEY(\`${compositePK.columns.join(`\`,\``)}\`)`;
631
+ }
632
+
633
+ if (
634
+ typeof uniqueConstraints !== 'undefined'
635
+ && uniqueConstraints.length > 0
636
+ ) {
637
+ for (const uniqueConstraint of uniqueConstraints) {
638
+ statement += ',\n';
639
+ const unsquashedUnique = SingleStoreSquasher.unsquashUnique(uniqueConstraint);
640
+
641
+ const uniqueString = unsquashedUnique.columns
642
+ .map((it) => {
643
+ return internals?.indexes
644
+ ? internals?.indexes[unsquashedUnique.name]?.columns[it]
645
+ ?.isExpression
646
+ ? it
647
+ : `\`${it}\``
648
+ : `\`${it}\``;
649
+ })
650
+ .join(',');
651
+
652
+ statement += `\tCONSTRAINT \`${unsquashedUnique.name}\` UNIQUE(${uniqueString})`;
653
+ }
654
+ }
655
+
656
+ statement += `\n);`;
657
+ statement += `\n`;
658
+ return statement;
659
+ }
660
+ }
661
+
662
+ export class SQLiteCreateTableConvertor extends Convertor {
663
+ can(statement: JsonStatement, dialect: Dialect): boolean {
664
+ return statement.type === 'sqlite_create_table' && (dialect === 'sqlite' || dialect === 'turso');
665
+ }
666
+
667
+ convert(st: JsonSqliteCreateTableStatement) {
668
+ const {
669
+ tableName,
670
+ columns,
671
+ referenceData,
672
+ compositePKs,
673
+ uniqueConstraints,
674
+ checkConstraints,
675
+ } = st;
676
+
677
+ let statement = '';
678
+ statement += `CREATE TABLE \`${tableName}\` (\n`;
679
+ for (let i = 0; i < columns.length; i++) {
680
+ const column = columns[i];
681
+
682
+ const primaryKeyStatement = column.primaryKey ? ' PRIMARY KEY' : '';
683
+ const notNullStatement = column.notNull ? ' NOT NULL' : '';
684
+ const defaultStatement = column.default !== undefined ? ` DEFAULT ${column.default}` : '';
685
+
686
+ const autoincrementStatement = column.autoincrement
687
+ ? ' AUTOINCREMENT'
688
+ : '';
689
+
690
+ const generatedStatement = column.generated
691
+ ? ` GENERATED ALWAYS AS ${column.generated.as} ${column.generated.type.toUpperCase()}`
692
+ : '';
693
+
694
+ statement += '\t';
695
+ statement +=
696
+ `\`${column.name}\` ${column.type}${primaryKeyStatement}${autoincrementStatement}${defaultStatement}${generatedStatement}${notNullStatement}`;
697
+
698
+ statement += i === columns.length - 1 ? '' : ',\n';
699
+ }
700
+
701
+ compositePKs.forEach((it) => {
702
+ statement += ',\n\t';
703
+ statement += `PRIMARY KEY(${it.map((it) => `\`${it}\``).join(', ')})`;
704
+ });
705
+
706
+ for (let i = 0; i < referenceData.length; i++) {
707
+ const {
708
+ name,
709
+ tableFrom,
710
+ tableTo,
711
+ columnsFrom,
712
+ columnsTo,
713
+ onDelete,
714
+ onUpdate,
715
+ } = referenceData[i];
716
+
717
+ const onDeleteStatement = onDelete ? ` ON DELETE ${onDelete}` : '';
718
+ const onUpdateStatement = onUpdate ? ` ON UPDATE ${onUpdate}` : '';
719
+ const fromColumnsString = columnsFrom.map((it) => `\`${it}\``).join(',');
720
+ const toColumnsString = columnsTo.map((it) => `\`${it}\``).join(',');
721
+
722
+ statement += ',';
723
+ statement += '\n\t';
724
+ statement +=
725
+ `FOREIGN KEY (${fromColumnsString}) REFERENCES \`${tableTo}\`(${toColumnsString})${onUpdateStatement}${onDeleteStatement}`;
726
+ }
727
+
728
+ if (
729
+ typeof uniqueConstraints !== 'undefined'
730
+ && uniqueConstraints.length > 0
731
+ ) {
732
+ for (const uniqueConstraint of uniqueConstraints) {
733
+ statement += ',\n';
734
+ const unsquashedUnique = SQLiteSquasher.unsquashUnique(uniqueConstraint);
735
+ statement += `\tCONSTRAINT ${unsquashedUnique.name} UNIQUE(\`${unsquashedUnique.columns.join(`\`,\``)}\`)`;
736
+ }
737
+ }
738
+
739
+ if (
740
+ typeof checkConstraints !== 'undefined'
741
+ && checkConstraints.length > 0
742
+ ) {
743
+ for (const check of checkConstraints) {
744
+ statement += ',\n';
745
+ const { value, name } = SQLiteSquasher.unsquashCheck(check);
746
+ statement += `\tCONSTRAINT "${name}" CHECK(${value})`;
747
+ }
748
+ }
749
+
750
+ statement += `\n`;
751
+ statement += `);`;
752
+ statement += `\n`;
753
+ return statement;
754
+ }
755
+ }
756
+
757
+ class PgCreateViewConvertor extends Convertor {
758
+ can(statement: JsonStatement, dialect: Dialect): boolean {
759
+ return statement.type === 'create_view' && dialect === 'postgresql';
760
+ }
761
+
762
+ convert(st: JsonCreatePgViewStatement) {
763
+ const { definition, name: viewName, schema, with: withOption, materialized, withNoData, tablespace, using } = st;
764
+
765
+ const name = schema ? `"${schema}"."${viewName}"` : `"${viewName}"`;
766
+
767
+ let statement = materialized ? `CREATE MATERIALIZED VIEW ${name}` : `CREATE VIEW ${name}`;
768
+
769
+ if (using) statement += ` USING "${using}"`;
770
+
771
+ const options: string[] = [];
772
+ if (withOption) {
773
+ statement += ` WITH (`;
774
+
775
+ Object.entries(withOption).forEach(([key, value]) => {
776
+ if (typeof value === 'undefined') return;
777
+
778
+ options.push(`${key.snake_case()} = ${value}`);
779
+ });
780
+
781
+ statement += options.join(', ');
782
+
783
+ statement += `)`;
784
+ }
785
+
786
+ if (tablespace) statement += ` TABLESPACE ${tablespace}`;
787
+
788
+ statement += ` AS (${definition})`;
789
+
790
+ if (withNoData) statement += ` WITH NO DATA`;
791
+
792
+ statement += `;`;
793
+
794
+ return statement;
795
+ }
796
+ }
797
+
798
+ class MySqlCreateViewConvertor extends Convertor {
799
+ can(statement: JsonStatement, dialect: Dialect): boolean {
800
+ return statement.type === 'mysql_create_view' && dialect === 'mysql';
801
+ }
802
+
803
+ convert(st: JsonCreateMySqlViewStatement) {
804
+ const { definition, name, algorithm, sqlSecurity, withCheckOption, replace } = st;
805
+
806
+ let statement = `CREATE `;
807
+ statement += replace ? `OR REPLACE ` : '';
808
+ statement += algorithm ? `ALGORITHM = ${algorithm}\n` : '';
809
+ statement += sqlSecurity ? `SQL SECURITY ${sqlSecurity}\n` : '';
810
+ statement += `VIEW \`${name}\` AS (${definition})`;
811
+ statement += withCheckOption ? `\nWITH ${withCheckOption} CHECK OPTION` : '';
812
+
813
+ statement += ';';
814
+
815
+ return statement;
816
+ }
817
+ }
818
+
819
+ class SqliteCreateViewConvertor extends Convertor {
820
+ can(statement: JsonStatement, dialect: Dialect): boolean {
821
+ return statement.type === 'sqlite_create_view' && (dialect === 'sqlite' || dialect === 'turso');
822
+ }
823
+
824
+ convert(st: JsonCreateSqliteViewStatement) {
825
+ const { definition, name } = st;
826
+
827
+ return `CREATE VIEW \`${name}\` AS ${definition};`;
828
+ }
829
+ }
830
+
831
+ class PgDropViewConvertor extends Convertor {
832
+ can(statement: JsonStatement, dialect: Dialect): boolean {
833
+ return statement.type === 'drop_view' && dialect === 'postgresql';
834
+ }
835
+
836
+ convert(st: JsonDropViewStatement) {
837
+ const { name: viewName, schema, materialized } = st;
838
+
839
+ const name = schema ? `"${schema}"."${viewName}"` : `"${viewName}"`;
840
+
841
+ return `DROP${materialized ? ' MATERIALIZED' : ''} VIEW ${name};`;
842
+ }
843
+ }
844
+
845
+ class MySqlDropViewConvertor extends Convertor {
846
+ can(statement: JsonStatement, dialect: Dialect): boolean {
847
+ return statement.type === 'drop_view' && dialect === 'mysql';
848
+ }
849
+
850
+ convert(st: JsonDropViewStatement) {
851
+ const { name } = st;
852
+
853
+ return `DROP VIEW \`${name}\`;`;
854
+ }
855
+ }
856
+
857
+ class SqliteDropViewConvertor extends Convertor {
858
+ can(statement: JsonStatement, dialect: Dialect): boolean {
859
+ return statement.type === 'drop_view' && (dialect === 'sqlite' || dialect === 'turso');
860
+ }
861
+
862
+ convert(st: JsonDropViewStatement) {
863
+ const { name } = st;
864
+
865
+ return `DROP VIEW \`${name}\`;`;
866
+ }
867
+ }
868
+
869
+ class MySqlAlterViewConvertor extends Convertor {
870
+ can(statement: JsonStatement, dialect: Dialect): boolean {
871
+ return statement.type === 'alter_mysql_view' && dialect === 'mysql';
872
+ }
873
+
874
+ convert(st: JsonAlterMySqlViewStatement) {
875
+ const { name, algorithm, definition, sqlSecurity, withCheckOption } = st;
876
+
877
+ let statement = `ALTER `;
878
+ statement += algorithm ? `ALGORITHM = ${algorithm}\n` : '';
879
+ statement += sqlSecurity ? `SQL SECURITY ${sqlSecurity}\n` : '';
880
+ statement += `VIEW \`${name}\` AS ${definition}`;
881
+ statement += withCheckOption ? `\nWITH ${withCheckOption} CHECK OPTION` : '';
882
+
883
+ statement += ';';
884
+
885
+ return statement;
886
+ }
887
+ }
888
+
889
+ class PgRenameViewConvertor extends Convertor {
890
+ can(statement: JsonStatement, dialect: Dialect): boolean {
891
+ return statement.type === 'rename_view' && dialect === 'postgresql';
892
+ }
893
+
894
+ convert(st: JsonRenameViewStatement) {
895
+ const { nameFrom: from, nameTo: to, schema, materialized } = st;
896
+
897
+ const nameFrom = `"${schema}"."${from}"`;
898
+
899
+ return `ALTER${materialized ? ' MATERIALIZED' : ''} VIEW ${nameFrom} RENAME TO "${to}";`;
900
+ }
901
+ }
902
+
903
+ class MySqlRenameViewConvertor extends Convertor {
904
+ can(statement: JsonStatement, dialect: Dialect): boolean {
905
+ return statement.type === 'rename_view' && dialect === 'mysql';
906
+ }
907
+
908
+ convert(st: JsonRenameViewStatement) {
909
+ const { nameFrom: from, nameTo: to } = st;
910
+
911
+ return `RENAME TABLE \`${from}\` TO \`${to}\`;`;
912
+ }
913
+ }
914
+
915
+ class PgAlterViewSchemaConvertor extends Convertor {
916
+ can(statement: JsonStatement, dialect: Dialect): boolean {
917
+ return statement.type === 'alter_view_alter_schema' && dialect === 'postgresql';
918
+ }
919
+
920
+ convert(st: JsonAlterViewAlterSchemaStatement) {
921
+ const { fromSchema, toSchema, name, materialized } = st;
922
+
923
+ const statement = `ALTER${
924
+ materialized ? ' MATERIALIZED' : ''
925
+ } VIEW "${fromSchema}"."${name}" SET SCHEMA "${toSchema}";`;
926
+
927
+ return statement;
928
+ }
929
+ }
930
+
931
+ class PgAlterViewAddWithOptionConvertor extends Convertor {
932
+ can(statement: JsonStatement, dialect: Dialect): boolean {
933
+ return statement.type === 'alter_view_add_with_option' && dialect === 'postgresql';
934
+ }
935
+
936
+ convert(st: JsonAlterViewAddWithOptionStatement) {
937
+ const { schema, with: withOption, name, materialized } = st;
938
+
939
+ let statement = `ALTER${materialized ? ' MATERIALIZED' : ''} VIEW "${schema}"."${name}" SET (`;
940
+
941
+ const options: string[] = [];
942
+
943
+ Object.entries(withOption).forEach(([key, value]) => {
944
+ options.push(`${key.snake_case()} = ${value}`);
945
+ });
946
+
947
+ statement += options.join(', ');
948
+
949
+ statement += `);`;
950
+
951
+ return statement;
952
+ }
953
+ }
954
+
955
+ class PgAlterViewDropWithOptionConvertor extends Convertor {
956
+ can(statement: JsonStatement, dialect: Dialect): boolean {
957
+ return statement.type === 'alter_view_drop_with_option' && dialect === 'postgresql';
958
+ }
959
+
960
+ convert(st: JsonAlterViewDropWithOptionStatement) {
961
+ const { schema, name, materialized, with: withOptions } = st;
962
+
963
+ let statement = `ALTER${materialized ? ' MATERIALIZED' : ''} VIEW "${schema}"."${name}" RESET (`;
964
+
965
+ const options: string[] = [];
966
+
967
+ Object.entries(withOptions).forEach(([key, value]) => {
968
+ options.push(`${key.snake_case()}`);
969
+ });
970
+
971
+ statement += options.join(', ');
972
+
973
+ statement += ');';
974
+
975
+ return statement;
976
+ }
977
+ }
978
+
979
+ class PgAlterViewAlterTablespaceConvertor extends Convertor {
980
+ can(statement: JsonStatement, dialect: Dialect): boolean {
981
+ return statement.type === 'alter_view_alter_tablespace' && dialect === 'postgresql';
982
+ }
983
+
984
+ convert(st: JsonAlterViewAlterTablespaceStatement) {
985
+ const { schema, name, toTablespace } = st;
986
+
987
+ const statement = `ALTER MATERIALIZED VIEW "${schema}"."${name}" SET TABLESPACE ${toTablespace};`;
988
+
989
+ return statement;
990
+ }
991
+ }
992
+
993
+ class PgAlterViewAlterUsingConvertor extends Convertor {
994
+ can(statement: JsonStatement, dialect: Dialect): boolean {
995
+ return statement.type === 'alter_view_alter_using' && dialect === 'postgresql';
996
+ }
997
+
998
+ convert(st: JsonAlterViewAlterUsingStatement) {
999
+ const { schema, name, toUsing } = st;
1000
+
1001
+ const statement = `ALTER MATERIALIZED VIEW "${schema}"."${name}" SET ACCESS METHOD "${toUsing}";`;
1002
+
1003
+ return statement;
1004
+ }
1005
+ }
1006
+
1007
+ class PgAlterTableAlterColumnSetGenerated extends Convertor {
1008
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
1009
+ return (
1010
+ statement.type === 'alter_table_alter_column_set_identity'
1011
+ && dialect === 'postgresql'
1012
+ );
1013
+ }
1014
+ override convert(
1015
+ statement: JsonAlterColumnSetIdentityStatement,
1016
+ ): string | string[] {
1017
+ const { identity, tableName, columnName, schema } = statement;
1018
+
1019
+ const tableNameWithSchema = schema
1020
+ ? `"${schema}"."${tableName}"`
1021
+ : `"${tableName}"`;
1022
+
1023
+ const unsquashedIdentity = PgSquasher.unsquashIdentity(identity);
1024
+
1025
+ const identityWithSchema = schema
1026
+ ? `"${schema}"."${unsquashedIdentity?.name}"`
1027
+ : `"${unsquashedIdentity?.name}"`;
1028
+
1029
+ const identityStatement = unsquashedIdentity
1030
+ ? ` GENERATED ${
1031
+ unsquashedIdentity.type === 'always' ? 'ALWAYS' : 'BY DEFAULT'
1032
+ } AS IDENTITY (sequence name ${identityWithSchema}${
1033
+ unsquashedIdentity.increment
1034
+ ? ` INCREMENT BY ${unsquashedIdentity.increment}`
1035
+ : ''
1036
+ }${
1037
+ unsquashedIdentity.minValue
1038
+ ? ` MINVALUE ${unsquashedIdentity.minValue}`
1039
+ : ''
1040
+ }${
1041
+ unsquashedIdentity.maxValue
1042
+ ? ` MAXVALUE ${unsquashedIdentity.maxValue}`
1043
+ : ''
1044
+ }${
1045
+ unsquashedIdentity.startWith
1046
+ ? ` START WITH ${unsquashedIdentity.startWith}`
1047
+ : ''
1048
+ }${unsquashedIdentity.cache ? ` CACHE ${unsquashedIdentity.cache}` : ''}${
1049
+ unsquashedIdentity.cycle ? ` CYCLE` : ''
1050
+ })`
1051
+ : '';
1052
+
1053
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" ADD${identityStatement};`;
1054
+ }
1055
+ }
1056
+
1057
+ class PgAlterTableAlterColumnDropGenerated extends Convertor {
1058
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
1059
+ return (
1060
+ statement.type === 'alter_table_alter_column_drop_identity'
1061
+ && dialect === 'postgresql'
1062
+ );
1063
+ }
1064
+ override convert(
1065
+ statement: JsonAlterColumnDropIdentityStatement,
1066
+ ): string | string[] {
1067
+ const { tableName, columnName, schema } = statement;
1068
+
1069
+ const tableNameWithSchema = schema
1070
+ ? `"${schema}"."${tableName}"`
1071
+ : `"${tableName}"`;
1072
+
1073
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" DROP IDENTITY;`;
1074
+ }
1075
+ }
1076
+
1077
+ class PgAlterTableAlterColumnAlterGenerated extends Convertor {
1078
+ override can(statement: JsonStatement, dialect: Dialect): boolean {
1079
+ return (
1080
+ statement.type === 'alter_table_alter_column_change_identity'
1081
+ && dialect === 'postgresql'
1082
+ );
1083
+ }
1084
+ override convert(
1085
+ statement: JsonAlterColumnAlterIdentityStatement,
1086
+ ): string | string[] {
1087
+ const { identity, oldIdentity, tableName, columnName, schema } = statement;
1088
+
1089
+ const tableNameWithSchema = schema
1090
+ ? `"${schema}"."${tableName}"`
1091
+ : `"${tableName}"`;
1092
+
1093
+ const unsquashedIdentity = PgSquasher.unsquashIdentity(identity);
1094
+ const unsquashedOldIdentity = PgSquasher.unsquashIdentity(oldIdentity);
1095
+
1096
+ const statementsToReturn: string[] = [];
1097
+
1098
+ if (unsquashedOldIdentity.type !== unsquashedIdentity.type) {
1099
+ statementsToReturn.push(
1100
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET GENERATED ${
1101
+ unsquashedIdentity.type === 'always' ? 'ALWAYS' : 'BY DEFAULT'
1102
+ };`,
1103
+ );
1104
+ }
1105
+
1106
+ if (unsquashedOldIdentity.minValue !== unsquashedIdentity.minValue) {
1107
+ statementsToReturn.push(
1108
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET MINVALUE ${unsquashedIdentity.minValue};`,
1109
+ );
1110
+ }
1111
+
1112
+ if (unsquashedOldIdentity.maxValue !== unsquashedIdentity.maxValue) {
1113
+ statementsToReturn.push(
1114
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET MAXVALUE ${unsquashedIdentity.maxValue};`,
1115
+ );
1116
+ }
1117
+
1118
+ if (unsquashedOldIdentity.increment !== unsquashedIdentity.increment) {
1119
+ statementsToReturn.push(
1120
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET INCREMENT BY ${unsquashedIdentity.increment};`,
1121
+ );
1122
+ }
1123
+
1124
+ if (unsquashedOldIdentity.startWith !== unsquashedIdentity.startWith) {
1125
+ statementsToReturn.push(
1126
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET START WITH ${unsquashedIdentity.startWith};`,
1127
+ );
1128
+ }
1129
+
1130
+ if (unsquashedOldIdentity.cache !== unsquashedIdentity.cache) {
1131
+ statementsToReturn.push(
1132
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET CACHE ${unsquashedIdentity.cache};`,
1133
+ );
1134
+ }
1135
+
1136
+ if (unsquashedOldIdentity.cycle !== unsquashedIdentity.cycle) {
1137
+ statementsToReturn.push(
1138
+ `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET ${
1139
+ unsquashedIdentity.cycle ? `CYCLE` : 'NO CYCLE'
1140
+ };`,
1141
+ );
1142
+ }
1143
+
1144
+ return statementsToReturn;
1145
+ }
1146
+ }
1147
+
1148
+ class PgAlterTableAddUniqueConstraintConvertor extends Convertor {
1149
+ can(statement: JsonCreateUniqueConstraint, dialect: Dialect): boolean {
1150
+ return (
1151
+ statement.type === 'create_unique_constraint' && dialect === 'postgresql'
1152
+ );
1153
+ }
1154
+ convert(statement: JsonCreateUniqueConstraint): string {
1155
+ const unsquashed = PgSquasher.unsquashUnique(statement.data);
1156
+
1157
+ const tableNameWithSchema = statement.schema
1158
+ ? `"${statement.schema}"."${statement.tableName}"`
1159
+ : `"${statement.tableName}"`;
1160
+
1161
+ return `ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${unsquashed.name}" UNIQUE${
1162
+ unsquashed.nullsNotDistinct ? ' NULLS NOT DISTINCT' : ''
1163
+ }("${unsquashed.columns.join('","')}");`;
1164
+ }
1165
+ }
1166
+
1167
+ class PgAlterTableDropUniqueConstraintConvertor extends Convertor {
1168
+ can(statement: JsonDeleteUniqueConstraint, dialect: Dialect): boolean {
1169
+ return (
1170
+ statement.type === 'delete_unique_constraint' && dialect === 'postgresql'
1171
+ );
1172
+ }
1173
+ convert(statement: JsonDeleteUniqueConstraint): string {
1174
+ const unsquashed = PgSquasher.unsquashUnique(statement.data);
1175
+
1176
+ const tableNameWithSchema = statement.schema
1177
+ ? `"${statement.schema}"."${statement.tableName}"`
1178
+ : `"${statement.tableName}"`;
1179
+
1180
+ return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${unsquashed.name}";`;
1181
+ }
1182
+ }
1183
+
1184
+ class PgAlterTableAddCheckConstraintConvertor extends Convertor {
1185
+ can(statement: JsonCreateCheckConstraint, dialect: Dialect): boolean {
1186
+ return (
1187
+ statement.type === 'create_check_constraint' && dialect === 'postgresql'
1188
+ );
1189
+ }
1190
+ convert(statement: JsonCreateCheckConstraint): string {
1191
+ const unsquashed = PgSquasher.unsquashCheck(statement.data);
1192
+
1193
+ const tableNameWithSchema = statement.schema
1194
+ ? `"${statement.schema}"."${statement.tableName}"`
1195
+ : `"${statement.tableName}"`;
1196
+
1197
+ return `ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${unsquashed.name}" CHECK (${unsquashed.value});`;
1198
+ }
1199
+ }
1200
+
1201
+ class PgAlterTableDeleteCheckConstraintConvertor extends Convertor {
1202
+ can(statement: JsonDeleteCheckConstraint, dialect: Dialect): boolean {
1203
+ return (
1204
+ statement.type === 'delete_check_constraint' && dialect === 'postgresql'
1205
+ );
1206
+ }
1207
+ convert(statement: JsonDeleteCheckConstraint): string {
1208
+ const tableNameWithSchema = statement.schema
1209
+ ? `"${statement.schema}"."${statement.tableName}"`
1210
+ : `"${statement.tableName}"`;
1211
+
1212
+ return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${statement.constraintName}";`;
1213
+ }
1214
+ }
1215
+
1216
+ class MySQLAlterTableAddUniqueConstraintConvertor extends Convertor {
1217
+ can(statement: JsonCreateUniqueConstraint, dialect: Dialect): boolean {
1218
+ return statement.type === 'create_unique_constraint' && dialect === 'mysql';
1219
+ }
1220
+ convert(statement: JsonCreateUniqueConstraint): string {
1221
+ const unsquashed = MySqlSquasher.unsquashUnique(statement.data);
1222
+
1223
+ return `ALTER TABLE \`${statement.tableName}\` ADD CONSTRAINT \`${unsquashed.name}\` UNIQUE(\`${
1224
+ unsquashed.columns.join('`,`')
1225
+ }\`);`;
1226
+ }
1227
+ }
1228
+
1229
+ class MySQLAlterTableDropUniqueConstraintConvertor extends Convertor {
1230
+ can(statement: JsonDeleteUniqueConstraint, dialect: Dialect): boolean {
1231
+ return statement.type === 'delete_unique_constraint' && dialect === 'mysql';
1232
+ }
1233
+ convert(statement: JsonDeleteUniqueConstraint): string {
1234
+ const unsquashed = MySqlSquasher.unsquashUnique(statement.data);
1235
+
1236
+ return `ALTER TABLE \`${statement.tableName}\` DROP INDEX \`${unsquashed.name}\`;`;
1237
+ }
1238
+ }
1239
+
1240
+ class MySqlAlterTableAddCheckConstraintConvertor extends Convertor {
1241
+ can(statement: JsonCreateCheckConstraint, dialect: Dialect): boolean {
1242
+ return (
1243
+ statement.type === 'create_check_constraint' && dialect === 'mysql'
1244
+ );
1245
+ }
1246
+ convert(statement: JsonCreateCheckConstraint): string {
1247
+ const unsquashed = MySqlSquasher.unsquashCheck(statement.data);
1248
+ const { tableName } = statement;
1249
+
1250
+ return `ALTER TABLE \`${tableName}\` ADD CONSTRAINT \`${unsquashed.name}\` CHECK (${unsquashed.value});`;
1251
+ }
1252
+ }
1253
+
1254
+ class SingleStoreAlterTableAddUniqueConstraintConvertor extends Convertor {
1255
+ can(statement: JsonCreateUniqueConstraint, dialect: Dialect): boolean {
1256
+ return statement.type === 'create_unique_constraint' && dialect === 'singlestore';
1257
+ }
1258
+ convert(statement: JsonCreateUniqueConstraint): string {
1259
+ const unsquashed = SingleStoreSquasher.unsquashUnique(statement.data);
1260
+
1261
+ return `ALTER TABLE \`${statement.tableName}\` ADD CONSTRAINT \`${unsquashed.name}\` UNIQUE(\`${
1262
+ unsquashed.columns.join('`,`')
1263
+ }\`);`;
1264
+ }
1265
+ }
1266
+ class SingleStoreAlterTableDropUniqueConstraintConvertor extends Convertor {
1267
+ can(statement: JsonDeleteUniqueConstraint, dialect: Dialect): boolean {
1268
+ return statement.type === 'delete_unique_constraint' && dialect === 'singlestore';
1269
+ }
1270
+ convert(statement: JsonDeleteUniqueConstraint): string {
1271
+ const unsquashed = SingleStoreSquasher.unsquashUnique(statement.data);
1272
+
1273
+ return `ALTER TABLE \`${statement.tableName}\` DROP INDEX \`${unsquashed.name}\`;`;
1274
+ }
1275
+ }
1276
+
1277
+ class MySqlAlterTableDeleteCheckConstraintConvertor extends Convertor {
1278
+ can(statement: JsonDeleteCheckConstraint, dialect: Dialect): boolean {
1279
+ return (
1280
+ statement.type === 'delete_check_constraint' && dialect === 'mysql'
1281
+ );
1282
+ }
1283
+ convert(statement: JsonDeleteCheckConstraint): string {
1284
+ const { tableName } = statement;
1285
+
1286
+ return `ALTER TABLE \`${tableName}\` DROP CONSTRAINT \`${statement.constraintName}\`;`;
1287
+ }
1288
+ }
1289
+
1290
+ class CreatePgSequenceConvertor extends Convertor {
1291
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1292
+ return statement.type === 'create_sequence' && dialect === 'postgresql';
1293
+ }
1294
+
1295
+ convert(st: JsonCreateSequenceStatement) {
1296
+ const { name, values, schema } = st;
1297
+
1298
+ const sequenceWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
1299
+
1300
+ return `CREATE SEQUENCE ${sequenceWithSchema}${values.increment ? ` INCREMENT BY ${values.increment}` : ''}${
1301
+ values.minValue ? ` MINVALUE ${values.minValue}` : ''
1302
+ }${values.maxValue ? ` MAXVALUE ${values.maxValue}` : ''}${
1303
+ values.startWith ? ` START WITH ${values.startWith}` : ''
1304
+ }${values.cache ? ` CACHE ${values.cache}` : ''}${values.cycle ? ` CYCLE` : ''};`;
1305
+ }
1306
+ }
1307
+
1308
+ class DropPgSequenceConvertor extends Convertor {
1309
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1310
+ return statement.type === 'drop_sequence' && dialect === 'postgresql';
1311
+ }
1312
+
1313
+ convert(st: JsonDropSequenceStatement) {
1314
+ const { name, schema } = st;
1315
+
1316
+ const sequenceWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
1317
+
1318
+ return `DROP SEQUENCE ${sequenceWithSchema};`;
1319
+ }
1320
+ }
1321
+
1322
+ class RenamePgSequenceConvertor extends Convertor {
1323
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1324
+ return statement.type === 'rename_sequence' && dialect === 'postgresql';
1325
+ }
1326
+
1327
+ convert(st: JsonRenameSequenceStatement) {
1328
+ const { nameFrom, nameTo, schema } = st;
1329
+
1330
+ const sequenceWithSchemaFrom = schema
1331
+ ? `"${schema}"."${nameFrom}"`
1332
+ : `"${nameFrom}"`;
1333
+ const sequenceWithSchemaTo = schema
1334
+ ? `"${schema}"."${nameTo}"`
1335
+ : `"${nameTo}"`;
1336
+
1337
+ return `ALTER SEQUENCE ${sequenceWithSchemaFrom} RENAME TO "${nameTo}";`;
1338
+ }
1339
+ }
1340
+
1341
+ class MovePgSequenceConvertor extends Convertor {
1342
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1343
+ return statement.type === 'move_sequence' && dialect === 'postgresql';
1344
+ }
1345
+
1346
+ convert(st: JsonMoveSequenceStatement) {
1347
+ const { schemaFrom, schemaTo, name } = st;
1348
+
1349
+ const sequenceWithSchema = schemaFrom
1350
+ ? `"${schemaFrom}"."${name}"`
1351
+ : `"${name}"`;
1352
+
1353
+ const seqSchemaTo = schemaTo ? `"${schemaTo}"` : `public`;
1354
+
1355
+ return `ALTER SEQUENCE ${sequenceWithSchema} SET SCHEMA ${seqSchemaTo};`;
1356
+ }
1357
+ }
1358
+
1359
+ class AlterPgSequenceConvertor extends Convertor {
1360
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1361
+ return statement.type === 'alter_sequence' && dialect === 'postgresql';
1362
+ }
1363
+
1364
+ convert(st: JsonAlterSequenceStatement) {
1365
+ const { name, schema, values } = st;
1366
+
1367
+ const { increment, minValue, maxValue, startWith, cache, cycle } = values;
1368
+
1369
+ const sequenceWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
1370
+
1371
+ return `ALTER SEQUENCE ${sequenceWithSchema}${increment ? ` INCREMENT BY ${increment}` : ''}${
1372
+ minValue ? ` MINVALUE ${minValue}` : ''
1373
+ }${maxValue ? ` MAXVALUE ${maxValue}` : ''}${startWith ? ` START WITH ${startWith}` : ''}${
1374
+ cache ? ` CACHE ${cache}` : ''
1375
+ }${cycle ? ` CYCLE` : ''};`;
1376
+ }
1377
+ }
1378
+
1379
+ abstract class DomainConvertor extends Convertor {
1380
+ protected getDomainNameWithSchema(name: string, schema?: string): string {
1381
+ return schema ? `"${schema}"."${name}"` : `"${name}"`;
1382
+ }
1383
+ }
1384
+
1385
+ class CreateDomainConvertor extends DomainConvertor {
1386
+ can(statement: JsonStatement): boolean {
1387
+ return statement.type === 'create_domain';
1388
+ }
1389
+
1390
+ convert(st: JsonCreateDomainStatement): string {
1391
+ const { name, schema, baseType, notNull, defaultValue, checkConstraints } = st;
1392
+ const domainNameWithSchema = this.getDomainNameWithSchema(name, schema);
1393
+ let statement = `CREATE DOMAIN ${domainNameWithSchema} AS ${baseType}`;
1394
+
1395
+ if (notNull) {
1396
+ statement += ' NOT NULL';
1397
+ }
1398
+
1399
+ if (defaultValue) {
1400
+ statement += ` DEFAULT '${defaultValue}'`;
1401
+ }
1402
+
1403
+ if (checkConstraints && checkConstraints.length > 0) {
1404
+ for (const checkConstraint of checkConstraints) {
1405
+ const unsquashedCheck = PgSquasher.unsquashCheck(checkConstraint);
1406
+
1407
+ if (unsquashedCheck.name) {
1408
+ statement += ` CONSTRAINT ${unsquashedCheck.name} CHECK (${unsquashedCheck.value})`;
1409
+ } else {
1410
+ statement += ` CHECK (${unsquashedCheck.value})`;
1411
+ }
1412
+ }
1413
+ }
1414
+
1415
+ statement += ';';
1416
+ return statement;
1417
+ }
1418
+ }
1419
+
1420
+ class AlterDomainConvertor extends DomainConvertor {
1421
+ can(statement: JsonStatement): boolean {
1422
+ return statement.type === 'alter_domain';
1423
+ }
1424
+
1425
+ convert(st: JsonAlterDomainStatement): string {
1426
+ const { name, schema, action, checkConstraints, defaultValue } = st;
1427
+ const domainNameWithSchema = this.getDomainNameWithSchema(name, schema);
1428
+ let statement = `ALTER DOMAIN ${domainNameWithSchema}`;
1429
+
1430
+ switch (action) {
1431
+ case 'add_constraint':
1432
+ if (checkConstraints && checkConstraints.length > 0) {
1433
+ for (const checkConstraint of checkConstraints) {
1434
+ const unsquashedCheck = PgSquasher.unsquashCheck(checkConstraint);
1435
+
1436
+ if (unsquashedCheck.name) {
1437
+ statement += ` ADD CONSTRAINT ${unsquashedCheck.name} CHECK (${unsquashedCheck.value})`;
1438
+ } else {
1439
+ statement += ` ADD CHECK (${unsquashedCheck.value})`;
1440
+ }
1441
+ }
1442
+ }
1443
+ break;
1444
+ case 'drop_constraint':
1445
+ if (checkConstraints && checkConstraints.length > 0) {
1446
+ for (const checkConstraint of checkConstraints) {
1447
+ const unsquashedCheck = PgSquasher.unsquashCheck(checkConstraint);
1448
+ statement += ` DROP CONSTRAINT ${unsquashedCheck.name}`;
1449
+ }
1450
+ }
1451
+ break;
1452
+ case 'set_not_null':
1453
+ statement += ` SET NOT NULL`;
1454
+ break;
1455
+ case 'drop_not_null':
1456
+ statement += ` DROP NOT NULL`;
1457
+ break;
1458
+ case 'set_default':
1459
+ statement += ` SET DEFAULT ${defaultValue}`;
1460
+ break;
1461
+ case 'drop_default':
1462
+ statement += ` DROP DEFAULT`;
1463
+ break;
1464
+ default:
1465
+ throw new Error(`Unknown alter domain action: ${action}`);
1466
+ }
1467
+
1468
+ statement += ';';
1469
+ return statement;
1470
+ }
1471
+ }
1472
+
1473
+ class DropDomainConvertor extends DomainConvertor {
1474
+ can(statement: JsonStatement): boolean {
1475
+ return statement.type === 'drop_domain';
1476
+ }
1477
+
1478
+ convert(st: JsonDropDomainStatement): string {
1479
+ const { name, schema } = st;
1480
+ const domainNameWithSchema = this.getDomainNameWithSchema(name, schema);
1481
+ return `DROP DOMAIN ${domainNameWithSchema} CASCADE;`;
1482
+ }
1483
+ }
1484
+
1485
+ class CreateTypeEnumConvertor extends Convertor {
1486
+ can(statement: JsonStatement): boolean {
1487
+ return statement.type === 'create_type_enum';
1488
+ }
1489
+
1490
+ convert(st: JsonCreateEnumStatement) {
1491
+ const { name, values, schema } = st;
1492
+
1493
+ const enumNameWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
1494
+
1495
+ let valuesStatement = '(';
1496
+ valuesStatement += values.map((it) => `'${escapeSingleQuotes(it)}'`).join(', ');
1497
+ valuesStatement += ')';
1498
+
1499
+ // TODO do we need this?
1500
+ // let statement = 'DO $$ BEGIN';
1501
+ // statement += '\n';
1502
+ let statement = `CREATE TYPE ${enumNameWithSchema} AS ENUM${valuesStatement};`;
1503
+ // statement += '\n';
1504
+ // statement += 'EXCEPTION';
1505
+ // statement += '\n';
1506
+ // statement += ' WHEN duplicate_object THEN null;';
1507
+ // statement += '\n';
1508
+ // statement += 'END $$;';
1509
+ // statement += '\n';
1510
+ return statement;
1511
+ }
1512
+ }
1513
+
1514
+ class DropTypeEnumConvertor extends Convertor {
1515
+ can(statement: JsonStatement): boolean {
1516
+ return statement.type === 'drop_type_enum';
1517
+ }
1518
+
1519
+ convert(st: JsonDropEnumStatement) {
1520
+ const { name, schema } = st;
1521
+
1522
+ const enumNameWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
1523
+
1524
+ let statement = `DROP TYPE ${enumNameWithSchema};`;
1525
+
1526
+ return statement;
1527
+ }
1528
+ }
1529
+
1530
+ class AlterTypeAddValueConvertor extends Convertor {
1531
+ can(statement: JsonStatement): boolean {
1532
+ return statement.type === 'alter_type_add_value';
1533
+ }
1534
+
1535
+ convert(st: JsonAddValueToEnumStatement) {
1536
+ const { name, schema, value, before } = st;
1537
+
1538
+ const enumNameWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
1539
+
1540
+ return `ALTER TYPE ${enumNameWithSchema} ADD VALUE '${value}'${before.length ? ` BEFORE '${before}'` : ''};`;
1541
+ }
1542
+ }
1543
+
1544
+ class AlterTypeSetSchemaConvertor extends Convertor {
1545
+ can(statement: JsonStatement): boolean {
1546
+ return statement.type === 'move_type_enum';
1547
+ }
1548
+
1549
+ convert(st: JsonMoveEnumStatement) {
1550
+ const { name, schemaFrom, schemaTo } = st;
1551
+
1552
+ const enumNameWithSchema = schemaFrom ? `"${schemaFrom}"."${name}"` : `"${name}"`;
1553
+
1554
+ return `ALTER TYPE ${enumNameWithSchema} SET SCHEMA "${schemaTo}";`;
1555
+ }
1556
+ }
1557
+
1558
+ class AlterRenameTypeConvertor extends Convertor {
1559
+ can(statement: JsonStatement): boolean {
1560
+ return statement.type === 'rename_type_enum';
1561
+ }
1562
+
1563
+ convert(st: JsonRenameEnumStatement) {
1564
+ const { nameTo, nameFrom, schema } = st;
1565
+
1566
+ const enumNameWithSchema = schema ? `"${schema}"."${nameFrom}"` : `"${nameFrom}"`;
1567
+
1568
+ return `ALTER TYPE ${enumNameWithSchema} RENAME TO "${nameTo}";`;
1569
+ }
1570
+ }
1571
+
1572
+ class AlterTypeDropValueConvertor extends Convertor {
1573
+ can(statement: JsonStatement): boolean {
1574
+ return statement.type === 'alter_type_drop_value';
1575
+ }
1576
+
1577
+ convert(st: JsonDropValueFromEnumStatement) {
1578
+ const { columnsWithEnum, name, newValues, schema } = st;
1579
+
1580
+ const statements: string[] = [];
1581
+
1582
+ for (const withEnum of columnsWithEnum) {
1583
+ statements.push(
1584
+ `ALTER TABLE "${withEnum.schema}"."${withEnum.table}" ALTER COLUMN "${withEnum.column}" SET DATA TYPE text;`,
1585
+ );
1586
+ }
1587
+
1588
+ statements.push(new DropTypeEnumConvertor().convert({ name: name, schema, type: 'drop_type_enum' }));
1589
+
1590
+ statements.push(new CreateTypeEnumConvertor().convert({
1591
+ name: name,
1592
+ schema: schema,
1593
+ values: newValues,
1594
+ type: 'create_type_enum',
1595
+ }));
1596
+
1597
+ for (const withEnum of columnsWithEnum) {
1598
+ statements.push(
1599
+ `ALTER TABLE "${withEnum.schema}"."${withEnum.table}" ALTER COLUMN "${withEnum.column}" SET DATA TYPE "${schema}"."${name}" USING "${withEnum.column}"::"${schema}"."${name}";`,
1600
+ );
1601
+ }
1602
+
1603
+ return statements;
1604
+ }
1605
+ }
1606
+
1607
+ class PgDropTableConvertor extends Convertor {
1608
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1609
+ return statement.type === 'drop_table' && dialect === 'postgresql';
1610
+ }
1611
+
1612
+ convert(statement: JsonDropTableStatement, _d: any, action?: string) {
1613
+ const { tableName, schema, policies } = statement;
1614
+
1615
+ const tableNameWithSchema = schema
1616
+ ? `"${schema}"."${tableName}"`
1617
+ : `"${tableName}"`;
1618
+
1619
+ const dropPolicyConvertor = new PgDropPolicyConvertor();
1620
+ const droppedPolicies = policies?.map((p) => {
1621
+ return dropPolicyConvertor.convert({
1622
+ type: 'drop_policy',
1623
+ tableName,
1624
+ data: action === 'push'
1625
+ ? PgSquasher.unsquashPolicyPush(p)
1626
+ : PgSquasher.unsquashPolicy(p),
1627
+ schema,
1628
+ }) as string;
1629
+ }) ?? [];
1630
+
1631
+ return [
1632
+ ...droppedPolicies,
1633
+ `DROP TABLE ${tableNameWithSchema} CASCADE;`,
1634
+ ];
1635
+ }
1636
+ }
1637
+
1638
+ class MySQLDropTableConvertor extends Convertor {
1639
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1640
+ return statement.type === 'drop_table' && dialect === 'mysql';
1641
+ }
1642
+
1643
+ convert(statement: JsonDropTableStatement) {
1644
+ const { tableName } = statement;
1645
+ return `DROP TABLE \`${tableName}\`;`;
1646
+ }
1647
+ }
1648
+
1649
+ export class SingleStoreDropTableConvertor extends Convertor {
1650
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1651
+ return statement.type === 'drop_table' && dialect === 'singlestore';
1652
+ }
1653
+
1654
+ convert(statement: JsonDropTableStatement) {
1655
+ const { tableName } = statement;
1656
+ return `DROP TABLE \`${tableName}\`;`;
1657
+ }
1658
+ }
1659
+
1660
+ export class SQLiteDropTableConvertor extends Convertor {
1661
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1662
+ return statement.type === 'drop_table' && (dialect === 'sqlite' || dialect === 'turso');
1663
+ }
1664
+
1665
+ convert(statement: JsonDropTableStatement) {
1666
+ const { tableName } = statement;
1667
+ return `DROP TABLE \`${tableName}\`;`;
1668
+ }
1669
+ }
1670
+
1671
+ class PgRenameTableConvertor extends Convertor {
1672
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1673
+ return statement.type === 'rename_table' && dialect === 'postgresql';
1674
+ }
1675
+
1676
+ convert(statement: JsonRenameTableStatement) {
1677
+ const { tableNameFrom, tableNameTo, toSchema, fromSchema } = statement;
1678
+ const from = fromSchema
1679
+ ? `"${fromSchema}"."${tableNameFrom}"`
1680
+ : `"${tableNameFrom}"`;
1681
+ const to = `"${tableNameTo}"`;
1682
+ return `ALTER TABLE ${from} RENAME TO ${to};`;
1683
+ }
1684
+ }
1685
+
1686
+ export class SqliteRenameTableConvertor extends Convertor {
1687
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1688
+ return statement.type === 'rename_table' && (dialect === 'sqlite' || dialect === 'turso');
1689
+ }
1690
+
1691
+ convert(statement: JsonRenameTableStatement) {
1692
+ const { tableNameFrom, tableNameTo } = statement;
1693
+ return `ALTER TABLE \`${tableNameFrom}\` RENAME TO \`${tableNameTo}\`;`;
1694
+ }
1695
+ }
1696
+
1697
+ class MySqlRenameTableConvertor extends Convertor {
1698
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1699
+ return statement.type === 'rename_table' && dialect === 'mysql';
1700
+ }
1701
+
1702
+ convert(statement: JsonRenameTableStatement) {
1703
+ const { tableNameFrom, tableNameTo } = statement;
1704
+ return `RENAME TABLE \`${tableNameFrom}\` TO \`${tableNameTo}\`;`;
1705
+ }
1706
+ }
1707
+
1708
+ export class SingleStoreRenameTableConvertor extends Convertor {
1709
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1710
+ return statement.type === 'rename_table' && dialect === 'singlestore';
1711
+ }
1712
+
1713
+ convert(statement: JsonRenameTableStatement) {
1714
+ const { tableNameFrom, tableNameTo } = statement;
1715
+ return `ALTER TABLE \`${tableNameFrom}\` RENAME TO \`${tableNameTo}\`;`;
1716
+ }
1717
+ }
1718
+
1719
+ class PgAlterTableRenameColumnConvertor extends Convertor {
1720
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1721
+ return (
1722
+ statement.type === 'alter_table_rename_column' && dialect === 'postgresql'
1723
+ );
1724
+ }
1725
+
1726
+ convert(statement: JsonRenameColumnStatement) {
1727
+ const { tableName, oldColumnName, newColumnName, schema } = statement;
1728
+
1729
+ const tableNameWithSchema = schema
1730
+ ? `"${schema}"."${tableName}"`
1731
+ : `"${tableName}"`;
1732
+
1733
+ return `ALTER TABLE ${tableNameWithSchema} RENAME COLUMN "${oldColumnName}" TO "${newColumnName}";`;
1734
+ }
1735
+ }
1736
+
1737
+ class MySqlAlterTableRenameColumnConvertor extends Convertor {
1738
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1739
+ return (
1740
+ statement.type === 'alter_table_rename_column' && dialect === 'mysql'
1741
+ );
1742
+ }
1743
+
1744
+ convert(statement: JsonRenameColumnStatement) {
1745
+ const { tableName, oldColumnName, newColumnName } = statement;
1746
+ return `ALTER TABLE \`${tableName}\` RENAME COLUMN \`${oldColumnName}\` TO \`${newColumnName}\`;`;
1747
+ }
1748
+ }
1749
+
1750
+ class SingleStoreAlterTableRenameColumnConvertor extends Convertor {
1751
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1752
+ return (
1753
+ statement.type === 'alter_table_rename_column' && dialect === 'singlestore'
1754
+ );
1755
+ }
1756
+
1757
+ convert(statement: JsonRenameColumnStatement) {
1758
+ const { tableName, oldColumnName, newColumnName } = statement;
1759
+ return `ALTER TABLE \`${tableName}\` CHANGE \`${oldColumnName}\` \`${newColumnName}\`;`;
1760
+ }
1761
+ }
1762
+
1763
+ class SQLiteAlterTableRenameColumnConvertor extends Convertor {
1764
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1765
+ return (
1766
+ statement.type === 'alter_table_rename_column' && (dialect === 'sqlite' || dialect === 'turso')
1767
+ );
1768
+ }
1769
+
1770
+ convert(statement: JsonRenameColumnStatement) {
1771
+ const { tableName, oldColumnName, newColumnName } = statement;
1772
+ return `ALTER TABLE \`${tableName}\` RENAME COLUMN "${oldColumnName}" TO "${newColumnName}";`;
1773
+ }
1774
+ }
1775
+
1776
+ class PgAlterTableDropColumnConvertor extends Convertor {
1777
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1778
+ return (
1779
+ statement.type === 'alter_table_drop_column' && dialect === 'postgresql'
1780
+ );
1781
+ }
1782
+
1783
+ convert(statement: JsonDropColumnStatement) {
1784
+ const { tableName, columnName, schema } = statement;
1785
+
1786
+ const tableNameWithSchema = schema
1787
+ ? `"${schema}"."${tableName}"`
1788
+ : `"${tableName}"`;
1789
+
1790
+ return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${columnName}";`;
1791
+ }
1792
+ }
1793
+
1794
+ class MySqlAlterTableDropColumnConvertor extends Convertor {
1795
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1796
+ return statement.type === 'alter_table_drop_column' && dialect === 'mysql';
1797
+ }
1798
+
1799
+ convert(statement: JsonDropColumnStatement) {
1800
+ const { tableName, columnName } = statement;
1801
+ return `ALTER TABLE \`${tableName}\` DROP COLUMN \`${columnName}\`;`;
1802
+ }
1803
+ }
1804
+
1805
+ class SingleStoreAlterTableDropColumnConvertor extends Convertor {
1806
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1807
+ return statement.type === 'alter_table_drop_column' && dialect === 'singlestore';
1808
+ }
1809
+
1810
+ convert(statement: JsonDropColumnStatement) {
1811
+ const { tableName, columnName } = statement;
1812
+ return `ALTER TABLE \`${tableName}\` DROP COLUMN \`${columnName}\`;`;
1813
+ }
1814
+ }
1815
+
1816
+ class SQLiteAlterTableDropColumnConvertor extends Convertor {
1817
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1818
+ return statement.type === 'alter_table_drop_column' && (dialect === 'sqlite' || dialect === 'turso');
1819
+ }
1820
+
1821
+ convert(statement: JsonDropColumnStatement) {
1822
+ const { tableName, columnName } = statement;
1823
+ return `ALTER TABLE \`${tableName}\` DROP COLUMN \`${columnName}\`;`;
1824
+ }
1825
+ }
1826
+
1827
+ class PgAlterTableAddColumnConvertor extends Convertor {
1828
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1829
+ return (
1830
+ statement.type === 'alter_table_add_column' && dialect === 'postgresql'
1831
+ );
1832
+ }
1833
+
1834
+ convert(statement: JsonAddColumnStatement) {
1835
+ const { tableName, column, schema } = statement;
1836
+ const { name, type, notNull, generated, primaryKey, identity } = column;
1837
+
1838
+ const primaryKeyStatement = primaryKey ? ' PRIMARY KEY' : '';
1839
+
1840
+ const tableNameWithSchema = schema
1841
+ ? `"${schema}"."${tableName}"`
1842
+ : `"${tableName}"`;
1843
+
1844
+ const defaultStatement = `${column.default !== undefined ? ` DEFAULT ${column.default}` : ''}`;
1845
+
1846
+ const schemaPrefix = column.typeSchema && column.typeSchema !== 'public'
1847
+ ? `"${column.typeSchema}".`
1848
+ : '';
1849
+
1850
+ const fixedType = parseType(schemaPrefix, column.type);
1851
+
1852
+ const notNullStatement = `${notNull ? ' NOT NULL' : ''}`;
1853
+
1854
+ const unsquashedIdentity = identity
1855
+ ? PgSquasher.unsquashIdentity(identity)
1856
+ : undefined;
1857
+
1858
+ const identityWithSchema = schema
1859
+ ? `"${schema}"."${unsquashedIdentity?.name}"`
1860
+ : `"${unsquashedIdentity?.name}"`;
1861
+
1862
+ const identityStatement = unsquashedIdentity
1863
+ ? ` GENERATED ${
1864
+ unsquashedIdentity.type === 'always' ? 'ALWAYS' : 'BY DEFAULT'
1865
+ } AS IDENTITY (sequence name ${identityWithSchema}${
1866
+ unsquashedIdentity.increment
1867
+ ? ` INCREMENT BY ${unsquashedIdentity.increment}`
1868
+ : ''
1869
+ }${
1870
+ unsquashedIdentity.minValue
1871
+ ? ` MINVALUE ${unsquashedIdentity.minValue}`
1872
+ : ''
1873
+ }${
1874
+ unsquashedIdentity.maxValue
1875
+ ? ` MAXVALUE ${unsquashedIdentity.maxValue}`
1876
+ : ''
1877
+ }${
1878
+ unsquashedIdentity.startWith
1879
+ ? ` START WITH ${unsquashedIdentity.startWith}`
1880
+ : ''
1881
+ }${unsquashedIdentity.cache ? ` CACHE ${unsquashedIdentity.cache}` : ''}${
1882
+ unsquashedIdentity.cycle ? ` CYCLE` : ''
1883
+ })`
1884
+ : '';
1885
+
1886
+ const generatedStatement = generated ? ` GENERATED ALWAYS AS (${generated?.as}) STORED` : '';
1887
+
1888
+ return `ALTER TABLE ${tableNameWithSchema} ADD COLUMN "${name}" ${fixedType}${primaryKeyStatement}${defaultStatement}${generatedStatement}${notNullStatement}${identityStatement};`;
1889
+ }
1890
+ }
1891
+
1892
+ class MySqlAlterTableAddColumnConvertor extends Convertor {
1893
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1894
+ return statement.type === 'alter_table_add_column' && dialect === 'mysql';
1895
+ }
1896
+
1897
+ convert(statement: JsonAddColumnStatement) {
1898
+ const { tableName, column } = statement;
1899
+ const {
1900
+ name,
1901
+ type,
1902
+ notNull,
1903
+ primaryKey,
1904
+ autoincrement,
1905
+ onUpdate,
1906
+ generated,
1907
+ } = column;
1908
+
1909
+ const defaultStatement = `${column.default !== undefined ? ` DEFAULT ${column.default}` : ''}`;
1910
+ const notNullStatement = `${notNull ? ' NOT NULL' : ''}`;
1911
+ const primaryKeyStatement = `${primaryKey ? ' PRIMARY KEY' : ''}`;
1912
+ const autoincrementStatement = `${autoincrement ? ' AUTO_INCREMENT' : ''}`;
1913
+ const onUpdateStatement = `${onUpdate ? ' ON UPDATE CURRENT_TIMESTAMP' : ''}`;
1914
+
1915
+ const generatedStatement = generated
1916
+ ? ` GENERATED ALWAYS AS (${generated?.as}) ${generated?.type.toUpperCase()}`
1917
+ : '';
1918
+
1919
+ return `ALTER TABLE \`${tableName}\` ADD \`${name}\` ${type}${primaryKeyStatement}${autoincrementStatement}${defaultStatement}${generatedStatement}${notNullStatement}${onUpdateStatement};`;
1920
+ }
1921
+ }
1922
+
1923
+ class SingleStoreAlterTableAddColumnConvertor extends Convertor {
1924
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1925
+ return statement.type === 'alter_table_add_column' && dialect === 'singlestore';
1926
+ }
1927
+
1928
+ convert(statement: JsonAddColumnStatement) {
1929
+ const { tableName, column } = statement;
1930
+ const {
1931
+ name,
1932
+ type,
1933
+ notNull,
1934
+ primaryKey,
1935
+ autoincrement,
1936
+ onUpdate,
1937
+ generated,
1938
+ } = column;
1939
+
1940
+ const defaultStatement = `${column.default !== undefined ? ` DEFAULT ${column.default}` : ''}`;
1941
+ const notNullStatement = `${notNull ? ' NOT NULL' : ''}`;
1942
+ const primaryKeyStatement = `${primaryKey ? ' PRIMARY KEY' : ''}`;
1943
+ const autoincrementStatement = `${autoincrement ? ' AUTO_INCREMENT' : ''}`;
1944
+ const onUpdateStatement = `${onUpdate ? ' ON UPDATE CURRENT_TIMESTAMP' : ''}`;
1945
+
1946
+ const generatedStatement = generated
1947
+ ? ` GENERATED ALWAYS AS (${generated?.as}) ${generated?.type.toUpperCase()}`
1948
+ : '';
1949
+
1950
+ return `ALTER TABLE \`${tableName}\` ADD \`${name}\` ${type}${primaryKeyStatement}${autoincrementStatement}${defaultStatement}${notNullStatement}${onUpdateStatement}${generatedStatement};`;
1951
+ }
1952
+ }
1953
+
1954
+ export class SQLiteAlterTableAddColumnConvertor extends Convertor {
1955
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1956
+ return (
1957
+ statement.type === 'sqlite_alter_table_add_column' && (dialect === 'sqlite' || dialect === 'turso')
1958
+ );
1959
+ }
1960
+
1961
+ convert(statement: JsonSqliteAddColumnStatement) {
1962
+ const { tableName, column, referenceData } = statement;
1963
+ const { name, type, notNull, primaryKey, generated } = column;
1964
+
1965
+ const defaultStatement = `${column.default !== undefined ? ` DEFAULT ${column.default}` : ''}`;
1966
+ const notNullStatement = `${notNull ? ' NOT NULL' : ''}`;
1967
+ const primaryKeyStatement = `${primaryKey ? ' PRIMARY KEY' : ''}`;
1968
+ const referenceAsObject = referenceData
1969
+ ? SQLiteSquasher.unsquashFK(referenceData)
1970
+ : undefined;
1971
+ const referenceStatement = `${
1972
+ referenceAsObject
1973
+ ? ` REFERENCES ${referenceAsObject.tableTo}(${referenceAsObject.columnsTo})`
1974
+ : ''
1975
+ }`;
1976
+ // const autoincrementStatement = `${autoincrement ? 'AUTO_INCREMENT' : ''}`
1977
+ const generatedStatement = generated
1978
+ ? ` GENERATED ALWAYS AS ${generated.as} ${generated.type.toUpperCase()}`
1979
+ : '';
1980
+
1981
+ return `ALTER TABLE \`${tableName}\` ADD \`${name}\` ${type}${primaryKeyStatement}${defaultStatement}${generatedStatement}${notNullStatement}${referenceStatement};`;
1982
+ }
1983
+ }
1984
+
1985
+ class PgAlterTableAlterColumnSetTypeConvertor extends Convertor {
1986
+ can(statement: JsonStatement, dialect: Dialect): boolean {
1987
+ return (
1988
+ statement.type === 'alter_table_alter_column_set_type'
1989
+ && dialect === 'postgresql'
1990
+ );
1991
+ }
1992
+
1993
+ convert(statement: JsonAlterColumnTypeStatement) {
1994
+ const { tableName, columnName, newDataType, schema } = statement;
1995
+
1996
+ const tableNameWithSchema = schema
1997
+ ? `"${schema}"."${tableName}"`
1998
+ : `"${tableName}"`;
1999
+
2000
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET DATA TYPE ${newDataType};`;
2001
+ }
2002
+ }
2003
+
2004
+ class PgAlterTableAlterColumnSetDefaultConvertor extends Convertor {
2005
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2006
+ return (
2007
+ statement.type === 'alter_table_alter_column_set_default'
2008
+ && dialect === 'postgresql'
2009
+ );
2010
+ }
2011
+
2012
+ convert(statement: JsonAlterColumnSetDefaultStatement) {
2013
+ const { tableName, columnName, schema } = statement;
2014
+
2015
+ const tableNameWithSchema = schema
2016
+ ? `"${schema}"."${tableName}"`
2017
+ : `"${tableName}"`;
2018
+
2019
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET DEFAULT ${statement.newDefaultValue};`;
2020
+ }
2021
+ }
2022
+
2023
+ class PgAlterTableAlterColumnDropDefaultConvertor extends Convertor {
2024
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2025
+ return (
2026
+ statement.type === 'alter_table_alter_column_drop_default'
2027
+ && dialect === 'postgresql'
2028
+ );
2029
+ }
2030
+
2031
+ convert(statement: JsonAlterColumnDropDefaultStatement) {
2032
+ const { tableName, columnName, schema } = statement;
2033
+
2034
+ const tableNameWithSchema = schema
2035
+ ? `"${schema}"."${tableName}"`
2036
+ : `"${tableName}"`;
2037
+
2038
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" DROP DEFAULT;`;
2039
+ }
2040
+ }
2041
+
2042
+ class PgAlterTableAlterColumnDropGeneratedConvertor extends Convertor {
2043
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2044
+ return (
2045
+ statement.type === 'alter_table_alter_column_drop_generated'
2046
+ && dialect === 'postgresql'
2047
+ );
2048
+ }
2049
+
2050
+ convert(statement: JsonAlterColumnDropGeneratedStatement) {
2051
+ const { tableName, columnName, schema } = statement;
2052
+
2053
+ const tableNameWithSchema = schema
2054
+ ? `"${schema}"."${tableName}"`
2055
+ : `"${tableName}"`;
2056
+
2057
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" DROP EXPRESSION;`;
2058
+ }
2059
+ }
2060
+
2061
+ class PgAlterTableAlterColumnSetExpressionConvertor extends Convertor {
2062
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2063
+ return (
2064
+ statement.type === 'alter_table_alter_column_set_generated'
2065
+ && dialect === 'postgresql'
2066
+ );
2067
+ }
2068
+
2069
+ convert(statement: JsonAlterColumnSetGeneratedStatement) {
2070
+ const {
2071
+ tableName,
2072
+ columnName,
2073
+ schema,
2074
+ columnNotNull: notNull,
2075
+ columnDefault,
2076
+ columnOnUpdate,
2077
+ columnAutoIncrement,
2078
+ columnPk,
2079
+ columnGenerated,
2080
+ } = statement;
2081
+
2082
+ const tableNameWithSchema = schema
2083
+ ? `"${schema}"."${tableName}"`
2084
+ : `"${tableName}"`;
2085
+
2086
+ const addColumnStatement = new PgAlterTableAddColumnConvertor().convert({
2087
+ schema,
2088
+ tableName,
2089
+ column: {
2090
+ name: columnName,
2091
+ type: statement.newDataType,
2092
+ notNull,
2093
+ default: columnDefault,
2094
+ onUpdate: columnOnUpdate,
2095
+ autoincrement: columnAutoIncrement,
2096
+ primaryKey: columnPk,
2097
+ generated: columnGenerated,
2098
+ },
2099
+ type: 'alter_table_add_column',
2100
+ });
2101
+
2102
+ return [
2103
+ `ALTER TABLE ${tableNameWithSchema} drop column "${columnName}";`,
2104
+ addColumnStatement,
2105
+ ];
2106
+ }
2107
+ }
2108
+
2109
+ class PgAlterTableAlterColumnAlterrGeneratedConvertor extends Convertor {
2110
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2111
+ return (
2112
+ statement.type === 'alter_table_alter_column_alter_generated'
2113
+ && dialect === 'postgresql'
2114
+ );
2115
+ }
2116
+
2117
+ convert(statement: JsonAlterColumnAlterGeneratedStatement) {
2118
+ const {
2119
+ tableName,
2120
+ columnName,
2121
+ schema,
2122
+ columnNotNull: notNull,
2123
+ columnDefault,
2124
+ columnOnUpdate,
2125
+ columnAutoIncrement,
2126
+ columnPk,
2127
+ columnGenerated,
2128
+ } = statement;
2129
+
2130
+ const tableNameWithSchema = schema
2131
+ ? `"${schema}"."${tableName}"`
2132
+ : `"${tableName}"`;
2133
+
2134
+ const addColumnStatement = new PgAlterTableAddColumnConvertor().convert({
2135
+ schema,
2136
+ tableName,
2137
+ column: {
2138
+ name: columnName,
2139
+ type: statement.newDataType,
2140
+ notNull,
2141
+ default: columnDefault,
2142
+ onUpdate: columnOnUpdate,
2143
+ autoincrement: columnAutoIncrement,
2144
+ primaryKey: columnPk,
2145
+ generated: columnGenerated,
2146
+ },
2147
+ type: 'alter_table_add_column',
2148
+ });
2149
+
2150
+ return [
2151
+ `ALTER TABLE ${tableNameWithSchema} drop column "${columnName}";`,
2152
+ addColumnStatement,
2153
+ ];
2154
+ }
2155
+ }
2156
+
2157
+ ////
2158
+ class SqliteAlterTableAlterColumnDropGeneratedConvertor extends Convertor {
2159
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2160
+ return (
2161
+ statement.type === 'alter_table_alter_column_drop_generated'
2162
+ && (dialect === 'sqlite' || dialect === 'turso')
2163
+ );
2164
+ }
2165
+
2166
+ convert(statement: JsonAlterColumnDropGeneratedStatement) {
2167
+ const {
2168
+ tableName,
2169
+ columnName,
2170
+ schema,
2171
+ columnDefault,
2172
+ columnOnUpdate,
2173
+ columnAutoIncrement,
2174
+ columnPk,
2175
+ columnGenerated,
2176
+ columnNotNull,
2177
+ } = statement;
2178
+
2179
+ const addColumnStatement = new SQLiteAlterTableAddColumnConvertor().convert(
2180
+ {
2181
+ tableName,
2182
+ column: {
2183
+ name: columnName,
2184
+ type: statement.newDataType,
2185
+ notNull: columnNotNull,
2186
+ default: columnDefault,
2187
+ onUpdate: columnOnUpdate,
2188
+ autoincrement: columnAutoIncrement,
2189
+ primaryKey: columnPk,
2190
+ generated: columnGenerated,
2191
+ },
2192
+ type: 'sqlite_alter_table_add_column',
2193
+ },
2194
+ );
2195
+
2196
+ const dropColumnStatement = new SQLiteAlterTableDropColumnConvertor().convert({
2197
+ tableName,
2198
+ columnName,
2199
+ schema,
2200
+ type: 'alter_table_drop_column',
2201
+ });
2202
+
2203
+ return [dropColumnStatement, addColumnStatement];
2204
+ }
2205
+ }
2206
+
2207
+ class SqliteAlterTableAlterColumnSetExpressionConvertor extends Convertor {
2208
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2209
+ return (
2210
+ statement.type === 'alter_table_alter_column_set_generated'
2211
+ && (dialect === 'sqlite' || dialect === 'turso')
2212
+ );
2213
+ }
2214
+
2215
+ convert(statement: JsonAlterColumnSetGeneratedStatement) {
2216
+ const {
2217
+ tableName,
2218
+ columnName,
2219
+ schema,
2220
+ columnNotNull: notNull,
2221
+ columnDefault,
2222
+ columnOnUpdate,
2223
+ columnAutoIncrement,
2224
+ columnPk,
2225
+ columnGenerated,
2226
+ } = statement;
2227
+
2228
+ const addColumnStatement = new SQLiteAlterTableAddColumnConvertor().convert(
2229
+ {
2230
+ tableName,
2231
+ column: {
2232
+ name: columnName,
2233
+ type: statement.newDataType,
2234
+ notNull,
2235
+ default: columnDefault,
2236
+ onUpdate: columnOnUpdate,
2237
+ autoincrement: columnAutoIncrement,
2238
+ primaryKey: columnPk,
2239
+ generated: columnGenerated,
2240
+ },
2241
+ type: 'sqlite_alter_table_add_column',
2242
+ },
2243
+ );
2244
+
2245
+ const dropColumnStatement = new SQLiteAlterTableDropColumnConvertor().convert({
2246
+ tableName,
2247
+ columnName,
2248
+ schema,
2249
+ type: 'alter_table_drop_column',
2250
+ });
2251
+
2252
+ return [dropColumnStatement, addColumnStatement];
2253
+ }
2254
+ }
2255
+
2256
+ class SqliteAlterTableAlterColumnAlterGeneratedConvertor extends Convertor {
2257
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2258
+ return (
2259
+ statement.type === 'alter_table_alter_column_alter_generated'
2260
+ && (dialect === 'sqlite' || dialect === 'turso')
2261
+ );
2262
+ }
2263
+
2264
+ convert(statement: JsonAlterColumnAlterGeneratedStatement) {
2265
+ const {
2266
+ tableName,
2267
+ columnName,
2268
+ schema,
2269
+ columnNotNull,
2270
+ columnDefault,
2271
+ columnOnUpdate,
2272
+ columnAutoIncrement,
2273
+ columnPk,
2274
+ columnGenerated,
2275
+ } = statement;
2276
+
2277
+ const addColumnStatement = new SQLiteAlterTableAddColumnConvertor().convert(
2278
+ {
2279
+ tableName,
2280
+ column: {
2281
+ name: columnName,
2282
+ type: statement.newDataType,
2283
+ notNull: columnNotNull,
2284
+ default: columnDefault,
2285
+ onUpdate: columnOnUpdate,
2286
+ autoincrement: columnAutoIncrement,
2287
+ primaryKey: columnPk,
2288
+ generated: columnGenerated,
2289
+ },
2290
+ type: 'sqlite_alter_table_add_column',
2291
+ },
2292
+ );
2293
+
2294
+ const dropColumnStatement = new SQLiteAlterTableDropColumnConvertor().convert({
2295
+ tableName,
2296
+ columnName,
2297
+ schema,
2298
+ type: 'alter_table_drop_column',
2299
+ });
2300
+
2301
+ return [dropColumnStatement, addColumnStatement];
2302
+ }
2303
+ }
2304
+
2305
+ ////
2306
+
2307
+ class MySqlAlterTableAlterColumnAlterrGeneratedConvertor extends Convertor {
2308
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2309
+ return (
2310
+ statement.type === 'alter_table_alter_column_alter_generated'
2311
+ && dialect === 'mysql'
2312
+ );
2313
+ }
2314
+
2315
+ convert(statement: JsonAlterColumnAlterGeneratedStatement) {
2316
+ const {
2317
+ tableName,
2318
+ columnName,
2319
+ schema,
2320
+ columnNotNull: notNull,
2321
+ columnDefault,
2322
+ columnOnUpdate,
2323
+ columnAutoIncrement,
2324
+ columnPk,
2325
+ columnGenerated,
2326
+ } = statement;
2327
+
2328
+ const tableNameWithSchema = schema
2329
+ ? `\`${schema}\`.\`${tableName}\``
2330
+ : `\`${tableName}\``;
2331
+
2332
+ const addColumnStatement = new MySqlAlterTableAddColumnConvertor().convert({
2333
+ schema,
2334
+ tableName,
2335
+ column: {
2336
+ name: columnName,
2337
+ type: statement.newDataType,
2338
+ notNull,
2339
+ default: columnDefault,
2340
+ onUpdate: columnOnUpdate,
2341
+ autoincrement: columnAutoIncrement,
2342
+ primaryKey: columnPk,
2343
+ generated: columnGenerated,
2344
+ },
2345
+ type: 'alter_table_add_column',
2346
+ });
2347
+
2348
+ return [
2349
+ `ALTER TABLE ${tableNameWithSchema} drop column \`${columnName}\`;`,
2350
+ addColumnStatement,
2351
+ ];
2352
+ }
2353
+ }
2354
+
2355
+ class MySqlAlterTableAlterColumnSetDefaultConvertor extends Convertor {
2356
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2357
+ return (
2358
+ statement.type === 'alter_table_alter_column_set_default'
2359
+ && dialect === 'mysql'
2360
+ );
2361
+ }
2362
+
2363
+ convert(statement: JsonAlterColumnSetDefaultStatement) {
2364
+ const { tableName, columnName } = statement;
2365
+ return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${columnName}\` SET DEFAULT ${statement.newDefaultValue};`;
2366
+ }
2367
+ }
2368
+
2369
+ class MySqlAlterTableAlterColumnDropDefaultConvertor extends Convertor {
2370
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2371
+ return (
2372
+ statement.type === 'alter_table_alter_column_drop_default'
2373
+ && dialect === 'mysql'
2374
+ );
2375
+ }
2376
+
2377
+ convert(statement: JsonAlterColumnDropDefaultStatement) {
2378
+ const { tableName, columnName } = statement;
2379
+ return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${columnName}\` DROP DEFAULT;`;
2380
+ }
2381
+ }
2382
+
2383
+ class MySqlAlterTableAddPk extends Convertor {
2384
+ can(statement: JsonStatement, dialect: string): boolean {
2385
+ return (
2386
+ statement.type === 'alter_table_alter_column_set_pk'
2387
+ && dialect === 'mysql'
2388
+ );
2389
+ }
2390
+ convert(statement: JsonAlterColumnSetPrimaryKeyStatement): string {
2391
+ return `ALTER TABLE \`${statement.tableName}\` ADD PRIMARY KEY (\`${statement.columnName}\`);`;
2392
+ }
2393
+ }
2394
+
2395
+ class MySqlAlterTableDropPk extends Convertor {
2396
+ can(statement: JsonStatement, dialect: string): boolean {
2397
+ return (
2398
+ statement.type === 'alter_table_alter_column_drop_pk'
2399
+ && dialect === 'mysql'
2400
+ );
2401
+ }
2402
+ convert(statement: JsonAlterColumnDropPrimaryKeyStatement): string {
2403
+ return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY`;
2404
+ }
2405
+ }
2406
+
2407
+ type LibSQLModifyColumnStatement =
2408
+ | JsonAlterColumnTypeStatement
2409
+ | JsonAlterColumnDropNotNullStatement
2410
+ | JsonAlterColumnSetNotNullStatement
2411
+ | JsonAlterColumnSetDefaultStatement
2412
+ | JsonAlterColumnDropDefaultStatement;
2413
+
2414
+ export class LibSQLModifyColumn extends Convertor {
2415
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2416
+ return (
2417
+ (statement.type === 'alter_table_alter_column_set_type'
2418
+ || statement.type === 'alter_table_alter_column_drop_notnull'
2419
+ || statement.type === 'alter_table_alter_column_set_notnull'
2420
+ || statement.type === 'alter_table_alter_column_set_default'
2421
+ || statement.type === 'alter_table_alter_column_drop_default'
2422
+ || statement.type === 'create_check_constraint'
2423
+ || statement.type === 'delete_check_constraint')
2424
+ && dialect === 'turso'
2425
+ );
2426
+ }
2427
+
2428
+ convert(statement: LibSQLModifyColumnStatement, json2: SQLiteSchemaSquashed) {
2429
+ const { tableName, columnName } = statement;
2430
+
2431
+ let columnType = ``;
2432
+ let columnDefault: any = '';
2433
+ let columnNotNull = '';
2434
+
2435
+ const sqlStatements: string[] = [];
2436
+
2437
+ // collect index info
2438
+ const indexes: {
2439
+ name: string;
2440
+ tableName: string;
2441
+ columns: string[];
2442
+ isUnique: boolean;
2443
+ where?: string | undefined;
2444
+ }[] = [];
2445
+ for (const table of Object.values(json2.tables)) {
2446
+ for (const index of Object.values(table.indexes)) {
2447
+ const unsquashed = SQLiteSquasher.unsquashIdx(index);
2448
+ sqlStatements.push(`DROP INDEX "${unsquashed.name}";`);
2449
+ indexes.push({ ...unsquashed, tableName: table.name });
2450
+ }
2451
+ }
2452
+
2453
+ switch (statement.type) {
2454
+ case 'alter_table_alter_column_set_type':
2455
+ columnType = ` ${statement.newDataType}`;
2456
+
2457
+ columnDefault = statement.columnDefault
2458
+ ? ` DEFAULT ${statement.columnDefault}`
2459
+ : '';
2460
+
2461
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2462
+
2463
+ break;
2464
+ case 'alter_table_alter_column_drop_notnull':
2465
+ columnType = ` ${statement.newDataType}`;
2466
+
2467
+ columnDefault = statement.columnDefault
2468
+ ? ` DEFAULT ${statement.columnDefault}`
2469
+ : '';
2470
+
2471
+ columnNotNull = '';
2472
+ break;
2473
+ case 'alter_table_alter_column_set_notnull':
2474
+ columnType = ` ${statement.newDataType}`;
2475
+
2476
+ columnDefault = statement.columnDefault
2477
+ ? ` DEFAULT ${statement.columnDefault}`
2478
+ : '';
2479
+
2480
+ columnNotNull = ` NOT NULL`;
2481
+ break;
2482
+ case 'alter_table_alter_column_set_default':
2483
+ columnType = ` ${statement.newDataType}`;
2484
+
2485
+ columnDefault = ` DEFAULT ${statement.newDefaultValue}`;
2486
+
2487
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2488
+ break;
2489
+ case 'alter_table_alter_column_drop_default':
2490
+ columnType = ` ${statement.newDataType}`;
2491
+
2492
+ columnDefault = '';
2493
+
2494
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2495
+ break;
2496
+ }
2497
+
2498
+ // Seems like getting value from simple json2 shanpshot makes dates be dates
2499
+ columnDefault = columnDefault instanceof Date
2500
+ ? columnDefault.toISOString()
2501
+ : columnDefault;
2502
+
2503
+ sqlStatements.push(
2504
+ `ALTER TABLE \`${tableName}\` ALTER COLUMN "${columnName}" TO "${columnName}"${columnType}${columnNotNull}${columnDefault};`,
2505
+ );
2506
+
2507
+ for (const index of indexes) {
2508
+ const indexPart = index.isUnique ? 'UNIQUE INDEX' : 'INDEX';
2509
+ const whereStatement = index.where ? ` WHERE ${index.where}` : '';
2510
+ const uniqueString = index.columns.map((it) => `\`${it}\``).join(',');
2511
+ const tableName = index.tableName;
2512
+
2513
+ sqlStatements.push(
2514
+ `CREATE ${indexPart} \`${index.name}\` ON \`${tableName}\` (${uniqueString})${whereStatement};`,
2515
+ );
2516
+ }
2517
+
2518
+ return sqlStatements;
2519
+ }
2520
+ }
2521
+
2522
+ type MySqlModifyColumnStatement =
2523
+ | JsonAlterColumnDropNotNullStatement
2524
+ | JsonAlterColumnSetNotNullStatement
2525
+ | JsonAlterColumnTypeStatement
2526
+ | JsonAlterColumnDropOnUpdateStatement
2527
+ | JsonAlterColumnSetOnUpdateStatement
2528
+ | JsonAlterColumnDropAutoincrementStatement
2529
+ | JsonAlterColumnSetAutoincrementStatement
2530
+ | JsonAlterColumnSetDefaultStatement
2531
+ | JsonAlterColumnDropDefaultStatement
2532
+ | JsonAlterColumnSetGeneratedStatement
2533
+ | JsonAlterColumnDropGeneratedStatement;
2534
+
2535
+ class MySqlModifyColumn extends Convertor {
2536
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2537
+ return (
2538
+ (statement.type === 'alter_table_alter_column_set_type'
2539
+ || statement.type === 'alter_table_alter_column_set_notnull'
2540
+ || statement.type === 'alter_table_alter_column_drop_notnull'
2541
+ || statement.type === 'alter_table_alter_column_drop_on_update'
2542
+ || statement.type === 'alter_table_alter_column_set_on_update'
2543
+ || statement.type === 'alter_table_alter_column_set_autoincrement'
2544
+ || statement.type === 'alter_table_alter_column_drop_autoincrement'
2545
+ || statement.type === 'alter_table_alter_column_set_default'
2546
+ || statement.type === 'alter_table_alter_column_drop_default'
2547
+ || statement.type === 'alter_table_alter_column_set_generated'
2548
+ || statement.type === 'alter_table_alter_column_drop_generated')
2549
+ && dialect === 'mysql'
2550
+ );
2551
+ }
2552
+
2553
+ convert(statement: MySqlModifyColumnStatement) {
2554
+ const { tableName, columnName } = statement;
2555
+ let columnType = ``;
2556
+ let columnDefault: any = '';
2557
+ let columnNotNull = '';
2558
+ let columnOnUpdate = '';
2559
+ let columnAutoincrement = '';
2560
+ let primaryKey = statement.columnPk ? ' PRIMARY KEY' : '';
2561
+ let columnGenerated = '';
2562
+
2563
+ if (statement.type === 'alter_table_alter_column_drop_notnull') {
2564
+ columnType = ` ${statement.newDataType}`;
2565
+ columnDefault = statement.columnDefault
2566
+ ? ` DEFAULT ${statement.columnDefault}`
2567
+ : '';
2568
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2569
+ columnOnUpdate = statement.columnOnUpdate
2570
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2571
+ : '';
2572
+ columnAutoincrement = statement.columnAutoIncrement
2573
+ ? ' AUTO_INCREMENT'
2574
+ : '';
2575
+ } else if (statement.type === 'alter_table_alter_column_set_notnull') {
2576
+ columnNotNull = ` NOT NULL`;
2577
+ columnType = ` ${statement.newDataType}`;
2578
+ columnDefault = statement.columnDefault
2579
+ ? ` DEFAULT ${statement.columnDefault}`
2580
+ : '';
2581
+ columnOnUpdate = statement.columnOnUpdate
2582
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2583
+ : '';
2584
+ columnAutoincrement = statement.columnAutoIncrement
2585
+ ? ' AUTO_INCREMENT'
2586
+ : '';
2587
+ } else if (statement.type === 'alter_table_alter_column_drop_on_update') {
2588
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2589
+ columnType = ` ${statement.newDataType}`;
2590
+ columnDefault = statement.columnDefault
2591
+ ? ` DEFAULT ${statement.columnDefault}`
2592
+ : '';
2593
+ columnOnUpdate = '';
2594
+ columnAutoincrement = statement.columnAutoIncrement
2595
+ ? ' AUTO_INCREMENT'
2596
+ : '';
2597
+ } else if (statement.type === 'alter_table_alter_column_set_on_update') {
2598
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2599
+ columnOnUpdate = ` ON UPDATE CURRENT_TIMESTAMP`;
2600
+ columnType = ` ${statement.newDataType}`;
2601
+ columnDefault = statement.columnDefault
2602
+ ? ` DEFAULT ${statement.columnDefault}`
2603
+ : '';
2604
+ columnAutoincrement = statement.columnAutoIncrement
2605
+ ? ' AUTO_INCREMENT'
2606
+ : '';
2607
+ } else if (
2608
+ statement.type === 'alter_table_alter_column_set_autoincrement'
2609
+ ) {
2610
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2611
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2612
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2613
+ : '';
2614
+ columnType = ` ${statement.newDataType}`;
2615
+ columnDefault = statement.columnDefault
2616
+ ? ` DEFAULT ${statement.columnDefault}`
2617
+ : '';
2618
+ columnAutoincrement = ' AUTO_INCREMENT';
2619
+ } else if (
2620
+ statement.type === 'alter_table_alter_column_drop_autoincrement'
2621
+ ) {
2622
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2623
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2624
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2625
+ : '';
2626
+ columnType = ` ${statement.newDataType}`;
2627
+ columnDefault = statement.columnDefault
2628
+ ? ` DEFAULT ${statement.columnDefault}`
2629
+ : '';
2630
+ columnAutoincrement = '';
2631
+ } else if (statement.type === 'alter_table_alter_column_set_default') {
2632
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2633
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2634
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2635
+ : '';
2636
+ columnType = ` ${statement.newDataType}`;
2637
+ columnDefault = ` DEFAULT ${statement.newDefaultValue}`;
2638
+ columnAutoincrement = statement.columnAutoIncrement
2639
+ ? ' AUTO_INCREMENT'
2640
+ : '';
2641
+ } else if (statement.type === 'alter_table_alter_column_drop_default') {
2642
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2643
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2644
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2645
+ : '';
2646
+ columnType = ` ${statement.newDataType}`;
2647
+ columnDefault = '';
2648
+ columnAutoincrement = statement.columnAutoIncrement
2649
+ ? ' AUTO_INCREMENT'
2650
+ : '';
2651
+ } else if (statement.type === 'alter_table_alter_column_set_generated') {
2652
+ columnType = ` ${statement.newDataType}`;
2653
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2654
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2655
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2656
+ : '';
2657
+ columnDefault = statement.columnDefault
2658
+ ? ` DEFAULT ${statement.columnDefault}`
2659
+ : '';
2660
+ columnAutoincrement = statement.columnAutoIncrement
2661
+ ? ' AUTO_INCREMENT'
2662
+ : '';
2663
+
2664
+ if (statement.columnGenerated?.type === 'virtual') {
2665
+ return [
2666
+ new MySqlAlterTableDropColumnConvertor().convert({
2667
+ type: 'alter_table_drop_column',
2668
+ tableName: statement.tableName,
2669
+ columnName: statement.columnName,
2670
+ schema: statement.schema,
2671
+ }),
2672
+ new MySqlAlterTableAddColumnConvertor().convert({
2673
+ tableName,
2674
+ column: {
2675
+ name: columnName,
2676
+ type: statement.newDataType,
2677
+ notNull: statement.columnNotNull,
2678
+ default: statement.columnDefault,
2679
+ onUpdate: statement.columnOnUpdate,
2680
+ autoincrement: statement.columnAutoIncrement,
2681
+ primaryKey: statement.columnPk,
2682
+ generated: statement.columnGenerated,
2683
+ },
2684
+ schema: statement.schema,
2685
+ type: 'alter_table_add_column',
2686
+ }),
2687
+ ];
2688
+ } else {
2689
+ columnGenerated = statement.columnGenerated
2690
+ ? ` GENERATED ALWAYS AS (${statement.columnGenerated?.as}) ${statement.columnGenerated?.type.toUpperCase()}`
2691
+ : '';
2692
+ }
2693
+ } else if (statement.type === 'alter_table_alter_column_drop_generated') {
2694
+ columnType = ` ${statement.newDataType}`;
2695
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2696
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2697
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2698
+ : '';
2699
+ columnDefault = statement.columnDefault
2700
+ ? ` DEFAULT ${statement.columnDefault}`
2701
+ : '';
2702
+ columnAutoincrement = statement.columnAutoIncrement
2703
+ ? ' AUTO_INCREMENT'
2704
+ : '';
2705
+
2706
+ if (statement.oldColumn?.generated?.type === 'virtual') {
2707
+ return [
2708
+ new MySqlAlterTableDropColumnConvertor().convert({
2709
+ type: 'alter_table_drop_column',
2710
+ tableName: statement.tableName,
2711
+ columnName: statement.columnName,
2712
+ schema: statement.schema,
2713
+ }),
2714
+ new MySqlAlterTableAddColumnConvertor().convert({
2715
+ tableName,
2716
+ column: {
2717
+ name: columnName,
2718
+ type: statement.newDataType,
2719
+ notNull: statement.columnNotNull,
2720
+ default: statement.columnDefault,
2721
+ onUpdate: statement.columnOnUpdate,
2722
+ autoincrement: statement.columnAutoIncrement,
2723
+ primaryKey: statement.columnPk,
2724
+ generated: statement.columnGenerated,
2725
+ },
2726
+ schema: statement.schema,
2727
+ type: 'alter_table_add_column',
2728
+ }),
2729
+ ];
2730
+ }
2731
+ } else {
2732
+ columnType = ` ${statement.newDataType}`;
2733
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2734
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2735
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2736
+ : '';
2737
+ columnDefault = statement.columnDefault
2738
+ ? ` DEFAULT ${statement.columnDefault}`
2739
+ : '';
2740
+ columnAutoincrement = statement.columnAutoIncrement
2741
+ ? ' AUTO_INCREMENT'
2742
+ : '';
2743
+ columnGenerated = statement.columnGenerated
2744
+ ? ` GENERATED ALWAYS AS (${statement.columnGenerated?.as}) ${statement.columnGenerated?.type.toUpperCase()}`
2745
+ : '';
2746
+ }
2747
+
2748
+ // Seems like getting value from simple json2 shanpshot makes dates be dates
2749
+ columnDefault = columnDefault instanceof Date
2750
+ ? columnDefault.toISOString()
2751
+ : columnDefault;
2752
+
2753
+ return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${columnName}\`${columnType}${columnAutoincrement}${columnGenerated}${columnNotNull}${columnDefault}${columnOnUpdate};`;
2754
+ }
2755
+ }
2756
+
2757
+ class SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor extends Convertor {
2758
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2759
+ return (
2760
+ statement.type === 'alter_table_alter_column_alter_generated'
2761
+ && dialect === 'singlestore'
2762
+ );
2763
+ }
2764
+
2765
+ convert(statement: JsonAlterColumnAlterGeneratedStatement) {
2766
+ const {
2767
+ tableName,
2768
+ columnName,
2769
+ schema,
2770
+ columnNotNull: notNull,
2771
+ columnDefault,
2772
+ columnOnUpdate,
2773
+ columnAutoIncrement,
2774
+ columnPk,
2775
+ columnGenerated,
2776
+ } = statement;
2777
+
2778
+ const tableNameWithSchema = schema
2779
+ ? `\`${schema}\`.\`${tableName}\``
2780
+ : `\`${tableName}\``;
2781
+
2782
+ const addColumnStatement = new SingleStoreAlterTableAddColumnConvertor().convert({
2783
+ schema,
2784
+ tableName,
2785
+ column: {
2786
+ name: columnName,
2787
+ type: statement.newDataType,
2788
+ notNull,
2789
+ default: columnDefault,
2790
+ onUpdate: columnOnUpdate,
2791
+ autoincrement: columnAutoIncrement,
2792
+ primaryKey: columnPk,
2793
+ generated: columnGenerated,
2794
+ },
2795
+ type: 'alter_table_add_column',
2796
+ });
2797
+
2798
+ return [
2799
+ `ALTER TABLE ${tableNameWithSchema} drop column \`${columnName}\`;`,
2800
+ addColumnStatement,
2801
+ ];
2802
+ }
2803
+ }
2804
+
2805
+ class SingleStoreAlterTableAlterColumnSetDefaultConvertor extends Convertor {
2806
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2807
+ return (
2808
+ statement.type === 'alter_table_alter_column_set_default'
2809
+ && dialect === 'singlestore'
2810
+ );
2811
+ }
2812
+
2813
+ convert(statement: JsonAlterColumnSetDefaultStatement) {
2814
+ const { tableName, columnName } = statement;
2815
+ return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${columnName}\` SET DEFAULT ${statement.newDefaultValue};`;
2816
+ }
2817
+ }
2818
+
2819
+ class SingleStoreAlterTableAlterColumnDropDefaultConvertor extends Convertor {
2820
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2821
+ return (
2822
+ statement.type === 'alter_table_alter_column_drop_default'
2823
+ && dialect === 'singlestore'
2824
+ );
2825
+ }
2826
+
2827
+ convert(statement: JsonAlterColumnDropDefaultStatement) {
2828
+ const { tableName, columnName } = statement;
2829
+ return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${columnName}\` DROP DEFAULT;`;
2830
+ }
2831
+ }
2832
+
2833
+ class SingleStoreAlterTableAddPk extends Convertor {
2834
+ can(statement: JsonStatement, dialect: string): boolean {
2835
+ return (
2836
+ statement.type === 'alter_table_alter_column_set_pk'
2837
+ && dialect === 'singlestore'
2838
+ );
2839
+ }
2840
+ convert(statement: JsonAlterColumnSetPrimaryKeyStatement): string {
2841
+ return `ALTER TABLE \`${statement.tableName}\` ADD PRIMARY KEY (\`${statement.columnName}\`);`;
2842
+ }
2843
+ }
2844
+
2845
+ class SingleStoreAlterTableDropPk extends Convertor {
2846
+ can(statement: JsonStatement, dialect: string): boolean {
2847
+ return (
2848
+ statement.type === 'alter_table_alter_column_drop_pk'
2849
+ && dialect === 'singlestore'
2850
+ );
2851
+ }
2852
+ convert(statement: JsonAlterColumnDropPrimaryKeyStatement): string {
2853
+ return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY`;
2854
+ }
2855
+ }
2856
+
2857
+ type SingleStoreModifyColumnStatement =
2858
+ | JsonAlterColumnDropNotNullStatement
2859
+ | JsonAlterColumnSetNotNullStatement
2860
+ | JsonAlterColumnTypeStatement
2861
+ | JsonAlterColumnDropOnUpdateStatement
2862
+ | JsonAlterColumnSetOnUpdateStatement
2863
+ | JsonAlterColumnDropAutoincrementStatement
2864
+ | JsonAlterColumnSetAutoincrementStatement
2865
+ | JsonAlterColumnSetDefaultStatement
2866
+ | JsonAlterColumnDropDefaultStatement
2867
+ | JsonAlterColumnSetGeneratedStatement
2868
+ | JsonAlterColumnDropGeneratedStatement;
2869
+
2870
+ class SingleStoreModifyColumn extends Convertor {
2871
+ can(statement: JsonStatement, dialect: Dialect): boolean {
2872
+ return (
2873
+ (statement.type === 'alter_table_alter_column_set_type'
2874
+ || statement.type === 'alter_table_alter_column_set_notnull'
2875
+ || statement.type === 'alter_table_alter_column_drop_notnull'
2876
+ || statement.type === 'alter_table_alter_column_drop_on_update'
2877
+ || statement.type === 'alter_table_alter_column_set_on_update'
2878
+ || statement.type === 'alter_table_alter_column_set_autoincrement'
2879
+ || statement.type === 'alter_table_alter_column_drop_autoincrement'
2880
+ || statement.type === 'alter_table_alter_column_set_default'
2881
+ || statement.type === 'alter_table_alter_column_drop_default'
2882
+ || statement.type === 'alter_table_alter_column_set_generated'
2883
+ || statement.type === 'alter_table_alter_column_drop_generated')
2884
+ && dialect === 'singlestore'
2885
+ );
2886
+ }
2887
+
2888
+ convert(statement: SingleStoreModifyColumnStatement) {
2889
+ const { tableName, columnName } = statement;
2890
+ let columnType = ``;
2891
+ let columnDefault: any = '';
2892
+ let columnNotNull = '';
2893
+ let columnOnUpdate = '';
2894
+ let columnAutoincrement = '';
2895
+ let primaryKey = statement.columnPk ? ' PRIMARY KEY' : '';
2896
+ let columnGenerated = '';
2897
+
2898
+ if (statement.type === 'alter_table_alter_column_drop_notnull') {
2899
+ columnType = ` ${statement.newDataType}`;
2900
+ columnDefault = statement.columnDefault
2901
+ ? ` DEFAULT ${statement.columnDefault}`
2902
+ : '';
2903
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2904
+ columnOnUpdate = statement.columnOnUpdate
2905
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2906
+ : '';
2907
+ columnAutoincrement = statement.columnAutoIncrement
2908
+ ? ' AUTO_INCREMENT'
2909
+ : '';
2910
+ } else if (statement.type === 'alter_table_alter_column_set_notnull') {
2911
+ columnNotNull = ` NOT NULL`;
2912
+ columnType = ` ${statement.newDataType}`;
2913
+ columnDefault = statement.columnDefault
2914
+ ? ` DEFAULT ${statement.columnDefault}`
2915
+ : '';
2916
+ columnOnUpdate = statement.columnOnUpdate
2917
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2918
+ : '';
2919
+ columnAutoincrement = statement.columnAutoIncrement
2920
+ ? ' AUTO_INCREMENT'
2921
+ : '';
2922
+ } else if (statement.type === 'alter_table_alter_column_drop_on_update') {
2923
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2924
+ columnType = ` ${statement.newDataType}`;
2925
+ columnDefault = statement.columnDefault
2926
+ ? ` DEFAULT ${statement.columnDefault}`
2927
+ : '';
2928
+ columnOnUpdate = '';
2929
+ columnAutoincrement = statement.columnAutoIncrement
2930
+ ? ' AUTO_INCREMENT'
2931
+ : '';
2932
+ } else if (statement.type === 'alter_table_alter_column_set_on_update') {
2933
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2934
+ columnOnUpdate = ` ON UPDATE CURRENT_TIMESTAMP`;
2935
+ columnType = ` ${statement.newDataType}`;
2936
+ columnDefault = statement.columnDefault
2937
+ ? ` DEFAULT ${statement.columnDefault}`
2938
+ : '';
2939
+ columnAutoincrement = statement.columnAutoIncrement
2940
+ ? ' AUTO_INCREMENT'
2941
+ : '';
2942
+ } else if (
2943
+ statement.type === 'alter_table_alter_column_set_autoincrement'
2944
+ ) {
2945
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2946
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2947
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2948
+ : '';
2949
+ columnType = ` ${statement.newDataType}`;
2950
+ columnDefault = statement.columnDefault
2951
+ ? ` DEFAULT ${statement.columnDefault}`
2952
+ : '';
2953
+ columnAutoincrement = ' AUTO_INCREMENT';
2954
+ } else if (
2955
+ statement.type === 'alter_table_alter_column_drop_autoincrement'
2956
+ ) {
2957
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2958
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2959
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2960
+ : '';
2961
+ columnType = ` ${statement.newDataType}`;
2962
+ columnDefault = statement.columnDefault
2963
+ ? ` DEFAULT ${statement.columnDefault}`
2964
+ : '';
2965
+ columnAutoincrement = '';
2966
+ } else if (statement.type === 'alter_table_alter_column_set_default') {
2967
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2968
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2969
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2970
+ : '';
2971
+ columnType = ` ${statement.newDataType}`;
2972
+ columnDefault = ` DEFAULT ${statement.newDefaultValue}`;
2973
+ columnAutoincrement = statement.columnAutoIncrement
2974
+ ? ' AUTO_INCREMENT'
2975
+ : '';
2976
+ } else if (statement.type === 'alter_table_alter_column_drop_default') {
2977
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2978
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2979
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2980
+ : '';
2981
+ columnType = ` ${statement.newDataType}`;
2982
+ columnDefault = '';
2983
+ columnAutoincrement = statement.columnAutoIncrement
2984
+ ? ' AUTO_INCREMENT'
2985
+ : '';
2986
+ } else if (statement.type === 'alter_table_alter_column_set_generated') {
2987
+ columnType = ` ${statement.newDataType}`;
2988
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
2989
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
2990
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
2991
+ : '';
2992
+ columnDefault = statement.columnDefault
2993
+ ? ` DEFAULT ${statement.columnDefault}`
2994
+ : '';
2995
+ columnAutoincrement = statement.columnAutoIncrement
2996
+ ? ' AUTO_INCREMENT'
2997
+ : '';
2998
+
2999
+ if (statement.columnGenerated?.type === 'virtual') {
3000
+ return [
3001
+ new SingleStoreAlterTableDropColumnConvertor().convert({
3002
+ type: 'alter_table_drop_column',
3003
+ tableName: statement.tableName,
3004
+ columnName: statement.columnName,
3005
+ schema: statement.schema,
3006
+ }),
3007
+ new SingleStoreAlterTableAddColumnConvertor().convert({
3008
+ tableName,
3009
+ column: {
3010
+ name: columnName,
3011
+ type: statement.newDataType,
3012
+ notNull: statement.columnNotNull,
3013
+ default: statement.columnDefault,
3014
+ onUpdate: statement.columnOnUpdate,
3015
+ autoincrement: statement.columnAutoIncrement,
3016
+ primaryKey: statement.columnPk,
3017
+ generated: statement.columnGenerated,
3018
+ },
3019
+ schema: statement.schema,
3020
+ type: 'alter_table_add_column',
3021
+ }),
3022
+ ];
3023
+ } else {
3024
+ columnGenerated = statement.columnGenerated
3025
+ ? ` GENERATED ALWAYS AS (${statement.columnGenerated?.as}) ${statement.columnGenerated?.type.toUpperCase()}`
3026
+ : '';
3027
+ }
3028
+ } else if (statement.type === 'alter_table_alter_column_drop_generated') {
3029
+ columnType = ` ${statement.newDataType}`;
3030
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
3031
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
3032
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
3033
+ : '';
3034
+ columnDefault = statement.columnDefault
3035
+ ? ` DEFAULT ${statement.columnDefault}`
3036
+ : '';
3037
+ columnAutoincrement = statement.columnAutoIncrement
3038
+ ? ' AUTO_INCREMENT'
3039
+ : '';
3040
+
3041
+ if (statement.oldColumn?.generated?.type === 'virtual') {
3042
+ return [
3043
+ new SingleStoreAlterTableDropColumnConvertor().convert({
3044
+ type: 'alter_table_drop_column',
3045
+ tableName: statement.tableName,
3046
+ columnName: statement.columnName,
3047
+ schema: statement.schema,
3048
+ }),
3049
+ new SingleStoreAlterTableAddColumnConvertor().convert({
3050
+ tableName,
3051
+ column: {
3052
+ name: columnName,
3053
+ type: statement.newDataType,
3054
+ notNull: statement.columnNotNull,
3055
+ default: statement.columnDefault,
3056
+ onUpdate: statement.columnOnUpdate,
3057
+ autoincrement: statement.columnAutoIncrement,
3058
+ primaryKey: statement.columnPk,
3059
+ generated: statement.columnGenerated,
3060
+ },
3061
+ schema: statement.schema,
3062
+ type: 'alter_table_add_column',
3063
+ }),
3064
+ ];
3065
+ }
3066
+ } else {
3067
+ columnType = ` ${statement.newDataType}`;
3068
+ columnNotNull = statement.columnNotNull ? ` NOT NULL` : '';
3069
+ columnOnUpdate = columnOnUpdate = statement.columnOnUpdate
3070
+ ? ` ON UPDATE CURRENT_TIMESTAMP`
3071
+ : '';
3072
+ columnDefault = statement.columnDefault
3073
+ ? ` DEFAULT ${statement.columnDefault}`
3074
+ : '';
3075
+ columnAutoincrement = statement.columnAutoIncrement
3076
+ ? ' AUTO_INCREMENT'
3077
+ : '';
3078
+ columnGenerated = statement.columnGenerated
3079
+ ? ` GENERATED ALWAYS AS (${statement.columnGenerated?.as}) ${statement.columnGenerated?.type.toUpperCase()}`
3080
+ : '';
3081
+ }
3082
+
3083
+ // Seems like getting value from simple json2 shanpshot makes dates be dates
3084
+ columnDefault = columnDefault instanceof Date
3085
+ ? columnDefault.toISOString()
3086
+ : columnDefault;
3087
+
3088
+ return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${columnName}\`${columnType}${columnAutoincrement}${columnNotNull}${columnDefault}${columnOnUpdate}${columnGenerated};`;
3089
+ }
3090
+ }
3091
+ class SqliteAlterTableAlterColumnDropDefaultConvertor extends Convertor {
3092
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3093
+ return (
3094
+ statement.type === 'alter_table_alter_column_drop_default'
3095
+ && dialect === 'sqlite'
3096
+ );
3097
+ }
3098
+
3099
+ convert(statement: JsonAlterColumnDropDefaultStatement) {
3100
+ return (
3101
+ '/*\n SQLite does not support "Drop default from column" out of the box, we do not generate automatic migration for that, so it has to be done manually'
3102
+ + '\n Please refer to: https://www.techonthenet.com/sqlite/tables/alter_table.php'
3103
+ + '\n https://www.sqlite.org/lang_altertable.html'
3104
+ + '\n https://stackoverflow.com/questions/2083543/modify-a-columns-type-in-sqlite3'
3105
+ + "\n\n Due to that we don't generate migration automatically and it has to be done manually"
3106
+ + '\n*/'
3107
+ );
3108
+ }
3109
+ }
3110
+
3111
+ class PgAlterTableCreateCompositePrimaryKeyConvertor extends Convertor {
3112
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3113
+ return statement.type === 'create_composite_pk' && dialect === 'postgresql';
3114
+ }
3115
+
3116
+ convert(statement: JsonCreateCompositePK) {
3117
+ const { name, columns } = PgSquasher.unsquashPK(statement.data);
3118
+
3119
+ const tableNameWithSchema = statement.schema
3120
+ ? `"${statement.schema}"."${statement.tableName}"`
3121
+ : `"${statement.tableName}"`;
3122
+
3123
+ return `ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.constraintName}" PRIMARY KEY("${
3124
+ columns.join('","')
3125
+ }");`;
3126
+ }
3127
+ }
3128
+ class PgAlterTableDeleteCompositePrimaryKeyConvertor extends Convertor {
3129
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3130
+ return statement.type === 'delete_composite_pk' && dialect === 'postgresql';
3131
+ }
3132
+
3133
+ convert(statement: JsonDeleteCompositePK) {
3134
+ const { name, columns } = PgSquasher.unsquashPK(statement.data);
3135
+
3136
+ const tableNameWithSchema = statement.schema
3137
+ ? `"${statement.schema}"."${statement.tableName}"`
3138
+ : `"${statement.tableName}"`;
3139
+
3140
+ return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${statement.constraintName}";`;
3141
+ }
3142
+ }
3143
+
3144
+ class PgAlterTableAlterCompositePrimaryKeyConvertor extends Convertor {
3145
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3146
+ return statement.type === 'alter_composite_pk' && dialect === 'postgresql';
3147
+ }
3148
+
3149
+ convert(statement: JsonAlterCompositePK) {
3150
+ const { name, columns } = PgSquasher.unsquashPK(statement.old);
3151
+ const { name: newName, columns: newColumns } = PgSquasher.unsquashPK(
3152
+ statement.new,
3153
+ );
3154
+
3155
+ const tableNameWithSchema = statement.schema
3156
+ ? `"${statement.schema}"."${statement.tableName}"`
3157
+ : `"${statement.tableName}"`;
3158
+
3159
+ return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${statement.oldConstraintName}";\n${BREAKPOINT}ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.newConstraintName}" PRIMARY KEY("${
3160
+ newColumns.join('","')
3161
+ }");`;
3162
+ }
3163
+ }
3164
+
3165
+ class MySqlAlterTableCreateCompositePrimaryKeyConvertor extends Convertor {
3166
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3167
+ return statement.type === 'create_composite_pk' && dialect === 'mysql';
3168
+ }
3169
+
3170
+ convert(statement: JsonCreateCompositePK) {
3171
+ const { name, columns } = MySqlSquasher.unsquashPK(statement.data);
3172
+ return `ALTER TABLE \`${statement.tableName}\` ADD PRIMARY KEY(\`${columns.join('`,`')}\`);`;
3173
+ }
3174
+ }
3175
+
3176
+ class MySqlAlterTableDeleteCompositePrimaryKeyConvertor extends Convertor {
3177
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3178
+ return statement.type === 'delete_composite_pk' && dialect === 'mysql';
3179
+ }
3180
+
3181
+ convert(statement: JsonDeleteCompositePK) {
3182
+ const { name, columns } = MySqlSquasher.unsquashPK(statement.data);
3183
+ return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY;`;
3184
+ }
3185
+ }
3186
+
3187
+ class MySqlAlterTableAlterCompositePrimaryKeyConvertor extends Convertor {
3188
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3189
+ return statement.type === 'alter_composite_pk' && dialect === 'mysql';
3190
+ }
3191
+
3192
+ convert(statement: JsonAlterCompositePK) {
3193
+ const { name, columns } = MySqlSquasher.unsquashPK(statement.old);
3194
+ const { name: newName, columns: newColumns } = MySqlSquasher.unsquashPK(
3195
+ statement.new,
3196
+ );
3197
+ return `ALTER TABLE \`${statement.tableName}\` DROP PRIMARY KEY, ADD PRIMARY KEY(\`${newColumns.join('`,`')}\`);`;
3198
+ }
3199
+ }
3200
+
3201
+ class SqliteAlterTableCreateCompositePrimaryKeyConvertor extends Convertor {
3202
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3203
+ return statement.type === 'create_composite_pk' && dialect === 'sqlite';
3204
+ }
3205
+
3206
+ convert(statement: JsonCreateCompositePK) {
3207
+ let msg = '/*\n';
3208
+ msg += `You're trying to add PRIMARY KEY(${statement.data}) to '${statement.tableName}' table\n`;
3209
+ msg += 'SQLite does not support adding primary key to an already created table\n';
3210
+ msg += 'You can do it in 3 steps with drizzle orm:\n';
3211
+ msg += ' - create new mirror table with needed pk, rename current table to old_table, generate SQL\n';
3212
+ msg += ' - migrate old data from one table to another\n';
3213
+ msg += ' - delete old_table in schema, generate sql\n\n';
3214
+ msg += 'or create manual migration like below:\n\n';
3215
+ msg += 'ALTER TABLE table_name RENAME TO old_table;\n';
3216
+ msg += 'CREATE TABLE table_name (\n';
3217
+ msg += '\tcolumn1 datatype [ NULL | NOT NULL ],\n';
3218
+ msg += '\tcolumn2 datatype [ NULL | NOT NULL ],\n';
3219
+ msg += '\t...\n';
3220
+ msg += '\tPRIMARY KEY (pk_col1, pk_col2, ... pk_col_n)\n';
3221
+ msg += ' );\n';
3222
+ msg += 'INSERT INTO table_name SELECT * FROM old_table;\n\n';
3223
+ msg += "Due to that we don't generate migration automatically and it has to be done manually\n";
3224
+ msg += '*/\n';
3225
+ return msg;
3226
+ }
3227
+ }
3228
+ class SqliteAlterTableDeleteCompositePrimaryKeyConvertor extends Convertor {
3229
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3230
+ return statement.type === 'delete_composite_pk' && dialect === 'sqlite';
3231
+ }
3232
+
3233
+ convert(statement: JsonDeleteCompositePK) {
3234
+ let msg = '/*\n';
3235
+ msg += `You're trying to delete PRIMARY KEY(${statement.data}) from '${statement.tableName}' table\n`;
3236
+ msg += 'SQLite does not supportprimary key deletion from existing table\n';
3237
+ msg += 'You can do it in 3 steps with drizzle orm:\n';
3238
+ msg += ' - create new mirror table table without pk, rename current table to old_table, generate SQL\n';
3239
+ msg += ' - migrate old data from one table to another\n';
3240
+ msg += ' - delete old_table in schema, generate sql\n\n';
3241
+ msg += 'or create manual migration like below:\n\n';
3242
+ msg += 'ALTER TABLE table_name RENAME TO old_table;\n';
3243
+ msg += 'CREATE TABLE table_name (\n';
3244
+ msg += '\tcolumn1 datatype [ NULL | NOT NULL ],\n';
3245
+ msg += '\tcolumn2 datatype [ NULL | NOT NULL ],\n';
3246
+ msg += '\t...\n';
3247
+ msg += '\tPRIMARY KEY (pk_col1, pk_col2, ... pk_col_n)\n';
3248
+ msg += ' );\n';
3249
+ msg += 'INSERT INTO table_name SELECT * FROM old_table;\n\n';
3250
+ msg += "Due to that we don't generate migration automatically and it has to be done manually\n";
3251
+ msg += '*/\n';
3252
+ return msg;
3253
+ }
3254
+ }
3255
+
3256
+ class SqliteAlterTableAlterCompositePrimaryKeyConvertor extends Convertor {
3257
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3258
+ return statement.type === 'alter_composite_pk' && dialect === 'sqlite';
3259
+ }
3260
+
3261
+ convert(statement: JsonAlterCompositePK) {
3262
+ let msg = '/*\n';
3263
+ msg += 'SQLite does not support altering primary key\n';
3264
+ msg += 'You can do it in 3 steps with drizzle orm:\n';
3265
+ msg += ' - create new mirror table with needed pk, rename current table to old_table, generate SQL\n';
3266
+ msg += ' - migrate old data from one table to another\n';
3267
+ msg += ' - delete old_table in schema, generate sql\n\n';
3268
+ msg += 'or create manual migration like below:\n\n';
3269
+ msg += 'ALTER TABLE table_name RENAME TO old_table;\n';
3270
+ msg += 'CREATE TABLE table_name (\n';
3271
+ msg += '\tcolumn1 datatype [ NULL | NOT NULL ],\n';
3272
+ msg += '\tcolumn2 datatype [ NULL | NOT NULL ],\n';
3273
+ msg += '\t...\n';
3274
+ msg += '\tPRIMARY KEY (pk_col1, pk_col2, ... pk_col_n)\n';
3275
+ msg += ' );\n';
3276
+ msg += 'INSERT INTO table_name SELECT * FROM old_table;\n\n';
3277
+ msg += "Due to that we don't generate migration automatically and it has to be done manually\n";
3278
+ msg += '*/\n';
3279
+
3280
+ return msg;
3281
+ }
3282
+ }
3283
+
3284
+ class PgAlterTableAlterColumnSetPrimaryKeyConvertor extends Convertor {
3285
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3286
+ return (
3287
+ statement.type === 'alter_table_alter_column_set_pk'
3288
+ && dialect === 'postgresql'
3289
+ );
3290
+ }
3291
+
3292
+ convert(statement: JsonAlterColumnSetPrimaryKeyStatement) {
3293
+ const { tableName, columnName } = statement;
3294
+
3295
+ const tableNameWithSchema = statement.schema
3296
+ ? `"${statement.schema}"."${statement.tableName}"`
3297
+ : `"${statement.tableName}"`;
3298
+
3299
+ return `ALTER TABLE ${tableNameWithSchema} ADD PRIMARY KEY ("${columnName}");`;
3300
+ }
3301
+ }
3302
+
3303
+ class PgAlterTableAlterColumnDropPrimaryKeyConvertor extends Convertor {
3304
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3305
+ return (
3306
+ statement.type === 'alter_table_alter_column_drop_pk'
3307
+ && dialect === 'postgresql'
3308
+ );
3309
+ }
3310
+
3311
+ convert(statement: JsonAlterColumnDropPrimaryKeyStatement) {
3312
+ const { tableName, columnName, schema } = statement;
3313
+ return `/*
3314
+ Unfortunately in current drizzle-kit version we can't automatically get name for primary key.
3315
+ We are working on making it available!
3316
+
3317
+ Meanwhile you can:
3318
+ 1. Check pk name in your database, by running
3319
+ SELECT constraint_name FROM information_schema.table_constraints
3320
+ WHERE table_schema = '${typeof schema === 'undefined' || schema === '' ? 'public' : schema}'
3321
+ AND table_name = '${tableName}'
3322
+ AND constraint_type = 'PRIMARY KEY';
3323
+ 2. Uncomment code below and paste pk name manually
3324
+
3325
+ Hope to release this update as soon as possible
3326
+ */
3327
+
3328
+ -- ALTER TABLE "${tableName}" DROP CONSTRAINT "<constraint_name>";`;
3329
+ }
3330
+ }
3331
+
3332
+ class PgAlterTableAlterColumnSetNotNullConvertor extends Convertor {
3333
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3334
+ return (
3335
+ statement.type === 'alter_table_alter_column_set_notnull'
3336
+ && dialect === 'postgresql'
3337
+ );
3338
+ }
3339
+
3340
+ convert(statement: JsonAlterColumnSetNotNullStatement) {
3341
+ const { tableName, columnName } = statement;
3342
+
3343
+ const tableNameWithSchema = statement.schema
3344
+ ? `"${statement.schema}"."${statement.tableName}"`
3345
+ : `"${statement.tableName}"`;
3346
+
3347
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" SET NOT NULL;`;
3348
+ }
3349
+ }
3350
+
3351
+ class PgAlterTableAlterColumnDropNotNullConvertor extends Convertor {
3352
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3353
+ return (
3354
+ statement.type === 'alter_table_alter_column_drop_notnull'
3355
+ && dialect === 'postgresql'
3356
+ );
3357
+ }
3358
+
3359
+ convert(statement: JsonAlterColumnDropNotNullStatement) {
3360
+ const { tableName, columnName } = statement;
3361
+
3362
+ const tableNameWithSchema = statement.schema
3363
+ ? `"${statement.schema}"."${statement.tableName}"`
3364
+ : `"${statement.tableName}"`;
3365
+
3366
+ return `ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${columnName}" DROP NOT NULL;`;
3367
+ }
3368
+ }
3369
+
3370
+ // FK
3371
+ class PgCreateForeignKeyConvertor extends Convertor {
3372
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3373
+ return statement.type === 'create_reference' && dialect === 'postgresql';
3374
+ }
3375
+
3376
+ convert(statement: JsonCreateReferenceStatement): string {
3377
+ const {
3378
+ name,
3379
+ tableFrom,
3380
+ tableTo,
3381
+ columnsFrom,
3382
+ columnsTo,
3383
+ onDelete,
3384
+ onUpdate,
3385
+ schemaTo,
3386
+ } = PgSquasher.unsquashFK(statement.data);
3387
+ const onDeleteStatement = onDelete ? ` ON DELETE ${onDelete}` : '';
3388
+ const onUpdateStatement = onUpdate ? ` ON UPDATE ${onUpdate}` : '';
3389
+ const fromColumnsString = columnsFrom.map((it) => `"${it}"`).join(',');
3390
+ const toColumnsString = columnsTo.map((it) => `"${it}"`).join(',');
3391
+
3392
+ const tableNameWithSchema = statement.schema
3393
+ ? `"${statement.schema}"."${tableFrom}"`
3394
+ : `"${tableFrom}"`;
3395
+
3396
+ const tableToNameWithSchema = schemaTo
3397
+ ? `"${schemaTo}"."${tableTo}"`
3398
+ : `"${tableTo}"`;
3399
+
3400
+ const alterStatement =
3401
+ `ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${name}" FOREIGN KEY (${fromColumnsString}) REFERENCES ${tableToNameWithSchema}(${toColumnsString})${onDeleteStatement}${onUpdateStatement};`;
3402
+
3403
+ return alterStatement;
3404
+ }
3405
+ }
3406
+
3407
+ class LibSQLCreateForeignKeyConvertor extends Convertor {
3408
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3409
+ return (
3410
+ statement.type === 'create_reference'
3411
+ && dialect === 'turso'
3412
+ );
3413
+ }
3414
+
3415
+ convert(
3416
+ statement: JsonCreateReferenceStatement,
3417
+ json2?: SQLiteSchemaSquashed,
3418
+ action?: 'push',
3419
+ ): string {
3420
+ const { columnsFrom, columnsTo, tableFrom, onDelete, onUpdate, tableTo } = action === 'push'
3421
+ ? SQLiteSquasher.unsquashPushFK(statement.data)
3422
+ : SQLiteSquasher.unsquashFK(statement.data);
3423
+ const { columnDefault, columnNotNull, columnType } = statement;
3424
+
3425
+ const onDeleteStatement = onDelete ? ` ON DELETE ${onDelete}` : '';
3426
+ const onUpdateStatement = onUpdate ? ` ON UPDATE ${onUpdate}` : '';
3427
+ const columnsDefaultValue = columnDefault
3428
+ ? ` DEFAULT ${columnDefault}`
3429
+ : '';
3430
+ const columnNotNullValue = columnNotNull ? ` NOT NULL` : '';
3431
+ const columnTypeValue = columnType ? ` ${columnType}` : '';
3432
+
3433
+ const columnFrom = columnsFrom[0];
3434
+ const columnTo = columnsTo[0];
3435
+
3436
+ return `ALTER TABLE \`${tableFrom}\` ALTER COLUMN "${columnFrom}" TO "${columnFrom}"${columnTypeValue}${columnNotNullValue}${columnsDefaultValue} REFERENCES ${tableTo}(${columnTo})${onDeleteStatement}${onUpdateStatement};`;
3437
+ }
3438
+ }
3439
+
3440
+ class MySqlCreateForeignKeyConvertor extends Convertor {
3441
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3442
+ return statement.type === 'create_reference' && dialect === 'mysql';
3443
+ }
3444
+
3445
+ convert(statement: JsonCreateReferenceStatement): string {
3446
+ const {
3447
+ name,
3448
+ tableFrom,
3449
+ tableTo,
3450
+ columnsFrom,
3451
+ columnsTo,
3452
+ onDelete,
3453
+ onUpdate,
3454
+ } = MySqlSquasher.unsquashFK(statement.data);
3455
+ const onDeleteStatement = onDelete ? ` ON DELETE ${onDelete}` : '';
3456
+ const onUpdateStatement = onUpdate ? ` ON UPDATE ${onUpdate}` : '';
3457
+ const fromColumnsString = columnsFrom.map((it) => `\`${it}\``).join(',');
3458
+ const toColumnsString = columnsTo.map((it) => `\`${it}\``).join(',');
3459
+
3460
+ return `ALTER TABLE \`${tableFrom}\` ADD CONSTRAINT \`${name}\` FOREIGN KEY (${fromColumnsString}) REFERENCES \`${tableTo}\`(${toColumnsString})${onDeleteStatement}${onUpdateStatement};`;
3461
+ }
3462
+ }
3463
+
3464
+ class PgAlterForeignKeyConvertor extends Convertor {
3465
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3466
+ return statement.type === 'alter_reference' && dialect === 'postgresql';
3467
+ }
3468
+
3469
+ convert(statement: JsonAlterReferenceStatement): string {
3470
+ const newFk = PgSquasher.unsquashFK(statement.data);
3471
+ const oldFk = PgSquasher.unsquashFK(statement.oldFkey);
3472
+
3473
+ const tableNameWithSchema = statement.schema
3474
+ ? `"${statement.schema}"."${oldFk.tableFrom}"`
3475
+ : `"${oldFk.tableFrom}"`;
3476
+
3477
+ let sql = `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${oldFk.name}";\n`;
3478
+
3479
+ const onDeleteStatement = newFk.onDelete
3480
+ ? ` ON DELETE ${newFk.onDelete}`
3481
+ : '';
3482
+ const onUpdateStatement = newFk.onUpdate
3483
+ ? ` ON UPDATE ${newFk.onUpdate}`
3484
+ : '';
3485
+
3486
+ const fromColumnsString = newFk.columnsFrom
3487
+ .map((it) => `"${it}"`)
3488
+ .join(',');
3489
+ const toColumnsString = newFk.columnsTo.map((it) => `"${it}"`).join(',');
3490
+
3491
+ const tableFromNameWithSchema = oldFk.schemaTo
3492
+ ? `"${oldFk.schemaTo}"."${oldFk.tableFrom}"`
3493
+ : `"${oldFk.tableFrom}"`;
3494
+
3495
+ const tableToNameWithSchema = newFk.schemaTo
3496
+ ? `"${newFk.schemaTo}"."${newFk.tableFrom}"`
3497
+ : `"${newFk.tableFrom}"`;
3498
+
3499
+ const alterStatement =
3500
+ `ALTER TABLE ${tableFromNameWithSchema} ADD CONSTRAINT "${newFk.name}" FOREIGN KEY (${fromColumnsString}) REFERENCES ${tableToNameWithSchema}(${toColumnsString})${onDeleteStatement}${onUpdateStatement};`;
3501
+
3502
+ sql += alterStatement;
3503
+ return sql;
3504
+ }
3505
+ }
3506
+
3507
+ class PgDeleteForeignKeyConvertor extends Convertor {
3508
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3509
+ return statement.type === 'delete_reference' && dialect === 'postgresql';
3510
+ }
3511
+
3512
+ convert(statement: JsonDeleteReferenceStatement): string {
3513
+ const tableFrom = statement.tableName; // delete fk from renamed table case
3514
+ const { name } = PgSquasher.unsquashFK(statement.data);
3515
+
3516
+ const tableNameWithSchema = statement.schema
3517
+ ? `"${statement.schema}"."${tableFrom}"`
3518
+ : `"${tableFrom}"`;
3519
+
3520
+ return `ALTER TABLE ${tableNameWithSchema} DROP CONSTRAINT "${name}";\n`;
3521
+ }
3522
+ }
3523
+
3524
+ class MySqlDeleteForeignKeyConvertor extends Convertor {
3525
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3526
+ return statement.type === 'delete_reference' && dialect === 'mysql';
3527
+ }
3528
+
3529
+ convert(statement: JsonDeleteReferenceStatement): string {
3530
+ const tableFrom = statement.tableName; // delete fk from renamed table case
3531
+ const { name } = MySqlSquasher.unsquashFK(statement.data);
3532
+ return `ALTER TABLE \`${tableFrom}\` DROP FOREIGN KEY \`${name}\`;\n`;
3533
+ }
3534
+ }
3535
+
3536
+ class CreatePgIndexConvertor extends Convertor {
3537
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3538
+ return statement.type === 'create_index_pg' && dialect === 'postgresql';
3539
+ }
3540
+
3541
+ convert(statement: JsonPgCreateIndexStatement): string {
3542
+ const {
3543
+ name,
3544
+ columns,
3545
+ isUnique,
3546
+ concurrently,
3547
+ with: withMap,
3548
+ method,
3549
+ where,
3550
+ } = statement.data;
3551
+ // // since postgresql 9.5
3552
+ const indexPart = isUnique ? 'UNIQUE INDEX' : 'INDEX';
3553
+ const value = columns
3554
+ .map(
3555
+ (it) =>
3556
+ `${it.isExpression ? it.expression : `"${it.expression}"`}${
3557
+ it.opclass ? ` ${it.opclass}` : it.asc ? '' : ' DESC'
3558
+ }${
3559
+ (it.asc && it.nulls && it.nulls === 'last') || it.opclass
3560
+ ? ''
3561
+ : ` NULLS ${it.nulls!.toUpperCase()}`
3562
+ }`,
3563
+ )
3564
+ .join(',');
3565
+
3566
+ const tableNameWithSchema = statement.schema
3567
+ ? `"${statement.schema}"."${statement.tableName}"`
3568
+ : `"${statement.tableName}"`;
3569
+
3570
+ function reverseLogic(mappedWith: Record<string, string>): string {
3571
+ let reversedString = '';
3572
+ for (const key in mappedWith) {
3573
+ if (mappedWith.hasOwnProperty(key)) {
3574
+ reversedString += `${key}=${mappedWith[key]},`;
3575
+ }
3576
+ }
3577
+ reversedString = reversedString.slice(0, -1);
3578
+ return reversedString;
3579
+ }
3580
+
3581
+ return `CREATE ${indexPart}${
3582
+ concurrently ? ' CONCURRENTLY' : ''
3583
+ } "${name}" ON ${tableNameWithSchema} USING ${method} (${value})${
3584
+ Object.keys(withMap!).length !== 0
3585
+ ? ` WITH (${reverseLogic(withMap!)})`
3586
+ : ''
3587
+ }${where ? ` WHERE ${where}` : ''};`;
3588
+ }
3589
+ }
3590
+
3591
+ class CreateMySqlIndexConvertor extends Convertor {
3592
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3593
+ return statement.type === 'create_index' && dialect === 'mysql';
3594
+ }
3595
+
3596
+ convert(statement: JsonCreateIndexStatement): string {
3597
+ // should be changed
3598
+ const { name, columns, isUnique } = MySqlSquasher.unsquashIdx(
3599
+ statement.data,
3600
+ );
3601
+ const indexPart = isUnique ? 'UNIQUE INDEX' : 'INDEX';
3602
+
3603
+ const uniqueString = columns
3604
+ .map((it) => {
3605
+ return statement.internal?.indexes
3606
+ ? statement.internal?.indexes[name]?.columns[it]?.isExpression
3607
+ ? it
3608
+ : `\`${it}\``
3609
+ : `\`${it}\``;
3610
+ })
3611
+ .join(',');
3612
+
3613
+ return `CREATE ${indexPart} \`${name}\` ON \`${statement.tableName}\` (${uniqueString});`;
3614
+ }
3615
+ }
3616
+
3617
+ export class CreateSingleStoreIndexConvertor extends Convertor {
3618
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3619
+ return statement.type === 'create_index' && dialect === 'singlestore';
3620
+ }
3621
+
3622
+ convert(statement: JsonCreateIndexStatement): string {
3623
+ // should be changed
3624
+ const { name, columns, isUnique } = SingleStoreSquasher.unsquashIdx(
3625
+ statement.data,
3626
+ );
3627
+ const indexPart = isUnique ? 'UNIQUE INDEX' : 'INDEX';
3628
+
3629
+ const uniqueString = columns
3630
+ .map((it) => {
3631
+ return statement.internal?.indexes
3632
+ ? statement.internal?.indexes[name]?.columns[it]?.isExpression
3633
+ ? it
3634
+ : `\`${it}\``
3635
+ : `\`${it}\``;
3636
+ })
3637
+ .join(',');
3638
+
3639
+ return `CREATE ${indexPart} \`${name}\` ON \`${statement.tableName}\` (${uniqueString});`;
3640
+ }
3641
+ }
3642
+
3643
+ export class CreateSqliteIndexConvertor extends Convertor {
3644
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3645
+ return statement.type === 'create_index' && (dialect === 'sqlite' || dialect === 'turso');
3646
+ }
3647
+
3648
+ convert(statement: JsonCreateIndexStatement): string {
3649
+ // should be changed
3650
+ const { name, columns, isUnique, where } = SQLiteSquasher.unsquashIdx(
3651
+ statement.data,
3652
+ );
3653
+ // // since postgresql 9.5
3654
+ const indexPart = isUnique ? 'UNIQUE INDEX' : 'INDEX';
3655
+ const whereStatement = where ? ` WHERE ${where}` : '';
3656
+ const uniqueString = columns
3657
+ .map((it) => {
3658
+ return statement.internal?.indexes
3659
+ ? statement.internal?.indexes[name]?.columns[it]?.isExpression
3660
+ ? it
3661
+ : `\`${it}\``
3662
+ : `\`${it}\``;
3663
+ })
3664
+ .join(',');
3665
+ return `CREATE ${indexPart} \`${name}\` ON \`${statement.tableName}\` (${uniqueString})${whereStatement};`;
3666
+ }
3667
+ }
3668
+
3669
+ class PgDropIndexConvertor extends Convertor {
3670
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3671
+ return statement.type === 'drop_index' && dialect === 'postgresql';
3672
+ }
3673
+
3674
+ convert(statement: JsonDropIndexStatement): string {
3675
+ const { schema } = statement;
3676
+ const { name } = PgSquasher.unsquashIdx(statement.data);
3677
+
3678
+ const indexNameWithSchema = schema ? `"${schema}"."${name}"` : `"${name}"`;
3679
+
3680
+ return `DROP INDEX ${indexNameWithSchema};`;
3681
+ }
3682
+ }
3683
+
3684
+ class PgCreateSchemaConvertor extends Convertor {
3685
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3686
+ return statement.type === 'create_schema' && dialect === 'postgresql';
3687
+ }
3688
+
3689
+ convert(statement: JsonCreateSchema) {
3690
+ const { name } = statement;
3691
+ return `CREATE SCHEMA "${name}";\n`;
3692
+ }
3693
+ }
3694
+
3695
+ class PgRenameSchemaConvertor extends Convertor {
3696
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3697
+ return statement.type === 'rename_schema' && dialect === 'postgresql';
3698
+ }
3699
+
3700
+ convert(statement: JsonRenameSchema) {
3701
+ const { from, to } = statement;
3702
+ return `ALTER SCHEMA "${from}" RENAME TO "${to}";\n`;
3703
+ }
3704
+ }
3705
+
3706
+ class PgDropSchemaConvertor extends Convertor {
3707
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3708
+ return statement.type === 'drop_schema' && dialect === 'postgresql';
3709
+ }
3710
+
3711
+ convert(statement: JsonCreateSchema) {
3712
+ const { name } = statement;
3713
+ return `DROP SCHEMA "${name}";\n`;
3714
+ }
3715
+ }
3716
+
3717
+ class PgAlterTableSetSchemaConvertor extends Convertor {
3718
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3719
+ return (
3720
+ statement.type === 'alter_table_set_schema' && dialect === 'postgresql'
3721
+ );
3722
+ }
3723
+
3724
+ convert(statement: JsonAlterTableSetSchema) {
3725
+ const { tableName, schemaFrom, schemaTo } = statement;
3726
+
3727
+ return `ALTER TABLE "${schemaFrom}"."${tableName}" SET SCHEMA "${schemaTo}";\n`;
3728
+ }
3729
+ }
3730
+
3731
+ class PgAlterTableSetNewSchemaConvertor extends Convertor {
3732
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3733
+ return (
3734
+ statement.type === 'alter_table_set_new_schema'
3735
+ && dialect === 'postgresql'
3736
+ );
3737
+ }
3738
+
3739
+ convert(statement: JsonAlterTableSetNewSchema) {
3740
+ const { tableName, to, from } = statement;
3741
+
3742
+ const tableNameWithSchema = from
3743
+ ? `"${from}"."${tableName}"`
3744
+ : `"${tableName}"`;
3745
+
3746
+ return `ALTER TABLE ${tableNameWithSchema} SET SCHEMA "${to}";\n`;
3747
+ }
3748
+ }
3749
+
3750
+ class PgAlterTableRemoveFromSchemaConvertor extends Convertor {
3751
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3752
+ return (
3753
+ statement.type === 'alter_table_remove_from_schema'
3754
+ && dialect === 'postgresql'
3755
+ );
3756
+ }
3757
+
3758
+ convert(statement: JsonAlterTableRemoveFromSchema) {
3759
+ const { tableName, schema } = statement;
3760
+
3761
+ const tableNameWithSchema = schema
3762
+ ? `"${schema}"."${tableName}"`
3763
+ : `"${tableName}"`;
3764
+
3765
+ return `ALTER TABLE ${tableNameWithSchema} SET SCHEMA public;\n`;
3766
+ }
3767
+ }
3768
+
3769
+ export class SqliteDropIndexConvertor extends Convertor {
3770
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3771
+ return statement.type === 'drop_index' && (dialect === 'sqlite' || dialect === 'turso');
3772
+ }
3773
+
3774
+ convert(statement: JsonDropIndexStatement): string {
3775
+ const { name } = PgSquasher.unsquashIdx(statement.data);
3776
+ return `DROP INDEX \`${name}\`;`;
3777
+ }
3778
+ }
3779
+
3780
+ class MySqlDropIndexConvertor extends Convertor {
3781
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3782
+ return statement.type === 'drop_index' && dialect === 'mysql';
3783
+ }
3784
+
3785
+ convert(statement: JsonDropIndexStatement): string {
3786
+ const { name } = MySqlSquasher.unsquashIdx(statement.data);
3787
+ return `DROP INDEX \`${name}\` ON \`${statement.tableName}\`;`;
3788
+ }
3789
+ }
3790
+
3791
+ class SingleStoreDropIndexConvertor extends Convertor {
3792
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3793
+ return statement.type === 'drop_index' && dialect === 'singlestore';
3794
+ }
3795
+
3796
+ convert(statement: JsonDropIndexStatement): string {
3797
+ const { name } = SingleStoreSquasher.unsquashIdx(statement.data);
3798
+ return `DROP INDEX \`${name}\` ON \`${statement.tableName}\`;`;
3799
+ }
3800
+ }
3801
+
3802
+ class SQLiteRecreateTableConvertor extends Convertor {
3803
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3804
+ return (
3805
+ statement.type === 'recreate_table' && dialect === 'sqlite'
3806
+ );
3807
+ }
3808
+
3809
+ convert(statement: JsonRecreateTableStatement): string | string[] {
3810
+ const { tableName, columns, compositePKs, referenceData, checkConstraints } = statement;
3811
+
3812
+ const columnNames = columns.map((it) => `"${it.name}"`).join(', ');
3813
+ const newTableName = `__new_${tableName}`;
3814
+
3815
+ const sqlStatements: string[] = [];
3816
+
3817
+ sqlStatements.push(`PRAGMA foreign_keys=OFF;`);
3818
+
3819
+ // map all possible variants
3820
+ const mappedCheckConstraints: string[] = checkConstraints.map((it) =>
3821
+ it.replaceAll(`"${tableName}".`, `"${newTableName}".`).replaceAll(`\`${tableName}\`.`, `\`${newTableName}\`.`)
3822
+ .replaceAll(`${tableName}.`, `${newTableName}.`).replaceAll(`'${tableName}'.`, `'${newTableName}'.`)
3823
+ );
3824
+
3825
+ // create new table
3826
+ sqlStatements.push(
3827
+ new SQLiteCreateTableConvertor().convert({
3828
+ type: 'sqlite_create_table',
3829
+ tableName: newTableName,
3830
+ columns,
3831
+ referenceData,
3832
+ compositePKs,
3833
+ checkConstraints: mappedCheckConstraints,
3834
+ }),
3835
+ );
3836
+
3837
+ // migrate data
3838
+ sqlStatements.push(
3839
+ `INSERT INTO \`${newTableName}\`(${columnNames}) SELECT ${columnNames} FROM \`${tableName}\`;`,
3840
+ );
3841
+
3842
+ // drop table
3843
+ sqlStatements.push(
3844
+ new SQLiteDropTableConvertor().convert({
3845
+ type: 'drop_table',
3846
+ tableName: tableName,
3847
+ schema: '',
3848
+ }),
3849
+ );
3850
+
3851
+ // rename table
3852
+ sqlStatements.push(
3853
+ new SqliteRenameTableConvertor().convert({
3854
+ fromSchema: '',
3855
+ tableNameFrom: newTableName,
3856
+ tableNameTo: tableName,
3857
+ toSchema: '',
3858
+ type: 'rename_table',
3859
+ }),
3860
+ );
3861
+
3862
+ sqlStatements.push(`PRAGMA foreign_keys=ON;`);
3863
+
3864
+ return sqlStatements;
3865
+ }
3866
+ }
3867
+
3868
+ class LibSQLRecreateTableConvertor extends Convertor {
3869
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3870
+ return (
3871
+ statement.type === 'recreate_table'
3872
+ && dialect === 'turso'
3873
+ );
3874
+ }
3875
+
3876
+ convert(statement: JsonRecreateTableStatement): string[] {
3877
+ const { tableName, columns, compositePKs, referenceData, checkConstraints } = statement;
3878
+
3879
+ const columnNames = columns.map((it) => `"${it.name}"`).join(', ');
3880
+ const newTableName = `__new_${tableName}`;
3881
+
3882
+ const sqlStatements: string[] = [];
3883
+
3884
+ const mappedCheckConstraints: string[] = checkConstraints.map((it) =>
3885
+ it.replaceAll(`"${tableName}".`, `"${newTableName}".`).replaceAll(`\`${tableName}\`.`, `\`${newTableName}\`.`)
3886
+ .replaceAll(`${tableName}.`, `${newTableName}.`).replaceAll(`'${tableName}'.`, `\`${newTableName}\`.`)
3887
+ );
3888
+
3889
+ sqlStatements.push(`PRAGMA foreign_keys=OFF;`);
3890
+
3891
+ // create new table
3892
+ sqlStatements.push(
3893
+ new SQLiteCreateTableConvertor().convert({
3894
+ type: 'sqlite_create_table',
3895
+ tableName: newTableName,
3896
+ columns,
3897
+ referenceData,
3898
+ compositePKs,
3899
+ checkConstraints: mappedCheckConstraints,
3900
+ }),
3901
+ );
3902
+
3903
+ // migrate data
3904
+ sqlStatements.push(
3905
+ `INSERT INTO \`${newTableName}\`(${columnNames}) SELECT ${columnNames} FROM \`${tableName}\`;`,
3906
+ );
3907
+
3908
+ // drop table
3909
+ sqlStatements.push(
3910
+ new SQLiteDropTableConvertor().convert({
3911
+ type: 'drop_table',
3912
+ tableName: tableName,
3913
+ schema: '',
3914
+ }),
3915
+ );
3916
+
3917
+ // rename table
3918
+ sqlStatements.push(
3919
+ new SqliteRenameTableConvertor().convert({
3920
+ fromSchema: '',
3921
+ tableNameFrom: newTableName,
3922
+ tableNameTo: tableName,
3923
+ toSchema: '',
3924
+ type: 'rename_table',
3925
+ }),
3926
+ );
3927
+
3928
+ sqlStatements.push(`PRAGMA foreign_keys=ON;`);
3929
+
3930
+ return sqlStatements;
3931
+ }
3932
+ }
3933
+
3934
+ class SingleStoreRecreateTableConvertor extends Convertor {
3935
+ can(statement: JsonStatement, dialect: Dialect): boolean {
3936
+ return (
3937
+ statement.type === 'singlestore_recreate_table'
3938
+ && dialect === 'singlestore'
3939
+ );
3940
+ }
3941
+
3942
+ convert(statement: JsonRecreateSingleStoreTableStatement): string[] {
3943
+ const { tableName, columns, compositePKs, uniqueConstraints } = statement;
3944
+
3945
+ const columnNames = columns.map((it) => `\`${it.name}\``).join(', ');
3946
+ const newTableName = `__new_${tableName}`;
3947
+
3948
+ const sqlStatements: string[] = [];
3949
+
3950
+ // create new table
3951
+ sqlStatements.push(
3952
+ new SingleStoreCreateTableConvertor().convert({
3953
+ type: 'create_table',
3954
+ tableName: newTableName,
3955
+ columns,
3956
+ compositePKs,
3957
+ uniqueConstraints,
3958
+ schema: '',
3959
+ }),
3960
+ );
3961
+
3962
+ // migrate data
3963
+ sqlStatements.push(
3964
+ `INSERT INTO \`${newTableName}\`(${columnNames}) SELECT ${columnNames} FROM \`${tableName}\`;`,
3965
+ );
3966
+
3967
+ // drop table
3968
+ sqlStatements.push(
3969
+ new SingleStoreDropTableConvertor().convert({
3970
+ type: 'drop_table',
3971
+ tableName: tableName,
3972
+ schema: '',
3973
+ }),
3974
+ );
3975
+
3976
+ // rename table
3977
+ sqlStatements.push(
3978
+ new SingleStoreRenameTableConvertor().convert({
3979
+ fromSchema: '',
3980
+ tableNameFrom: newTableName,
3981
+ tableNameTo: tableName,
3982
+ toSchema: '',
3983
+ type: 'rename_table',
3984
+ }),
3985
+ );
3986
+
3987
+ return sqlStatements;
3988
+ }
3989
+ }
3990
+
3991
+ const convertors: Convertor[] = [];
3992
+ convertors.push(new PgCreateTableConvertor());
3993
+ convertors.push(new MySqlCreateTableConvertor());
3994
+ convertors.push(new SingleStoreCreateTableConvertor());
3995
+ convertors.push(new SingleStoreRecreateTableConvertor());
3996
+ convertors.push(new SQLiteCreateTableConvertor());
3997
+ convertors.push(new SQLiteRecreateTableConvertor());
3998
+ convertors.push(new LibSQLRecreateTableConvertor());
3999
+
4000
+ convertors.push(new PgCreateViewConvertor());
4001
+ convertors.push(new PgDropViewConvertor());
4002
+ convertors.push(new PgRenameViewConvertor());
4003
+ convertors.push(new PgAlterViewSchemaConvertor());
4004
+ convertors.push(new PgAlterViewAddWithOptionConvertor());
4005
+ convertors.push(new PgAlterViewDropWithOptionConvertor());
4006
+ convertors.push(new PgAlterViewAlterTablespaceConvertor());
4007
+ convertors.push(new PgAlterViewAlterUsingConvertor());
4008
+
4009
+ convertors.push(new MySqlCreateViewConvertor());
4010
+ convertors.push(new MySqlDropViewConvertor());
4011
+ convertors.push(new MySqlRenameViewConvertor());
4012
+ convertors.push(new MySqlAlterViewConvertor());
4013
+
4014
+ convertors.push(new SqliteCreateViewConvertor());
4015
+ convertors.push(new SqliteDropViewConvertor());
4016
+
4017
+ convertors.push(new CreateDomainConvertor());
4018
+ convertors.push(new DropDomainConvertor());
4019
+ convertors.push(new AlterDomainConvertor());
4020
+
4021
+ convertors.push(new CreateTypeEnumConvertor());
4022
+ convertors.push(new DropTypeEnumConvertor());
4023
+ convertors.push(new AlterTypeAddValueConvertor());
4024
+ convertors.push(new AlterTypeSetSchemaConvertor());
4025
+ convertors.push(new AlterRenameTypeConvertor());
4026
+ convertors.push(new AlterTypeDropValueConvertor());
4027
+
4028
+ convertors.push(new CreatePgSequenceConvertor());
4029
+ convertors.push(new DropPgSequenceConvertor());
4030
+ convertors.push(new RenamePgSequenceConvertor());
4031
+ convertors.push(new MovePgSequenceConvertor());
4032
+ convertors.push(new AlterPgSequenceConvertor());
4033
+
4034
+ convertors.push(new PgDropTableConvertor());
4035
+ convertors.push(new MySQLDropTableConvertor());
4036
+ convertors.push(new SingleStoreDropTableConvertor());
4037
+ convertors.push(new SQLiteDropTableConvertor());
4038
+
4039
+ convertors.push(new PgRenameTableConvertor());
4040
+ convertors.push(new MySqlRenameTableConvertor());
4041
+ convertors.push(new SingleStoreRenameTableConvertor());
4042
+ convertors.push(new SqliteRenameTableConvertor());
4043
+
4044
+ convertors.push(new PgAlterTableRenameColumnConvertor());
4045
+ convertors.push(new MySqlAlterTableRenameColumnConvertor());
4046
+ convertors.push(new SingleStoreAlterTableRenameColumnConvertor());
4047
+ convertors.push(new SQLiteAlterTableRenameColumnConvertor());
4048
+
4049
+ convertors.push(new PgAlterTableDropColumnConvertor());
4050
+ convertors.push(new MySqlAlterTableDropColumnConvertor());
4051
+ convertors.push(new SingleStoreAlterTableDropColumnConvertor());
4052
+ convertors.push(new SQLiteAlterTableDropColumnConvertor());
4053
+
4054
+ convertors.push(new PgAlterTableAddColumnConvertor());
4055
+ convertors.push(new MySqlAlterTableAddColumnConvertor());
4056
+ convertors.push(new SingleStoreAlterTableAddColumnConvertor());
4057
+ convertors.push(new SQLiteAlterTableAddColumnConvertor());
4058
+
4059
+ convertors.push(new PgAlterTableAlterColumnSetTypeConvertor());
4060
+
4061
+ convertors.push(new PgAlterTableAddUniqueConstraintConvertor());
4062
+ convertors.push(new PgAlterTableDropUniqueConstraintConvertor());
4063
+
4064
+ convertors.push(new PgAlterTableAddCheckConstraintConvertor());
4065
+ convertors.push(new PgAlterTableDeleteCheckConstraintConvertor());
4066
+ convertors.push(new MySqlAlterTableAddCheckConstraintConvertor());
4067
+ convertors.push(new MySqlAlterTableDeleteCheckConstraintConvertor());
4068
+
4069
+ convertors.push(new MySQLAlterTableAddUniqueConstraintConvertor());
4070
+ convertors.push(new MySQLAlterTableDropUniqueConstraintConvertor());
4071
+
4072
+ convertors.push(new SingleStoreAlterTableAddUniqueConstraintConvertor());
4073
+ convertors.push(new SingleStoreAlterTableDropUniqueConstraintConvertor());
4074
+
4075
+ convertors.push(new CreatePgIndexConvertor());
4076
+ convertors.push(new CreateMySqlIndexConvertor());
4077
+ convertors.push(new CreateSingleStoreIndexConvertor());
4078
+ convertors.push(new CreateSqliteIndexConvertor());
4079
+
4080
+ convertors.push(new PgDropIndexConvertor());
4081
+ convertors.push(new SqliteDropIndexConvertor());
4082
+ convertors.push(new MySqlDropIndexConvertor());
4083
+ convertors.push(new SingleStoreDropIndexConvertor());
4084
+
4085
+ convertors.push(new PgAlterTableAlterColumnSetPrimaryKeyConvertor());
4086
+ convertors.push(new PgAlterTableAlterColumnDropPrimaryKeyConvertor());
4087
+ convertors.push(new PgAlterTableAlterColumnSetNotNullConvertor());
4088
+ convertors.push(new PgAlterTableAlterColumnDropNotNullConvertor());
4089
+ convertors.push(new PgAlterTableAlterColumnSetDefaultConvertor());
4090
+ convertors.push(new PgAlterTableAlterColumnDropDefaultConvertor());
4091
+
4092
+ convertors.push(new PgAlterPolicyConvertor());
4093
+ convertors.push(new PgCreatePolicyConvertor());
4094
+ convertors.push(new PgDropPolicyConvertor());
4095
+ convertors.push(new PgRenamePolicyConvertor());
4096
+
4097
+ convertors.push(new PgAlterIndPolicyConvertor());
4098
+ convertors.push(new PgCreateIndPolicyConvertor());
4099
+ convertors.push(new PgDropIndPolicyConvertor());
4100
+ convertors.push(new PgRenameIndPolicyConvertor());
4101
+
4102
+ convertors.push(new PgEnableRlsConvertor());
4103
+ convertors.push(new PgDisableRlsConvertor());
4104
+
4105
+ convertors.push(new PgDropRoleConvertor());
4106
+ convertors.push(new PgAlterRoleConvertor());
4107
+ convertors.push(new PgCreateRoleConvertor());
4108
+ convertors.push(new PgRenameRoleConvertor());
4109
+
4110
+ /// generated
4111
+ convertors.push(new PgAlterTableAlterColumnSetExpressionConvertor());
4112
+ convertors.push(new PgAlterTableAlterColumnDropGeneratedConvertor());
4113
+ convertors.push(new PgAlterTableAlterColumnAlterrGeneratedConvertor());
4114
+
4115
+ convertors.push(new MySqlAlterTableAlterColumnAlterrGeneratedConvertor());
4116
+
4117
+ convertors.push(new SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor());
4118
+
4119
+ convertors.push(new SqliteAlterTableAlterColumnDropGeneratedConvertor());
4120
+ convertors.push(new SqliteAlterTableAlterColumnAlterGeneratedConvertor());
4121
+ convertors.push(new SqliteAlterTableAlterColumnSetExpressionConvertor());
4122
+
4123
+ convertors.push(new MySqlModifyColumn());
4124
+ convertors.push(new LibSQLModifyColumn());
4125
+ // convertors.push(new MySqlAlterTableAlterColumnSetDefaultConvertor());
4126
+ // convertors.push(new MySqlAlterTableAlterColumnDropDefaultConvertor());
4127
+
4128
+ convertors.push(new SingleStoreModifyColumn());
4129
+
4130
+ convertors.push(new PgCreateForeignKeyConvertor());
4131
+ convertors.push(new MySqlCreateForeignKeyConvertor());
4132
+
4133
+ convertors.push(new PgAlterForeignKeyConvertor());
4134
+
4135
+ convertors.push(new PgDeleteForeignKeyConvertor());
4136
+ convertors.push(new MySqlDeleteForeignKeyConvertor());
4137
+
4138
+ convertors.push(new PgCreateSchemaConvertor());
4139
+ convertors.push(new PgRenameSchemaConvertor());
4140
+ convertors.push(new PgDropSchemaConvertor());
4141
+ convertors.push(new PgAlterTableSetSchemaConvertor());
4142
+ convertors.push(new PgAlterTableSetNewSchemaConvertor());
4143
+ convertors.push(new PgAlterTableRemoveFromSchemaConvertor());
4144
+
4145
+ convertors.push(new LibSQLCreateForeignKeyConvertor());
4146
+
4147
+ convertors.push(new PgAlterTableAlterColumnDropGenerated());
4148
+ convertors.push(new PgAlterTableAlterColumnSetGenerated());
4149
+ convertors.push(new PgAlterTableAlterColumnAlterGenerated());
4150
+
4151
+ convertors.push(new PgAlterTableCreateCompositePrimaryKeyConvertor());
4152
+ convertors.push(new PgAlterTableDeleteCompositePrimaryKeyConvertor());
4153
+ convertors.push(new PgAlterTableAlterCompositePrimaryKeyConvertor());
4154
+
4155
+ convertors.push(new MySqlAlterTableDeleteCompositePrimaryKeyConvertor());
4156
+ convertors.push(new MySqlAlterTableDropPk());
4157
+ convertors.push(new MySqlAlterTableCreateCompositePrimaryKeyConvertor());
4158
+ convertors.push(new MySqlAlterTableAddPk());
4159
+ convertors.push(new MySqlAlterTableAlterCompositePrimaryKeyConvertor());
4160
+
4161
+ convertors.push(new SingleStoreAlterTableDropPk());
4162
+ convertors.push(new SingleStoreAlterTableAddPk());
4163
+
4164
+ export function fromJson(
4165
+ statements: JsonStatement[],
4166
+ dialect: Dialect,
4167
+ action?: 'push',
4168
+ json2?: SQLiteSchemaSquashed,
4169
+ ) {
4170
+ const result = statements
4171
+ .flatMap((statement) => {
4172
+ const filtered = convertors.filter((it) => {
4173
+ return it.can(statement, dialect);
4174
+ });
4175
+
4176
+ const convertor = filtered.length === 1 ? filtered[0] : undefined;
4177
+
4178
+ if (!convertor) {
4179
+ return '';
4180
+ }
4181
+
4182
+ return convertor.convert(statement, json2, action);
4183
+ })
4184
+ .filter((it) => it !== '');
4185
+ return result;
4186
+ }
4187
+
4188
+ // blog.yo1.dog/updating-enum-values-in-postgresql-the-safe-and-easy-way/
4189
+ // test case for enum altering
4190
+ https: `
4191
+ create table users (
4192
+ id int,
4193
+ name character varying(128)
4194
+ );
4195
+
4196
+ create type venum as enum('one', 'two', 'three');
4197
+ alter table users add column typed venum;
4198
+
4199
+ insert into users(id, name, typed) values (1, 'name1', 'one');
4200
+ insert into users(id, name, typed) values (2, 'name2', 'two');
4201
+ insert into users(id, name, typed) values (3, 'name3', 'three');
4202
+
4203
+ alter type venum rename to __venum;
4204
+ create type venum as enum ('one', 'two', 'three', 'four', 'five');
4205
+
4206
+ ALTER TABLE users ALTER COLUMN typed TYPE venum USING typed::text::venum;
4207
+
4208
+ insert into users(id, name, typed) values (4, 'name4', 'four');
4209
+ insert into users(id, name, typed) values (5, 'name5', 'five');
4210
+
4211
+ drop type __venum;
4212
+ `;