@anthonyalayo/drizzle-kit 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/.gitignore +25 -0
  2. package/README.md +79 -0
  3. package/build.dev.ts +51 -0
  4. package/build.ts +112 -0
  5. package/imports-checker/analyze.ts +78 -0
  6. package/imports-checker/checker.ts +296 -0
  7. package/imports-checker/grammar/grammar.ohm +121 -0
  8. package/imports-checker/grammar/grammar.ohm-bundle.d.ts +164 -0
  9. package/imports-checker/grammar/grammar.ohm-bundle.js +753 -0
  10. package/imports-checker/index.ts +48 -0
  11. package/package.json +142 -0
  12. package/patches/difflib@0.2.4.patch +31 -0
  13. package/src/@types/utils.ts +58 -0
  14. package/src/api.ts +504 -0
  15. package/src/cli/commands/_es5.ts +2 -0
  16. package/src/cli/commands/check.ts +52 -0
  17. package/src/cli/commands/drop.ts +60 -0
  18. package/src/cli/commands/introspect.ts +772 -0
  19. package/src/cli/commands/libSqlPushUtils.ts +355 -0
  20. package/src/cli/commands/migrate.ts +1526 -0
  21. package/src/cli/commands/mysqlIntrospect.ts +53 -0
  22. package/src/cli/commands/mysqlPushUtils.ts +352 -0
  23. package/src/cli/commands/mysqlUp.ts +102 -0
  24. package/src/cli/commands/pgIntrospect.ts +55 -0
  25. package/src/cli/commands/pgPushUtils.ts +269 -0
  26. package/src/cli/commands/pgUp.ts +217 -0
  27. package/src/cli/commands/push.ts +637 -0
  28. package/src/cli/commands/singlestoreIntrospect.ts +53 -0
  29. package/src/cli/commands/singlestorePushUtils.ts +456 -0
  30. package/src/cli/commands/singlestoreUp.ts +1 -0
  31. package/src/cli/commands/sqliteIntrospect.ts +96 -0
  32. package/src/cli/commands/sqlitePushUtils.ts +322 -0
  33. package/src/cli/commands/sqliteUp.ts +52 -0
  34. package/src/cli/commands/utils.ts +858 -0
  35. package/src/cli/connections.ts +914 -0
  36. package/src/cli/index.ts +48 -0
  37. package/src/cli/schema.ts +794 -0
  38. package/src/cli/selector-ui.ts +38 -0
  39. package/src/cli/utils.ts +112 -0
  40. package/src/cli/validations/cli.ts +79 -0
  41. package/src/cli/validations/common.ts +193 -0
  42. package/src/cli/validations/libsql.ts +27 -0
  43. package/src/cli/validations/mysql.ts +61 -0
  44. package/src/cli/validations/outputs.ts +91 -0
  45. package/src/cli/validations/postgres.ts +83 -0
  46. package/src/cli/validations/singlestore.ts +61 -0
  47. package/src/cli/validations/sqlite.ts +104 -0
  48. package/src/cli/validations/studio.ts +24 -0
  49. package/src/cli/views.ts +658 -0
  50. package/src/extensions/getTablesFilterByExtensions.ts +16 -0
  51. package/src/extensions/vector.ts +10 -0
  52. package/src/global.ts +61 -0
  53. package/src/index.ts +326 -0
  54. package/src/introspect-mysql.ts +1030 -0
  55. package/src/introspect-pg.ts +1435 -0
  56. package/src/introspect-singlestore.ts +913 -0
  57. package/src/introspect-sqlite.ts +533 -0
  58. package/src/jsonDiffer.js +882 -0
  59. package/src/jsonStatements.ts +3590 -0
  60. package/src/loader.mjs +57 -0
  61. package/src/migrationPreparator.ts +217 -0
  62. package/src/schemaValidator.ts +23 -0
  63. package/src/serializer/index.ts +142 -0
  64. package/src/serializer/mysqlImports.ts +38 -0
  65. package/src/serializer/mysqlSchema.ts +423 -0
  66. package/src/serializer/mysqlSerializer.ts +999 -0
  67. package/src/serializer/pgImports.ts +106 -0
  68. package/src/serializer/pgSchema.ts +937 -0
  69. package/src/serializer/pgSerializer.ts +2223 -0
  70. package/src/serializer/singlestoreImports.ts +38 -0
  71. package/src/serializer/singlestoreSchema.ts +257 -0
  72. package/src/serializer/singlestoreSerializer.ts +767 -0
  73. package/src/serializer/sqliteImports.ts +41 -0
  74. package/src/serializer/sqliteSchema.ts +352 -0
  75. package/src/serializer/sqliteSerializer.ts +931 -0
  76. package/src/serializer/studio.ts +694 -0
  77. package/src/serializer/utils.ts +45 -0
  78. package/src/simulator.ts +157 -0
  79. package/src/snapshotsDiffer.ts +4398 -0
  80. package/src/sqlgenerator.ts +4212 -0
  81. package/src/statementCombiner.ts +597 -0
  82. package/src/utils/certs.ts +44 -0
  83. package/src/utils/words.ts +1333 -0
  84. package/src/utils.ts +370 -0
  85. package/tests/bin.test.ts +58 -0
  86. package/tests/cli/d1http.config.ts +12 -0
  87. package/tests/cli/drizzle.config.ts +9 -0
  88. package/tests/cli/durable-sqlite.config.ts +7 -0
  89. package/tests/cli/expo.config.ts +7 -0
  90. package/tests/cli/postgres.config.ts +13 -0
  91. package/tests/cli/postgres2.config.ts +17 -0
  92. package/tests/cli/schema.ts +1 -0
  93. package/tests/cli/turso.config.ts +10 -0
  94. package/tests/cli-export.test.ts +79 -0
  95. package/tests/cli-generate.test.ts +259 -0
  96. package/tests/cli-migrate.test.ts +103 -0
  97. package/tests/cli-push.test.ts +126 -0
  98. package/tests/common.ts +15 -0
  99. package/tests/indexes/common.ts +21 -0
  100. package/tests/indexes/pg.test.ts +245 -0
  101. package/tests/introspect/libsql.test.ts +35 -0
  102. package/tests/introspect/mysql.test.ts +319 -0
  103. package/tests/introspect/pg.test.ts +894 -0
  104. package/tests/introspect/singlestore.test.ts +275 -0
  105. package/tests/introspect/sqlite.test.ts +122 -0
  106. package/tests/libsql-checks.test.ts +308 -0
  107. package/tests/libsql-statements.test.ts +989 -0
  108. package/tests/libsql-views.test.ts +218 -0
  109. package/tests/migrate/libsq-schema.ts +6 -0
  110. package/tests/migrate/libsql-migrate.test.ts +58 -0
  111. package/tests/migrate/migrations/0000_little_blizzard.sql +4 -0
  112. package/tests/migrate/migrations/0001_nebulous_storm.sql +10 -0
  113. package/tests/migrate/migrations/meta/0000_snapshot.json +40 -0
  114. package/tests/migrate/migrations/meta/0001_snapshot.json +40 -0
  115. package/tests/migrate/migrations/meta/_journal.json +20 -0
  116. package/tests/mysql-checks.test.ts +291 -0
  117. package/tests/mysql-generated.test.ts +1290 -0
  118. package/tests/mysql-schemas.test.ts +156 -0
  119. package/tests/mysql-views.test.ts +553 -0
  120. package/tests/mysql.test.ts +863 -0
  121. package/tests/pg-array.test.ts +368 -0
  122. package/tests/pg-checks.test.ts +329 -0
  123. package/tests/pg-columns.test.ts +484 -0
  124. package/tests/pg-domains.test.ts +306 -0
  125. package/tests/pg-enums.test.ts +751 -0
  126. package/tests/pg-generated.test.ts +529 -0
  127. package/tests/pg-identity.test.ts +447 -0
  128. package/tests/pg-schemas.test.ts +105 -0
  129. package/tests/pg-sequences.test.ts +298 -0
  130. package/tests/pg-tables.test.ts +1021 -0
  131. package/tests/pg-views.test.ts +1929 -0
  132. package/tests/push/common.ts +58 -0
  133. package/tests/push/libsql.test.ts +1400 -0
  134. package/tests/push/mysql-push.test.ts +345 -0
  135. package/tests/push/mysql.test.ts +788 -0
  136. package/tests/push/pg.test.ts +4341 -0
  137. package/tests/push/singlestore-push.test.ts +894 -0
  138. package/tests/push/singlestore.test.ts +444 -0
  139. package/tests/push/sqlite.test.ts +1613 -0
  140. package/tests/rls/pg-policy.test.ts +1656 -0
  141. package/tests/rls/pg-role.test.ts +234 -0
  142. package/tests/schemaDiffer.ts +2852 -0
  143. package/tests/singlestore-generated.test.ts +1290 -0
  144. package/tests/singlestore-schemas.test.ts +155 -0
  145. package/tests/singlestore.test.ts +978 -0
  146. package/tests/sqlite-checks.test.ts +308 -0
  147. package/tests/sqlite-columns.test.ts +1049 -0
  148. package/tests/sqlite-generated.test.ts +1726 -0
  149. package/tests/sqlite-tables.test.ts +637 -0
  150. package/tests/sqlite-views.test.ts +218 -0
  151. package/tests/statements-combiner/libsql-statements-combiner.test.ts +1812 -0
  152. package/tests/statements-combiner/singlestore-statements-combiner.test.ts +882 -0
  153. package/tests/statements-combiner/sqlite-statements-combiner.test.ts +1211 -0
  154. package/tests/test/sqlite.test.ts +39 -0
  155. package/tests/testsinglestore.ts +29 -0
  156. package/tests/validations.test.ts +869 -0
  157. package/tests/wrap-param.test.ts +16 -0
  158. package/tsconfig.build.json +4 -0
  159. package/tsconfig.cli-types.json +9 -0
  160. package/tsconfig.json +28 -0
  161. package/vitest.config.ts +34 -0
@@ -0,0 +1,53 @@
1
+ import { renderWithTask } from 'hanji';
2
+ import { Minimatch } from 'minimatch';
3
+ import { originUUID } from '../../global';
4
+ import type { MySqlSchema } from '../../serializer/mysqlSchema';
5
+ import { fromDatabase } from '../../serializer/mysqlSerializer';
6
+ import type { DB } from '../../utils';
7
+ import { ProgressView } from '../views';
8
+
9
+ export const mysqlPushIntrospect = async (
10
+ db: DB,
11
+ databaseName: string,
12
+ filters: string[],
13
+ ) => {
14
+ const matchers = filters.map((it) => {
15
+ return new Minimatch(it);
16
+ });
17
+
18
+ const filter = (tableName: string) => {
19
+ if (matchers.length === 0) return true;
20
+
21
+ let flags: boolean[] = [];
22
+
23
+ for (let matcher of matchers) {
24
+ if (matcher.negate) {
25
+ if (!matcher.match(tableName)) {
26
+ flags.push(false);
27
+ }
28
+ }
29
+
30
+ if (matcher.match(tableName)) {
31
+ flags.push(true);
32
+ }
33
+ }
34
+
35
+ if (flags.length > 0) {
36
+ return flags.every(Boolean);
37
+ }
38
+ return false;
39
+ };
40
+
41
+ const progress = new ProgressView(
42
+ 'Pulling schema from database...',
43
+ 'Pulling schema from database...',
44
+ );
45
+ const res = await renderWithTask(
46
+ progress,
47
+ fromDatabase(db, databaseName, filter),
48
+ );
49
+
50
+ const schema = { id: originUUID, prevId: '', ...res } as MySqlSchema;
51
+ const { internal, ...schemaWithoutInternals } = schema;
52
+ return { schema: schemaWithoutInternals };
53
+ };
@@ -0,0 +1,352 @@
1
+ import chalk from 'chalk';
2
+ import { render } from 'hanji';
3
+ import { TypeOf } from 'zod';
4
+ import { JsonAlterColumnTypeStatement, JsonStatement } from '../../jsonStatements';
5
+ import { mysqlSchema, MySqlSquasher } from '../../serializer/mysqlSchema';
6
+ import type { DB } from '../../utils';
7
+ import { Select } from '../selector-ui';
8
+ import { withStyle } from '../validations/outputs';
9
+
10
+ export const filterStatements = (
11
+ statements: JsonStatement[],
12
+ currentSchema: TypeOf<typeof mysqlSchema>,
13
+ prevSchema: TypeOf<typeof mysqlSchema>,
14
+ ) => {
15
+ return statements.filter((statement) => {
16
+ if (statement.type === 'alter_table_alter_column_set_type') {
17
+ // Don't need to handle it on migrations step and introspection
18
+ // but for both it should be skipped
19
+ if (
20
+ statement.oldDataType.startsWith('tinyint')
21
+ && statement.newDataType.startsWith('boolean')
22
+ ) {
23
+ return false;
24
+ }
25
+
26
+ if (
27
+ statement.oldDataType.startsWith('bigint unsigned')
28
+ && statement.newDataType.startsWith('serial')
29
+ ) {
30
+ return false;
31
+ }
32
+
33
+ if (
34
+ statement.oldDataType.startsWith('serial')
35
+ && statement.newDataType.startsWith('bigint unsigned')
36
+ ) {
37
+ return false;
38
+ }
39
+ } else if (statement.type === 'alter_table_alter_column_set_default') {
40
+ if (
41
+ statement.newDefaultValue === false
42
+ && statement.oldDefaultValue === 0
43
+ && statement.newDataType === 'boolean'
44
+ ) {
45
+ return false;
46
+ }
47
+ if (
48
+ statement.newDefaultValue === true
49
+ && statement.oldDefaultValue === 1
50
+ && statement.newDataType === 'boolean'
51
+ ) {
52
+ return false;
53
+ }
54
+ } else if (statement.type === 'delete_unique_constraint') {
55
+ const unsquashed = MySqlSquasher.unsquashUnique(statement.data);
56
+ // only if constraint was removed from a serial column, than treat it as removed
57
+ // const serialStatement = statements.find(
58
+ // (it) => it.type === "alter_table_alter_column_set_type"
59
+ // ) as JsonAlterColumnTypeStatement;
60
+ // if (
61
+ // serialStatement?.oldDataType.startsWith("bigint unsigned") &&
62
+ // serialStatement?.newDataType.startsWith("serial") &&
63
+ // serialStatement.columnName ===
64
+ // MySqlSquasher.unsquashUnique(statement.data).columns[0]
65
+ // ) {
66
+ // return false;
67
+ // }
68
+ // Check if uniqueindex was only on this column, that is serial
69
+
70
+ // if now serial and was not serial and was unique index
71
+ if (
72
+ unsquashed.columns.length === 1
73
+ && currentSchema.tables[statement.tableName].columns[unsquashed.columns[0]]
74
+ .type === 'serial'
75
+ && prevSchema.tables[statement.tableName].columns[unsquashed.columns[0]]
76
+ .type === 'serial'
77
+ && currentSchema.tables[statement.tableName].columns[unsquashed.columns[0]]
78
+ .name === unsquashed.columns[0]
79
+ ) {
80
+ return false;
81
+ }
82
+ } else if (statement.type === 'alter_table_alter_column_drop_notnull') {
83
+ // only if constraint was removed from a serial column, than treat it as removed
84
+ const serialStatement = statements.find(
85
+ (it) => it.type === 'alter_table_alter_column_set_type',
86
+ ) as JsonAlterColumnTypeStatement;
87
+ if (
88
+ serialStatement?.oldDataType.startsWith('bigint unsigned')
89
+ && serialStatement?.newDataType.startsWith('serial')
90
+ && serialStatement.columnName === statement.columnName
91
+ && serialStatement.tableName === statement.tableName
92
+ ) {
93
+ return false;
94
+ }
95
+ if (statement.newDataType === 'serial' && !statement.columnNotNull) {
96
+ return false;
97
+ }
98
+ if (statement.columnAutoIncrement) {
99
+ return false;
100
+ }
101
+ }
102
+
103
+ return true;
104
+ });
105
+ };
106
+
107
+ export const logSuggestionsAndReturn = async (
108
+ db: DB,
109
+ statements: JsonStatement[],
110
+ json2: TypeOf<typeof mysqlSchema>,
111
+ ) => {
112
+ let shouldAskForApprove = false;
113
+ const statementsToExecute: string[] = [];
114
+ const infoToPrint: string[] = [];
115
+
116
+ const tablesToRemove: string[] = [];
117
+ const columnsToRemove: string[] = [];
118
+ const schemasToRemove: string[] = [];
119
+ const tablesToTruncate: string[] = [];
120
+
121
+ for (const statement of statements) {
122
+ if (statement.type === 'drop_table') {
123
+ const res = await db.query(
124
+ `select count(*) as count from \`${statement.tableName}\``,
125
+ );
126
+ const count = Number(res[0].count);
127
+ if (count > 0) {
128
+ infoToPrint.push(
129
+ `· You're about to delete ${
130
+ chalk.underline(
131
+ statement.tableName,
132
+ )
133
+ } table with ${count} items`,
134
+ );
135
+ tablesToRemove.push(statement.tableName);
136
+ shouldAskForApprove = true;
137
+ }
138
+ } else if (statement.type === 'alter_table_drop_column') {
139
+ const res = await db.query(
140
+ `select count(*) as count from \`${statement.tableName}\``,
141
+ );
142
+ const count = Number(res[0].count);
143
+ if (count > 0) {
144
+ infoToPrint.push(
145
+ `· You're about to delete ${
146
+ chalk.underline(
147
+ statement.columnName,
148
+ )
149
+ } column in ${statement.tableName} table with ${count} items`,
150
+ );
151
+ columnsToRemove.push(`${statement.tableName}_${statement.columnName}`);
152
+ shouldAskForApprove = true;
153
+ }
154
+ } else if (statement.type === 'drop_schema') {
155
+ const res = await db.query(
156
+ `select count(*) as count from information_schema.tables where table_schema = \`${statement.name}\`;`,
157
+ );
158
+ const count = Number(res[0].count);
159
+ if (count > 0) {
160
+ infoToPrint.push(
161
+ `· You're about to delete ${
162
+ chalk.underline(
163
+ statement.name,
164
+ )
165
+ } schema with ${count} tables`,
166
+ );
167
+ schemasToRemove.push(statement.name);
168
+ shouldAskForApprove = true;
169
+ }
170
+ } else if (statement.type === 'alter_table_alter_column_set_type') {
171
+ const res = await db.query(
172
+ `select count(*) as count from \`${statement.tableName}\``,
173
+ );
174
+ const count = Number(res[0].count);
175
+ if (count > 0) {
176
+ infoToPrint.push(
177
+ `· You're about to change ${
178
+ chalk.underline(
179
+ statement.columnName,
180
+ )
181
+ } column type from ${
182
+ chalk.underline(
183
+ statement.oldDataType,
184
+ )
185
+ } to ${chalk.underline(statement.newDataType)} with ${count} items`,
186
+ );
187
+ statementsToExecute.push(`truncate table ${statement.tableName};`);
188
+ tablesToTruncate.push(statement.tableName);
189
+ shouldAskForApprove = true;
190
+ }
191
+ } else if (statement.type === 'alter_table_alter_column_drop_default') {
192
+ if (statement.columnNotNull) {
193
+ const res = await db.query(
194
+ `select count(*) as count from \`${statement.tableName}\``,
195
+ );
196
+
197
+ const count = Number(res[0].count);
198
+ if (count > 0) {
199
+ infoToPrint.push(
200
+ `· You're about to remove default value from ${
201
+ chalk.underline(
202
+ statement.columnName,
203
+ )
204
+ } not-null column with ${count} items`,
205
+ );
206
+
207
+ tablesToTruncate.push(statement.tableName);
208
+ statementsToExecute.push(`truncate table ${statement.tableName};`);
209
+
210
+ shouldAskForApprove = true;
211
+ }
212
+ }
213
+ // shouldAskForApprove = true;
214
+ } else if (statement.type === 'alter_table_alter_column_set_notnull') {
215
+ if (typeof statement.columnDefault === 'undefined') {
216
+ const res = await db.query(
217
+ `select count(*) as count from \`${statement.tableName}\``,
218
+ );
219
+
220
+ const count = Number(res[0].count);
221
+ if (count > 0) {
222
+ infoToPrint.push(
223
+ `· You're about to set not-null constraint to ${
224
+ chalk.underline(
225
+ statement.columnName,
226
+ )
227
+ } column without default, which contains ${count} items`,
228
+ );
229
+
230
+ tablesToTruncate.push(statement.tableName);
231
+ statementsToExecute.push(`truncate table ${statement.tableName};`);
232
+
233
+ shouldAskForApprove = true;
234
+ }
235
+ }
236
+ } else if (statement.type === 'alter_table_alter_column_drop_pk') {
237
+ const res = await db.query(
238
+ `select count(*) as count from \`${statement.tableName}\``,
239
+ );
240
+
241
+ // if drop pk and json2 has autoincrement in table -> exit process with error
242
+ if (
243
+ Object.values(json2.tables[statement.tableName].columns).filter(
244
+ (column) => column.autoincrement,
245
+ ).length > 0
246
+ ) {
247
+ console.log(
248
+ `${
249
+ withStyle.errorWarning(
250
+ `You have removed the primary key from a ${statement.tableName} table without removing the auto-increment property from this table. As the database error states: 'there can be only one auto column, and it must be defined as a key. Make sure to remove autoincrement from ${statement.tableName} table`,
251
+ )
252
+ }`,
253
+ );
254
+ process.exit(1);
255
+ }
256
+
257
+ const count = Number(res[0].count);
258
+ if (count > 0) {
259
+ infoToPrint.push(
260
+ `· You're about to change ${
261
+ chalk.underline(
262
+ statement.tableName,
263
+ )
264
+ } primary key. This statements may fail and you table may left without primary key`,
265
+ );
266
+
267
+ tablesToTruncate.push(statement.tableName);
268
+ shouldAskForApprove = true;
269
+ }
270
+ } else if (statement.type === 'delete_composite_pk') {
271
+ // if drop pk and json2 has autoincrement in table -> exit process with error
272
+ if (
273
+ Object.values(json2.tables[statement.tableName].columns).filter(
274
+ (column) => column.autoincrement,
275
+ ).length > 0
276
+ ) {
277
+ console.log(
278
+ `${
279
+ withStyle.errorWarning(
280
+ `You have removed the primary key from a ${statement.tableName} table without removing the auto-increment property from this table. As the database error states: 'there can be only one auto column, and it must be defined as a key. Make sure to remove autoincrement from ${statement.tableName} table`,
281
+ )
282
+ }`,
283
+ );
284
+ process.exit(1);
285
+ }
286
+ } else if (statement.type === 'alter_table_add_column') {
287
+ if (
288
+ statement.column.notNull
289
+ && typeof statement.column.default === 'undefined'
290
+ ) {
291
+ const res = await db.query(
292
+ `select count(*) as count from \`${statement.tableName}\``,
293
+ );
294
+ const count = Number(res[0].count);
295
+ if (count > 0) {
296
+ infoToPrint.push(
297
+ `· You're about to add not-null ${
298
+ chalk.underline(
299
+ statement.column.name,
300
+ )
301
+ } column without default value, which contains ${count} items`,
302
+ );
303
+
304
+ tablesToTruncate.push(statement.tableName);
305
+ statementsToExecute.push(`truncate table ${statement.tableName};`);
306
+
307
+ shouldAskForApprove = true;
308
+ }
309
+ }
310
+ } else if (statement.type === 'create_unique_constraint') {
311
+ const res = await db.query(
312
+ `select count(*) as count from \`${statement.tableName}\``,
313
+ );
314
+ const count = Number(res[0].count);
315
+ if (count > 0) {
316
+ const unsquashedUnique = MySqlSquasher.unsquashUnique(statement.data);
317
+ console.log(
318
+ `· You're about to add ${
319
+ chalk.underline(
320
+ unsquashedUnique.name,
321
+ )
322
+ } unique constraint to the table, which contains ${count} items. If this statement fails, you will receive an error from the database. Do you want to truncate ${
323
+ chalk.underline(
324
+ statement.tableName,
325
+ )
326
+ } table?\n`,
327
+ );
328
+ const { status, data } = await render(
329
+ new Select([
330
+ 'No, add the constraint without truncating the table',
331
+ `Yes, truncate the table`,
332
+ ]),
333
+ );
334
+ if (data?.index === 1) {
335
+ tablesToTruncate.push(statement.tableName);
336
+ statementsToExecute.push(`truncate table ${statement.tableName};`);
337
+ shouldAskForApprove = true;
338
+ }
339
+ }
340
+ }
341
+ }
342
+
343
+ return {
344
+ statementsToExecute,
345
+ shouldAskForApprove,
346
+ infoToPrint,
347
+ columnsToRemove: [...new Set(columnsToRemove)],
348
+ schemasToRemove: [...new Set(schemasToRemove)],
349
+ tablesToTruncate: [...new Set(tablesToTruncate)],
350
+ tablesToRemove: [...new Set(tablesToRemove)],
351
+ };
352
+ };
@@ -0,0 +1,102 @@
1
+ import chalk from 'chalk';
2
+ import fs, { writeFileSync } from 'fs';
3
+ import path from 'path';
4
+ import { Column, MySqlSchema, MySqlSchemaV4, MySqlSchemaV5, mysqlSchemaV5, Table } from '../../serializer/mysqlSchema';
5
+ import { prepareOutFolder, validateWithReport } from '../../utils';
6
+
7
+ export const upMysqlHandler = (out: string) => {};
8
+
9
+ export const upMySqlHandlerV4toV5 = (obj: MySqlSchemaV4): MySqlSchemaV5 => {
10
+ const mappedTables: Record<string, Table> = {};
11
+
12
+ for (const [key, table] of Object.entries(obj.tables)) {
13
+ const mappedColumns: Record<string, Column> = {};
14
+ for (const [ckey, column] of Object.entries(table.columns)) {
15
+ let newDefault: any = column.default;
16
+ let newType: string = column.type;
17
+ let newAutoIncrement: boolean | undefined = column.autoincrement;
18
+
19
+ if (column.type.toLowerCase().startsWith('datetime')) {
20
+ if (typeof column.default !== 'undefined') {
21
+ if (column.default.startsWith("'") && column.default.endsWith("'")) {
22
+ newDefault = `'${
23
+ column.default
24
+ .substring(1, column.default.length - 1)
25
+ .replace('T', ' ')
26
+ .slice(0, 23)
27
+ }'`;
28
+ } else {
29
+ newDefault = column.default.replace('T', ' ').slice(0, 23);
30
+ }
31
+ }
32
+
33
+ newType = column.type.toLowerCase().replace('datetime (', 'datetime(');
34
+ } else if (column.type.toLowerCase() === 'date') {
35
+ if (typeof column.default !== 'undefined') {
36
+ if (column.default.startsWith("'") && column.default.endsWith("'")) {
37
+ newDefault = `'${
38
+ column.default
39
+ .substring(1, column.default.length - 1)
40
+ .split('T')[0]
41
+ }'`;
42
+ } else {
43
+ newDefault = column.default.split('T')[0];
44
+ }
45
+ }
46
+ newType = column.type.toLowerCase().replace('date (', 'date(');
47
+ } else if (column.type.toLowerCase().startsWith('timestamp')) {
48
+ if (typeof column.default !== 'undefined') {
49
+ if (column.default.startsWith("'") && column.default.endsWith("'")) {
50
+ newDefault = `'${
51
+ column.default
52
+ .substring(1, column.default.length - 1)
53
+ .replace('T', ' ')
54
+ .slice(0, 23)
55
+ }'`;
56
+ } else {
57
+ newDefault = column.default.replace('T', ' ').slice(0, 23);
58
+ }
59
+ }
60
+ newType = column.type
61
+ .toLowerCase()
62
+ .replace('timestamp (', 'timestamp(');
63
+ } else if (column.type.toLowerCase().startsWith('time')) {
64
+ newType = column.type.toLowerCase().replace('time (', 'time(');
65
+ } else if (column.type.toLowerCase().startsWith('decimal')) {
66
+ newType = column.type.toLowerCase().replace(', ', ',');
67
+ } else if (column.type.toLowerCase().startsWith('enum')) {
68
+ newType = column.type.toLowerCase();
69
+ } else if (column.type.toLowerCase().startsWith('serial')) {
70
+ newAutoIncrement = true;
71
+ }
72
+ mappedColumns[ckey] = {
73
+ ...column,
74
+ default: newDefault,
75
+ type: newType,
76
+ autoincrement: newAutoIncrement,
77
+ };
78
+ }
79
+
80
+ mappedTables[key] = {
81
+ ...table,
82
+ columns: mappedColumns,
83
+ compositePrimaryKeys: {},
84
+ uniqueConstraints: {},
85
+ checkConstraint: {},
86
+ };
87
+ }
88
+
89
+ return {
90
+ version: '5',
91
+ dialect: obj.dialect,
92
+ id: obj.id,
93
+ prevId: obj.prevId,
94
+ tables: mappedTables,
95
+ schemas: obj.schemas,
96
+ _meta: {
97
+ schemas: {} as Record<string, string>,
98
+ tables: {} as Record<string, string>,
99
+ columns: {} as Record<string, string>,
100
+ },
101
+ };
102
+ };
@@ -0,0 +1,55 @@
1
+ import { renderWithTask } from 'hanji';
2
+ import { Minimatch } from 'minimatch';
3
+ import { originUUID } from '../../global';
4
+ import type { PgSchema, PgSchemaInternal } from '../../serializer/pgSchema';
5
+ import { fromDatabase } from '../../serializer/pgSerializer';
6
+ import type { DB } from '../../utils';
7
+ import { Entities } from '../validations/cli';
8
+ import { ProgressView } from '../views';
9
+
10
+ export const pgPushIntrospect = async (
11
+ db: DB,
12
+ filters: string[],
13
+ schemaFilters: string[],
14
+ entities: Entities,
15
+ tsSchema?: PgSchemaInternal,
16
+ ) => {
17
+ const matchers = filters.map((it) => {
18
+ return new Minimatch(it);
19
+ });
20
+
21
+ const filter = (tableName: string) => {
22
+ if (matchers.length === 0) return true;
23
+
24
+ let flags: boolean[] = [];
25
+
26
+ for (let matcher of matchers) {
27
+ if (matcher.negate) {
28
+ if (!matcher.match(tableName)) {
29
+ flags.push(false);
30
+ }
31
+ }
32
+
33
+ if (matcher.match(tableName)) {
34
+ flags.push(true);
35
+ }
36
+ }
37
+
38
+ if (flags.length > 0) {
39
+ return flags.every(Boolean);
40
+ }
41
+ return false;
42
+ };
43
+ const progress = new ProgressView(
44
+ 'Pulling schema from database...',
45
+ 'Pulling schema from database...',
46
+ );
47
+ const res = await renderWithTask(
48
+ progress,
49
+ fromDatabase(db, filter, schemaFilters, entities, undefined, tsSchema),
50
+ );
51
+
52
+ const schema = { id: originUUID, prevId: '', ...res } as PgSchema;
53
+ const { internal, ...schemaWithoutInternals } = schema;
54
+ return { schema: schemaWithoutInternals };
55
+ };