@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.
- package/.gitignore +25 -0
- package/README.md +79 -0
- package/build.dev.ts +51 -0
- package/build.ts +112 -0
- package/imports-checker/analyze.ts +78 -0
- package/imports-checker/checker.ts +296 -0
- package/imports-checker/grammar/grammar.ohm +121 -0
- package/imports-checker/grammar/grammar.ohm-bundle.d.ts +164 -0
- package/imports-checker/grammar/grammar.ohm-bundle.js +753 -0
- package/imports-checker/index.ts +48 -0
- package/package.json +142 -0
- package/patches/difflib@0.2.4.patch +31 -0
- package/src/@types/utils.ts +58 -0
- package/src/api.ts +504 -0
- package/src/cli/commands/_es5.ts +2 -0
- package/src/cli/commands/check.ts +52 -0
- package/src/cli/commands/drop.ts +60 -0
- package/src/cli/commands/introspect.ts +772 -0
- package/src/cli/commands/libSqlPushUtils.ts +355 -0
- package/src/cli/commands/migrate.ts +1526 -0
- package/src/cli/commands/mysqlIntrospect.ts +53 -0
- package/src/cli/commands/mysqlPushUtils.ts +352 -0
- package/src/cli/commands/mysqlUp.ts +102 -0
- package/src/cli/commands/pgIntrospect.ts +55 -0
- package/src/cli/commands/pgPushUtils.ts +269 -0
- package/src/cli/commands/pgUp.ts +217 -0
- package/src/cli/commands/push.ts +637 -0
- package/src/cli/commands/singlestoreIntrospect.ts +53 -0
- package/src/cli/commands/singlestorePushUtils.ts +456 -0
- package/src/cli/commands/singlestoreUp.ts +1 -0
- package/src/cli/commands/sqliteIntrospect.ts +96 -0
- package/src/cli/commands/sqlitePushUtils.ts +322 -0
- package/src/cli/commands/sqliteUp.ts +52 -0
- package/src/cli/commands/utils.ts +858 -0
- package/src/cli/connections.ts +914 -0
- package/src/cli/index.ts +48 -0
- package/src/cli/schema.ts +794 -0
- package/src/cli/selector-ui.ts +38 -0
- package/src/cli/utils.ts +112 -0
- package/src/cli/validations/cli.ts +79 -0
- package/src/cli/validations/common.ts +193 -0
- package/src/cli/validations/libsql.ts +27 -0
- package/src/cli/validations/mysql.ts +61 -0
- package/src/cli/validations/outputs.ts +91 -0
- package/src/cli/validations/postgres.ts +83 -0
- package/src/cli/validations/singlestore.ts +61 -0
- package/src/cli/validations/sqlite.ts +104 -0
- package/src/cli/validations/studio.ts +24 -0
- package/src/cli/views.ts +658 -0
- package/src/extensions/getTablesFilterByExtensions.ts +16 -0
- package/src/extensions/vector.ts +10 -0
- package/src/global.ts +61 -0
- package/src/index.ts +326 -0
- package/src/introspect-mysql.ts +1030 -0
- package/src/introspect-pg.ts +1435 -0
- package/src/introspect-singlestore.ts +913 -0
- package/src/introspect-sqlite.ts +533 -0
- package/src/jsonDiffer.js +882 -0
- package/src/jsonStatements.ts +3590 -0
- package/src/loader.mjs +57 -0
- package/src/migrationPreparator.ts +217 -0
- package/src/schemaValidator.ts +23 -0
- package/src/serializer/index.ts +142 -0
- package/src/serializer/mysqlImports.ts +38 -0
- package/src/serializer/mysqlSchema.ts +423 -0
- package/src/serializer/mysqlSerializer.ts +999 -0
- package/src/serializer/pgImports.ts +106 -0
- package/src/serializer/pgSchema.ts +937 -0
- package/src/serializer/pgSerializer.ts +2223 -0
- package/src/serializer/singlestoreImports.ts +38 -0
- package/src/serializer/singlestoreSchema.ts +257 -0
- package/src/serializer/singlestoreSerializer.ts +767 -0
- package/src/serializer/sqliteImports.ts +41 -0
- package/src/serializer/sqliteSchema.ts +352 -0
- package/src/serializer/sqliteSerializer.ts +931 -0
- package/src/serializer/studio.ts +694 -0
- package/src/serializer/utils.ts +45 -0
- package/src/simulator.ts +157 -0
- package/src/snapshotsDiffer.ts +4398 -0
- package/src/sqlgenerator.ts +4212 -0
- package/src/statementCombiner.ts +597 -0
- package/src/utils/certs.ts +44 -0
- package/src/utils/words.ts +1333 -0
- package/src/utils.ts +370 -0
- package/tests/bin.test.ts +58 -0
- package/tests/cli/d1http.config.ts +12 -0
- package/tests/cli/drizzle.config.ts +9 -0
- package/tests/cli/durable-sqlite.config.ts +7 -0
- package/tests/cli/expo.config.ts +7 -0
- package/tests/cli/postgres.config.ts +13 -0
- package/tests/cli/postgres2.config.ts +17 -0
- package/tests/cli/schema.ts +1 -0
- package/tests/cli/turso.config.ts +10 -0
- package/tests/cli-export.test.ts +79 -0
- package/tests/cli-generate.test.ts +259 -0
- package/tests/cli-migrate.test.ts +103 -0
- package/tests/cli-push.test.ts +126 -0
- package/tests/common.ts +15 -0
- package/tests/indexes/common.ts +21 -0
- package/tests/indexes/pg.test.ts +245 -0
- package/tests/introspect/libsql.test.ts +35 -0
- package/tests/introspect/mysql.test.ts +319 -0
- package/tests/introspect/pg.test.ts +894 -0
- package/tests/introspect/singlestore.test.ts +275 -0
- package/tests/introspect/sqlite.test.ts +122 -0
- package/tests/libsql-checks.test.ts +308 -0
- package/tests/libsql-statements.test.ts +989 -0
- package/tests/libsql-views.test.ts +218 -0
- package/tests/migrate/libsq-schema.ts +6 -0
- package/tests/migrate/libsql-migrate.test.ts +58 -0
- package/tests/migrate/migrations/0000_little_blizzard.sql +4 -0
- package/tests/migrate/migrations/0001_nebulous_storm.sql +10 -0
- package/tests/migrate/migrations/meta/0000_snapshot.json +40 -0
- package/tests/migrate/migrations/meta/0001_snapshot.json +40 -0
- package/tests/migrate/migrations/meta/_journal.json +20 -0
- package/tests/mysql-checks.test.ts +291 -0
- package/tests/mysql-generated.test.ts +1290 -0
- package/tests/mysql-schemas.test.ts +156 -0
- package/tests/mysql-views.test.ts +553 -0
- package/tests/mysql.test.ts +863 -0
- package/tests/pg-array.test.ts +368 -0
- package/tests/pg-checks.test.ts +329 -0
- package/tests/pg-columns.test.ts +484 -0
- package/tests/pg-domains.test.ts +306 -0
- package/tests/pg-enums.test.ts +751 -0
- package/tests/pg-generated.test.ts +529 -0
- package/tests/pg-identity.test.ts +447 -0
- package/tests/pg-schemas.test.ts +105 -0
- package/tests/pg-sequences.test.ts +298 -0
- package/tests/pg-tables.test.ts +1021 -0
- package/tests/pg-views.test.ts +1929 -0
- package/tests/push/common.ts +58 -0
- package/tests/push/libsql.test.ts +1400 -0
- package/tests/push/mysql-push.test.ts +345 -0
- package/tests/push/mysql.test.ts +788 -0
- package/tests/push/pg.test.ts +4341 -0
- package/tests/push/singlestore-push.test.ts +894 -0
- package/tests/push/singlestore.test.ts +444 -0
- package/tests/push/sqlite.test.ts +1613 -0
- package/tests/rls/pg-policy.test.ts +1656 -0
- package/tests/rls/pg-role.test.ts +234 -0
- package/tests/schemaDiffer.ts +2852 -0
- package/tests/singlestore-generated.test.ts +1290 -0
- package/tests/singlestore-schemas.test.ts +155 -0
- package/tests/singlestore.test.ts +978 -0
- package/tests/sqlite-checks.test.ts +308 -0
- package/tests/sqlite-columns.test.ts +1049 -0
- package/tests/sqlite-generated.test.ts +1726 -0
- package/tests/sqlite-tables.test.ts +637 -0
- package/tests/sqlite-views.test.ts +218 -0
- package/tests/statements-combiner/libsql-statements-combiner.test.ts +1812 -0
- package/tests/statements-combiner/singlestore-statements-combiner.test.ts +882 -0
- package/tests/statements-combiner/sqlite-statements-combiner.test.ts +1211 -0
- package/tests/test/sqlite.test.ts +39 -0
- package/tests/testsinglestore.ts +29 -0
- package/tests/validations.test.ts +869 -0
- package/tests/wrap-param.test.ts +16 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.cli-types.json +9 -0
- package/tsconfig.json +28 -0
- 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
|
+
`;
|