@anthonyalayo/drizzle-kit 1.0.2 → 1.0.5

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 (172) hide show
  1. package/api.d.mts +2891 -0
  2. package/api.d.ts +2891 -0
  3. package/api.js +47534 -0
  4. package/api.mjs +47521 -0
  5. package/bin.cjs +80043 -0
  6. package/{src/index.ts → index-Z-1TKnbX.d.mts} +123 -141
  7. package/index-Z-1TKnbX.d.ts +308 -0
  8. package/index.d.mts +2 -0
  9. package/index.d.ts +2 -0
  10. package/index.js +32 -0
  11. package/index.mjs +7 -0
  12. package/package.json +2 -2
  13. package/utils.js +6056 -0
  14. package/utils.mjs +6032 -0
  15. package/.gitignore +0 -25
  16. package/build.dev.ts +0 -51
  17. package/build.ts +0 -112
  18. package/imports-checker/analyze.ts +0 -78
  19. package/imports-checker/checker.ts +0 -296
  20. package/imports-checker/grammar/grammar.ohm +0 -121
  21. package/imports-checker/grammar/grammar.ohm-bundle.d.ts +0 -164
  22. package/imports-checker/grammar/grammar.ohm-bundle.js +0 -753
  23. package/imports-checker/index.ts +0 -48
  24. package/patches/difflib@0.2.4.patch +0 -31
  25. package/src/@types/utils.ts +0 -58
  26. package/src/api.ts +0 -504
  27. package/src/cli/commands/_es5.ts +0 -2
  28. package/src/cli/commands/check.ts +0 -52
  29. package/src/cli/commands/drop.ts +0 -60
  30. package/src/cli/commands/introspect.ts +0 -772
  31. package/src/cli/commands/libSqlPushUtils.ts +0 -355
  32. package/src/cli/commands/migrate.ts +0 -1526
  33. package/src/cli/commands/mysqlIntrospect.ts +0 -53
  34. package/src/cli/commands/mysqlPushUtils.ts +0 -352
  35. package/src/cli/commands/mysqlUp.ts +0 -102
  36. package/src/cli/commands/pgIntrospect.ts +0 -55
  37. package/src/cli/commands/pgPushUtils.ts +0 -269
  38. package/src/cli/commands/pgUp.ts +0 -217
  39. package/src/cli/commands/push.ts +0 -637
  40. package/src/cli/commands/singlestoreIntrospect.ts +0 -53
  41. package/src/cli/commands/singlestorePushUtils.ts +0 -456
  42. package/src/cli/commands/singlestoreUp.ts +0 -1
  43. package/src/cli/commands/sqliteIntrospect.ts +0 -96
  44. package/src/cli/commands/sqlitePushUtils.ts +0 -322
  45. package/src/cli/commands/sqliteUp.ts +0 -52
  46. package/src/cli/commands/utils.ts +0 -858
  47. package/src/cli/connections.ts +0 -914
  48. package/src/cli/index.ts +0 -48
  49. package/src/cli/schema.ts +0 -794
  50. package/src/cli/selector-ui.ts +0 -38
  51. package/src/cli/utils.ts +0 -112
  52. package/src/cli/validations/cli.ts +0 -79
  53. package/src/cli/validations/common.ts +0 -193
  54. package/src/cli/validations/libsql.ts +0 -27
  55. package/src/cli/validations/mysql.ts +0 -61
  56. package/src/cli/validations/outputs.ts +0 -91
  57. package/src/cli/validations/postgres.ts +0 -83
  58. package/src/cli/validations/singlestore.ts +0 -61
  59. package/src/cli/validations/sqlite.ts +0 -104
  60. package/src/cli/validations/studio.ts +0 -24
  61. package/src/cli/views.ts +0 -658
  62. package/src/extensions/getTablesFilterByExtensions.ts +0 -16
  63. package/src/extensions/vector.ts +0 -10
  64. package/src/global.ts +0 -61
  65. package/src/introspect-mysql.ts +0 -1030
  66. package/src/introspect-pg.ts +0 -1435
  67. package/src/introspect-singlestore.ts +0 -913
  68. package/src/introspect-sqlite.ts +0 -533
  69. package/src/jsonDiffer.js +0 -882
  70. package/src/jsonStatements.ts +0 -3590
  71. package/src/loader.mjs +0 -57
  72. package/src/migrationPreparator.ts +0 -217
  73. package/src/schemaValidator.ts +0 -23
  74. package/src/serializer/index.ts +0 -142
  75. package/src/serializer/mysqlImports.ts +0 -38
  76. package/src/serializer/mysqlSchema.ts +0 -423
  77. package/src/serializer/mysqlSerializer.ts +0 -999
  78. package/src/serializer/pgImports.ts +0 -106
  79. package/src/serializer/pgSchema.ts +0 -937
  80. package/src/serializer/pgSerializer.ts +0 -2223
  81. package/src/serializer/singlestoreImports.ts +0 -38
  82. package/src/serializer/singlestoreSchema.ts +0 -257
  83. package/src/serializer/singlestoreSerializer.ts +0 -767
  84. package/src/serializer/sqliteImports.ts +0 -41
  85. package/src/serializer/sqliteSchema.ts +0 -352
  86. package/src/serializer/sqliteSerializer.ts +0 -931
  87. package/src/serializer/studio.ts +0 -694
  88. package/src/serializer/utils.ts +0 -45
  89. package/src/simulator.ts +0 -157
  90. package/src/snapshotsDiffer.ts +0 -4398
  91. package/src/sqlgenerator.ts +0 -4212
  92. package/src/statementCombiner.ts +0 -597
  93. package/src/utils/certs.ts +0 -44
  94. package/src/utils/words.ts +0 -1333
  95. package/src/utils.ts +0 -370
  96. package/tests/bin.test.ts +0 -58
  97. package/tests/cli/d1http.config.ts +0 -12
  98. package/tests/cli/drizzle.config.ts +0 -9
  99. package/tests/cli/durable-sqlite.config.ts +0 -7
  100. package/tests/cli/expo.config.ts +0 -7
  101. package/tests/cli/postgres.config.ts +0 -13
  102. package/tests/cli/postgres2.config.ts +0 -17
  103. package/tests/cli/schema.ts +0 -1
  104. package/tests/cli/turso.config.ts +0 -10
  105. package/tests/cli-export.test.ts +0 -79
  106. package/tests/cli-generate.test.ts +0 -259
  107. package/tests/cli-migrate.test.ts +0 -103
  108. package/tests/cli-push.test.ts +0 -126
  109. package/tests/common.ts +0 -15
  110. package/tests/indexes/common.ts +0 -21
  111. package/tests/indexes/pg.test.ts +0 -245
  112. package/tests/introspect/libsql.test.ts +0 -35
  113. package/tests/introspect/mysql.test.ts +0 -319
  114. package/tests/introspect/pg.test.ts +0 -894
  115. package/tests/introspect/singlestore.test.ts +0 -275
  116. package/tests/introspect/sqlite.test.ts +0 -122
  117. package/tests/libsql-checks.test.ts +0 -308
  118. package/tests/libsql-statements.test.ts +0 -989
  119. package/tests/libsql-views.test.ts +0 -218
  120. package/tests/migrate/libsq-schema.ts +0 -6
  121. package/tests/migrate/libsql-migrate.test.ts +0 -58
  122. package/tests/migrate/migrations/0000_little_blizzard.sql +0 -4
  123. package/tests/migrate/migrations/0001_nebulous_storm.sql +0 -10
  124. package/tests/migrate/migrations/meta/0000_snapshot.json +0 -40
  125. package/tests/migrate/migrations/meta/0001_snapshot.json +0 -40
  126. package/tests/migrate/migrations/meta/_journal.json +0 -20
  127. package/tests/mysql-checks.test.ts +0 -291
  128. package/tests/mysql-generated.test.ts +0 -1290
  129. package/tests/mysql-schemas.test.ts +0 -156
  130. package/tests/mysql-views.test.ts +0 -553
  131. package/tests/mysql.test.ts +0 -863
  132. package/tests/pg-array.test.ts +0 -368
  133. package/tests/pg-checks.test.ts +0 -329
  134. package/tests/pg-columns.test.ts +0 -484
  135. package/tests/pg-domains.test.ts +0 -306
  136. package/tests/pg-enums.test.ts +0 -751
  137. package/tests/pg-generated.test.ts +0 -529
  138. package/tests/pg-identity.test.ts +0 -447
  139. package/tests/pg-schemas.test.ts +0 -105
  140. package/tests/pg-sequences.test.ts +0 -298
  141. package/tests/pg-tables.test.ts +0 -1021
  142. package/tests/pg-views.test.ts +0 -1929
  143. package/tests/push/common.ts +0 -58
  144. package/tests/push/libsql.test.ts +0 -1400
  145. package/tests/push/mysql-push.test.ts +0 -345
  146. package/tests/push/mysql.test.ts +0 -788
  147. package/tests/push/pg.test.ts +0 -4341
  148. package/tests/push/singlestore-push.test.ts +0 -894
  149. package/tests/push/singlestore.test.ts +0 -444
  150. package/tests/push/sqlite.test.ts +0 -1613
  151. package/tests/rls/pg-policy.test.ts +0 -1656
  152. package/tests/rls/pg-role.test.ts +0 -234
  153. package/tests/schemaDiffer.ts +0 -2852
  154. package/tests/singlestore-generated.test.ts +0 -1290
  155. package/tests/singlestore-schemas.test.ts +0 -155
  156. package/tests/singlestore.test.ts +0 -978
  157. package/tests/sqlite-checks.test.ts +0 -308
  158. package/tests/sqlite-columns.test.ts +0 -1049
  159. package/tests/sqlite-generated.test.ts +0 -1726
  160. package/tests/sqlite-tables.test.ts +0 -637
  161. package/tests/sqlite-views.test.ts +0 -218
  162. package/tests/statements-combiner/libsql-statements-combiner.test.ts +0 -1812
  163. package/tests/statements-combiner/singlestore-statements-combiner.test.ts +0 -882
  164. package/tests/statements-combiner/sqlite-statements-combiner.test.ts +0 -1211
  165. package/tests/test/sqlite.test.ts +0 -39
  166. package/tests/testsinglestore.ts +0 -29
  167. package/tests/validations.test.ts +0 -869
  168. package/tests/wrap-param.test.ts +0 -16
  169. package/tsconfig.build.json +0 -4
  170. package/tsconfig.cli-types.json +0 -9
  171. package/tsconfig.json +0 -28
  172. package/vitest.config.ts +0 -34
@@ -1,2852 +0,0 @@
1
- import { PGlite } from '@electric-sql/pglite';
2
- import { Client } from '@libsql/client/.';
3
- import { Database } from 'better-sqlite3';
4
- import { is } from 'drizzle-orm';
5
- import { MySqlSchema, MySqlTable, MySqlView } from 'drizzle-orm/mysql-core';
6
- import {
7
- getMaterializedViewConfig,
8
- isPgDomain,
9
- isPgEnum,
10
- isPgMaterializedView,
11
- isPgSequence,
12
- isPgView,
13
- PgDomain,
14
- PgEnum,
15
- PgMaterializedView,
16
- PgPolicy,
17
- PgRole,
18
- PgSchema,
19
- PgSequence,
20
- PgTable,
21
- PgView,
22
- } from 'drizzle-orm/pg-core';
23
- import { SingleStoreSchema, SingleStoreTable } from 'drizzle-orm/singlestore-core';
24
- import { SQLiteTable, SQLiteView } from 'drizzle-orm/sqlite-core';
25
- import * as fs from 'fs';
26
- import { Connection } from 'mysql2/promise';
27
- import { libSqlLogSuggestionsAndReturn } from 'src/cli/commands/libSqlPushUtils';
28
- import {
29
- columnsResolver,
30
- domainsResolver,
31
- enumsResolver,
32
- indPolicyResolver,
33
- mySqlViewsResolver,
34
- Named,
35
- policyResolver,
36
- roleResolver,
37
- schemasResolver,
38
- sequencesResolver,
39
- sqliteViewsResolver,
40
- tablesResolver,
41
- viewsResolver,
42
- } from 'src/cli/commands/migrate';
43
- import { pgSuggestions } from 'src/cli/commands/pgPushUtils';
44
- import { logSuggestionsAndReturn as singleStoreLogSuggestionsAndReturn } from 'src/cli/commands/singlestorePushUtils';
45
- import { logSuggestionsAndReturn } from 'src/cli/commands/sqlitePushUtils';
46
- import { Entities } from 'src/cli/validations/cli';
47
- import { CasingType } from 'src/cli/validations/common';
48
- import { snapshotVersion } from 'src/global';
49
- import { schemaToTypeScript as schemaToTypeScriptMySQL } from 'src/introspect-mysql';
50
- import { schemaToTypeScript } from 'src/introspect-pg';
51
- import { schemaToTypeScript as schemaToTypeScriptSingleStore } from 'src/introspect-singlestore';
52
- import { schemaToTypeScript as schemaToTypeScriptSQLite } from 'src/introspect-sqlite';
53
- import { prepareFromMySqlImports } from 'src/serializer/mysqlImports';
54
- import { mysqlSchema, squashMysqlScheme, ViewSquashed } from 'src/serializer/mysqlSchema';
55
- import { fromDatabase as fromMySqlDatabase, generateMySqlSnapshot } from 'src/serializer/mysqlSerializer';
56
- import { prepareFromPgImports } from 'src/serializer/pgImports';
57
- import { pgSchema, Policy, Role, squashPgScheme, View } from 'src/serializer/pgSchema';
58
- import { fromDatabase, generatePgSnapshot } from 'src/serializer/pgSerializer';
59
- import { prepareFromSingleStoreImports } from 'src/serializer/singlestoreImports';
60
- import { singlestoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema';
61
- import {
62
- fromDatabase as fromSingleStoreDatabase,
63
- generateSingleStoreSnapshot,
64
- } from 'src/serializer/singlestoreSerializer';
65
- import { prepareFromSqliteImports } from 'src/serializer/sqliteImports';
66
- import { sqliteSchema, squashSqliteScheme, View as SqliteView } from 'src/serializer/sqliteSchema';
67
- import { fromDatabase as fromSqliteDatabase, generateSqliteSnapshot } from 'src/serializer/sqliteSerializer';
68
- import {
69
- applyLibSQLSnapshotsDiff,
70
- applyMysqlSnapshotsDiff,
71
- applyPgSnapshotsDiff,
72
- applySingleStoreSnapshotsDiff,
73
- applySqliteSnapshotsDiff,
74
- Column,
75
- ColumnsResolverInput,
76
- ColumnsResolverOutput,
77
- Domain,
78
- Enum,
79
- PolicyResolverInput,
80
- PolicyResolverOutput,
81
- ResolverInput,
82
- ResolverOutput,
83
- ResolverOutputWithMoved,
84
- RolesResolverInput,
85
- RolesResolverOutput,
86
- Sequence,
87
- Table,
88
- TablePolicyResolverInput,
89
- TablePolicyResolverOutput,
90
- } from 'src/snapshotsDiffer';
91
-
92
- export type PostgresSchema = Record<
93
- string,
94
- | PgTable<any>
95
- | PgDomain<any>
96
- | PgEnum<any>
97
- | PgSchema
98
- | PgSequence
99
- | PgView
100
- | PgMaterializedView
101
- | PgRole
102
- | PgPolicy
103
- >;
104
- export type MysqlSchema = Record<
105
- string,
106
- MySqlTable<any> | MySqlSchema | MySqlView
107
- >;
108
- export type SqliteSchema = Record<string, SQLiteTable<any> | SQLiteView>;
109
- export type SinglestoreSchema = Record<
110
- string,
111
- SingleStoreTable<any> | SingleStoreSchema /* | SingleStoreView */
112
- >;
113
-
114
- export const testSchemasResolver =
115
- (renames: Set<string>) => async (input: ResolverInput<Named>): Promise<ResolverOutput<Named>> => {
116
- try {
117
- if (
118
- input.created.length === 0
119
- || input.deleted.length === 0
120
- || renames.size === 0
121
- ) {
122
- return {
123
- created: input.created,
124
- renamed: [],
125
- deleted: input.deleted,
126
- };
127
- }
128
-
129
- let createdSchemas = [...input.created];
130
- let deletedSchemas = [...input.deleted];
131
-
132
- const result: {
133
- created: Named[];
134
- renamed: { from: Named; to: Named }[];
135
- deleted: Named[];
136
- } = { created: [], renamed: [], deleted: [] };
137
-
138
- for (let rename of renames) {
139
- const [from, to] = rename.split('->');
140
-
141
- const idxFrom = deletedSchemas.findIndex((it) => {
142
- return it.name === from;
143
- });
144
-
145
- if (idxFrom >= 0) {
146
- const idxTo = createdSchemas.findIndex((it) => {
147
- return it.name === to;
148
- });
149
-
150
- result.renamed.push({
151
- from: deletedSchemas[idxFrom],
152
- to: createdSchemas[idxTo],
153
- });
154
-
155
- delete createdSchemas[idxTo];
156
- delete deletedSchemas[idxFrom];
157
-
158
- createdSchemas = createdSchemas.filter(Boolean);
159
- deletedSchemas = deletedSchemas.filter(Boolean);
160
- }
161
- }
162
-
163
- result.created = createdSchemas;
164
- result.deleted = deletedSchemas;
165
-
166
- return result;
167
- } catch (e) {
168
- console.error(e);
169
- throw e;
170
- }
171
- };
172
-
173
- export const testSequencesResolver = (renames: Set<string>) =>
174
- async (
175
- input: ResolverInput<Sequence>,
176
- ): Promise<ResolverOutputWithMoved<Sequence>> => {
177
- try {
178
- if (
179
- input.created.length === 0
180
- || input.deleted.length === 0
181
- || renames.size === 0
182
- ) {
183
- return {
184
- created: input.created,
185
- moved: [],
186
- renamed: [],
187
- deleted: input.deleted,
188
- };
189
- }
190
-
191
- let createdSequences = [...input.created];
192
- let deletedSequences = [...input.deleted];
193
-
194
- const result: {
195
- created: Sequence[];
196
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
197
- renamed: { from: Sequence; to: Sequence }[];
198
- deleted: Sequence[];
199
- } = { created: [], renamed: [], deleted: [], moved: [] };
200
-
201
- for (let rename of renames) {
202
- const [from, to] = rename.split('->');
203
-
204
- const idxFrom = deletedSequences.findIndex((it) => {
205
- return `${it.schema || 'public'}.${it.name}` === from;
206
- });
207
-
208
- if (idxFrom >= 0) {
209
- const idxTo = createdSequences.findIndex((it) => {
210
- return `${it.schema || 'public'}.${it.name}` === to;
211
- });
212
-
213
- const tableFrom = deletedSequences[idxFrom];
214
- const tableTo = createdSequences[idxFrom];
215
-
216
- if (tableFrom.schema !== tableTo.schema) {
217
- result.moved.push({
218
- name: tableFrom.name,
219
- schemaFrom: tableFrom.schema,
220
- schemaTo: tableTo.schema,
221
- });
222
- }
223
-
224
- if (tableFrom.name !== tableTo.name) {
225
- result.renamed.push({
226
- from: deletedSequences[idxFrom],
227
- to: createdSequences[idxTo],
228
- });
229
- }
230
-
231
- delete createdSequences[idxTo];
232
- delete deletedSequences[idxFrom];
233
-
234
- createdSequences = createdSequences.filter(Boolean);
235
- deletedSequences = deletedSequences.filter(Boolean);
236
- }
237
- }
238
-
239
- result.created = createdSequences;
240
- result.deleted = deletedSequences;
241
-
242
- return result;
243
- } catch (e) {
244
- console.error(e);
245
- throw e;
246
- }
247
- };
248
-
249
- export const testEnumsResolver = (renames: Set<string>) =>
250
- async (
251
- input: ResolverInput<Enum>,
252
- ): Promise<ResolverOutputWithMoved<Enum>> => {
253
- try {
254
- if (
255
- input.created.length === 0
256
- || input.deleted.length === 0
257
- || renames.size === 0
258
- ) {
259
- return {
260
- created: input.created,
261
- moved: [],
262
- renamed: [],
263
- deleted: input.deleted,
264
- };
265
- }
266
-
267
- let createdEnums = [...input.created];
268
- let deletedEnums = [...input.deleted];
269
-
270
- const result: {
271
- created: Enum[];
272
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
273
- renamed: { from: Enum; to: Enum }[];
274
- deleted: Enum[];
275
- } = { created: [], renamed: [], deleted: [], moved: [] };
276
-
277
- for (let rename of renames) {
278
- const [from, to] = rename.split('->');
279
-
280
- const idxFrom = deletedEnums.findIndex((it) => {
281
- return `${it.schema || 'public'}.${it.name}` === from;
282
- });
283
-
284
- if (idxFrom >= 0) {
285
- const idxTo = createdEnums.findIndex((it) => {
286
- return `${it.schema || 'public'}.${it.name}` === to;
287
- });
288
-
289
- const tableFrom = deletedEnums[idxFrom];
290
- const tableTo = createdEnums[idxFrom];
291
-
292
- if (tableFrom.schema !== tableTo.schema) {
293
- result.moved.push({
294
- name: tableFrom.name,
295
- schemaFrom: tableFrom.schema,
296
- schemaTo: tableTo.schema,
297
- });
298
- }
299
-
300
- if (tableFrom.name !== tableTo.name) {
301
- result.renamed.push({
302
- from: deletedEnums[idxFrom],
303
- to: createdEnums[idxTo],
304
- });
305
- }
306
-
307
- delete createdEnums[idxTo];
308
- delete deletedEnums[idxFrom];
309
-
310
- createdEnums = createdEnums.filter(Boolean);
311
- deletedEnums = deletedEnums.filter(Boolean);
312
- }
313
- }
314
-
315
- result.created = createdEnums;
316
- result.deleted = deletedEnums;
317
-
318
- return result;
319
- } catch (e) {
320
- console.error(e);
321
- throw e;
322
- }
323
- };
324
-
325
- export const testTablesResolver = (renames: Set<string>) =>
326
- async (
327
- input: ResolverInput<Table>,
328
- ): Promise<ResolverOutputWithMoved<Table>> => {
329
- try {
330
- if (
331
- input.created.length === 0
332
- || input.deleted.length === 0
333
- || renames.size === 0
334
- ) {
335
- return {
336
- created: input.created,
337
- moved: [],
338
- renamed: [],
339
- deleted: input.deleted,
340
- };
341
- }
342
-
343
- let createdTables = [...input.created];
344
- let deletedTables = [...input.deleted];
345
-
346
- const result: {
347
- created: Table[];
348
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
349
- renamed: { from: Table; to: Table }[];
350
- deleted: Table[];
351
- } = { created: [], renamed: [], deleted: [], moved: [] };
352
-
353
- for (let rename of renames) {
354
- const [from, to] = rename.split('->');
355
-
356
- const idxFrom = deletedTables.findIndex((it) => {
357
- return `${it.schema || 'public'}.${it.name}` === from;
358
- });
359
-
360
- if (idxFrom >= 0) {
361
- const idxTo = createdTables.findIndex((it) => {
362
- return `${it.schema || 'public'}.${it.name}` === to;
363
- });
364
-
365
- const tableFrom = deletedTables[idxFrom];
366
- const tableTo = createdTables[idxFrom];
367
-
368
- if (tableFrom.schema !== tableTo.schema) {
369
- result.moved.push({
370
- name: tableFrom.name,
371
- schemaFrom: tableFrom.schema,
372
- schemaTo: tableTo.schema,
373
- });
374
- }
375
-
376
- if (tableFrom.name !== tableTo.name) {
377
- result.renamed.push({
378
- from: deletedTables[idxFrom],
379
- to: createdTables[idxTo],
380
- });
381
- }
382
-
383
- delete createdTables[idxTo];
384
- delete deletedTables[idxFrom];
385
-
386
- createdTables = createdTables.filter(Boolean);
387
- deletedTables = deletedTables.filter(Boolean);
388
- }
389
- }
390
-
391
- result.created = createdTables;
392
- result.deleted = deletedTables;
393
-
394
- return result;
395
- } catch (e) {
396
- console.error(e);
397
- throw e;
398
- }
399
- };
400
-
401
- export const testColumnsResolver = (renames: Set<string>) =>
402
- async (
403
- input: ColumnsResolverInput<Column>,
404
- ): Promise<ColumnsResolverOutput<Column>> => {
405
- try {
406
- if (
407
- input.created.length === 0
408
- || input.deleted.length === 0
409
- || renames.size === 0
410
- ) {
411
- return {
412
- tableName: input.tableName,
413
- schema: input.schema,
414
- created: input.created,
415
- renamed: [],
416
- deleted: input.deleted,
417
- };
418
- }
419
-
420
- let createdColumns = [...input.created];
421
- let deletedColumns = [...input.deleted];
422
-
423
- const renamed: { from: Column; to: Column }[] = [];
424
-
425
- const schema = input.schema || 'public';
426
-
427
- for (let rename of renames) {
428
- const [from, to] = rename.split('->');
429
-
430
- const idxFrom = deletedColumns.findIndex((it) => {
431
- return `${schema}.${input.tableName}.${it.name}` === from;
432
- });
433
-
434
- if (idxFrom >= 0) {
435
- const idxTo = createdColumns.findIndex((it) => {
436
- return `${schema}.${input.tableName}.${it.name}` === to;
437
- });
438
-
439
- renamed.push({
440
- from: deletedColumns[idxFrom],
441
- to: createdColumns[idxTo],
442
- });
443
-
444
- delete createdColumns[idxTo];
445
- delete deletedColumns[idxFrom];
446
-
447
- createdColumns = createdColumns.filter(Boolean);
448
- deletedColumns = deletedColumns.filter(Boolean);
449
- }
450
- }
451
-
452
- return {
453
- tableName: input.tableName,
454
- schema: input.schema,
455
- created: createdColumns,
456
- deleted: deletedColumns,
457
- renamed,
458
- };
459
- } catch (e) {
460
- console.error(e);
461
- throw e;
462
- }
463
- };
464
-
465
- export const testPolicyResolver = (renames: Set<string>) =>
466
- async (
467
- input: TablePolicyResolverInput<Policy>,
468
- ): Promise<TablePolicyResolverOutput<Policy>> => {
469
- try {
470
- if (
471
- input.created.length === 0
472
- || input.deleted.length === 0
473
- || renames.size === 0
474
- ) {
475
- return {
476
- tableName: input.tableName,
477
- schema: input.schema,
478
- created: input.created,
479
- renamed: [],
480
- deleted: input.deleted,
481
- };
482
- }
483
-
484
- let createdPolicies = [...input.created];
485
- let deletedPolicies = [...input.deleted];
486
-
487
- const renamed: { from: Policy; to: Policy }[] = [];
488
-
489
- const schema = input.schema || 'public';
490
-
491
- for (let rename of renames) {
492
- const [from, to] = rename.split('->');
493
-
494
- const idxFrom = deletedPolicies.findIndex((it) => {
495
- return `${schema}.${input.tableName}.${it.name}` === from;
496
- });
497
-
498
- if (idxFrom >= 0) {
499
- const idxTo = createdPolicies.findIndex((it) => {
500
- return `${schema}.${input.tableName}.${it.name}` === to;
501
- });
502
-
503
- renamed.push({
504
- from: deletedPolicies[idxFrom],
505
- to: createdPolicies[idxTo],
506
- });
507
-
508
- delete createdPolicies[idxTo];
509
- delete deletedPolicies[idxFrom];
510
-
511
- createdPolicies = createdPolicies.filter(Boolean);
512
- deletedPolicies = deletedPolicies.filter(Boolean);
513
- }
514
- }
515
-
516
- return {
517
- tableName: input.tableName,
518
- schema: input.schema,
519
- created: createdPolicies,
520
- deleted: deletedPolicies,
521
- renamed,
522
- };
523
- } catch (e) {
524
- console.error(e);
525
- throw e;
526
- }
527
- };
528
-
529
- export const testIndPolicyResolver = (renames: Set<string>) =>
530
- async (
531
- input: PolicyResolverInput<Policy>,
532
- ): Promise<PolicyResolverOutput<Policy>> => {
533
- try {
534
- if (
535
- input.created.length === 0
536
- || input.deleted.length === 0
537
- || renames.size === 0
538
- ) {
539
- return {
540
- created: input.created,
541
- renamed: [],
542
- deleted: input.deleted,
543
- };
544
- }
545
-
546
- let createdPolicies = [...input.created];
547
- let deletedPolicies = [...input.deleted];
548
-
549
- const renamed: { from: Policy; to: Policy }[] = [];
550
-
551
- for (let rename of renames) {
552
- const [from, to] = rename.split('->');
553
-
554
- const idxFrom = deletedPolicies.findIndex((it) => {
555
- return `${it.on}.${it.name}` === from;
556
- });
557
-
558
- if (idxFrom >= 0) {
559
- const idxTo = createdPolicies.findIndex((it) => {
560
- return `${it.on}.${it.name}` === to;
561
- });
562
-
563
- renamed.push({
564
- from: deletedPolicies[idxFrom],
565
- to: createdPolicies[idxTo],
566
- });
567
-
568
- delete createdPolicies[idxTo];
569
- delete deletedPolicies[idxFrom];
570
-
571
- createdPolicies = createdPolicies.filter(Boolean);
572
- deletedPolicies = deletedPolicies.filter(Boolean);
573
- }
574
- }
575
-
576
- return {
577
- created: createdPolicies,
578
- deleted: deletedPolicies,
579
- renamed,
580
- };
581
- } catch (e) {
582
- console.error(e);
583
- throw e;
584
- }
585
- };
586
-
587
- export const testRolesResolver = (renames: Set<string>) =>
588
- async (
589
- input: RolesResolverInput<Role>,
590
- ): Promise<RolesResolverOutput<Role>> => {
591
- try {
592
- if (
593
- input.created.length === 0
594
- || input.deleted.length === 0
595
- || renames.size === 0
596
- ) {
597
- return {
598
- created: input.created,
599
- renamed: [],
600
- deleted: input.deleted,
601
- };
602
- }
603
-
604
- let createdPolicies = [...input.created];
605
- let deletedPolicies = [...input.deleted];
606
-
607
- const renamed: { from: Policy; to: Policy }[] = [];
608
-
609
- for (let rename of renames) {
610
- const [from, to] = rename.split('->');
611
-
612
- const idxFrom = deletedPolicies.findIndex((it) => {
613
- return `${it.name}` === from;
614
- });
615
-
616
- if (idxFrom >= 0) {
617
- const idxTo = createdPolicies.findIndex((it) => {
618
- return `${it.name}` === to;
619
- });
620
-
621
- renamed.push({
622
- from: deletedPolicies[idxFrom],
623
- to: createdPolicies[idxTo],
624
- });
625
-
626
- delete createdPolicies[idxTo];
627
- delete deletedPolicies[idxFrom];
628
-
629
- createdPolicies = createdPolicies.filter(Boolean);
630
- deletedPolicies = deletedPolicies.filter(Boolean);
631
- }
632
- }
633
-
634
- return {
635
- created: createdPolicies,
636
- deleted: deletedPolicies,
637
- renamed,
638
- };
639
- } catch (e) {
640
- console.error(e);
641
- throw e;
642
- }
643
- };
644
-
645
- export const testDomainsResolver = (renames: Set<string>) =>
646
- async (
647
- input: ResolverInput<Domain>,
648
- ): Promise<ResolverOutputWithMoved<Domain>> => {
649
- try {
650
- if (
651
- input.created.length === 0
652
- || input.deleted.length === 0
653
- || renames.size === 0
654
- ) {
655
- return {
656
- created: input.created,
657
- moved: [],
658
- renamed: [],
659
- deleted: input.deleted,
660
- };
661
- }
662
-
663
- let createdDomains = [...input.created];
664
- let deletedDomains = [...input.deleted];
665
-
666
- const result: {
667
- created: Domain[];
668
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
669
- renamed: { from: Domain; to: Domain }[];
670
- deleted: Domain[];
671
- } = { created: [], renamed: [], deleted: [], moved: [] };
672
-
673
- for (let rename of renames) {
674
- const [from, to] = rename.split('->');
675
-
676
- const idxFrom = deletedDomains.findIndex((it) => {
677
- return `${it.schema || 'public'}.${it.name}` === from;
678
- });
679
-
680
- if (idxFrom >= 0) {
681
- const idxTo = createdDomains.findIndex((it) => {
682
- return `${it.schema || 'public'}.${it.name}` === to;
683
- });
684
-
685
- const domainFrom = deletedDomains[idxFrom];
686
- const domainTo = createdDomains[idxFrom];
687
-
688
- if (domainFrom.schema !== domainTo.schema) {
689
- result.moved.push({
690
- name: domainFrom.name,
691
- schemaFrom: domainFrom.schema,
692
- schemaTo: domainTo.schema,
693
- });
694
- }
695
-
696
- if (domainFrom.name !== domainTo.name) {
697
- result.renamed.push({
698
- from: deletedDomains[idxFrom],
699
- to: createdDomains[idxTo],
700
- });
701
- }
702
-
703
- delete createdDomains[idxTo];
704
- delete deletedDomains[idxFrom];
705
-
706
- createdDomains = createdDomains.filter(Boolean);
707
- deletedDomains = deletedDomains.filter(Boolean);
708
- }
709
- }
710
-
711
- result.created = createdDomains;
712
- result.deleted = deletedDomains;
713
-
714
- return result;
715
- } catch (e) {
716
- console.error(e);
717
- throw e;
718
- }
719
- };
720
-
721
- export const testViewsResolver = (renames: Set<string>) =>
722
- async (
723
- input: ResolverInput<View>,
724
- ): Promise<ResolverOutputWithMoved<View>> => {
725
- try {
726
- if (
727
- input.created.length === 0
728
- || input.deleted.length === 0
729
- || renames.size === 0
730
- ) {
731
- return {
732
- created: input.created,
733
- moved: [],
734
- renamed: [],
735
- deleted: input.deleted,
736
- };
737
- }
738
-
739
- let createdViews = [...input.created];
740
- let deletedViews = [...input.deleted];
741
-
742
- const result: {
743
- created: View[];
744
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
745
- renamed: { from: View; to: View }[];
746
- deleted: View[];
747
- } = { created: [], renamed: [], deleted: [], moved: [] };
748
-
749
- for (let rename of renames) {
750
- const [from, to] = rename.split('->');
751
-
752
- const idxFrom = deletedViews.findIndex((it) => {
753
- return `${it.schema || 'public'}.${it.name}` === from;
754
- });
755
-
756
- if (idxFrom >= 0) {
757
- const idxTo = createdViews.findIndex((it) => {
758
- return `${it.schema || 'public'}.${it.name}` === to;
759
- });
760
-
761
- const viewFrom = deletedViews[idxFrom];
762
- const viewTo = createdViews[idxFrom];
763
-
764
- if (viewFrom.schema !== viewTo.schema) {
765
- result.moved.push({
766
- name: viewFrom.name,
767
- schemaFrom: viewFrom.schema,
768
- schemaTo: viewTo.schema,
769
- });
770
- }
771
-
772
- if (viewFrom.name !== viewTo.name) {
773
- result.renamed.push({
774
- from: deletedViews[idxFrom],
775
- to: createdViews[idxTo],
776
- });
777
- }
778
-
779
- delete createdViews[idxTo];
780
- delete deletedViews[idxFrom];
781
-
782
- createdViews = createdViews.filter(Boolean);
783
- deletedViews = deletedViews.filter(Boolean);
784
- }
785
- }
786
-
787
- result.created = createdViews;
788
- result.deleted = deletedViews;
789
-
790
- return result;
791
- } catch (e) {
792
- console.error(e);
793
- throw e;
794
- }
795
- };
796
-
797
- export const testViewsResolverMySql = (renames: Set<string>) =>
798
- async (
799
- input: ResolverInput<ViewSquashed & { schema: '' }>,
800
- ): Promise<ResolverOutputWithMoved<ViewSquashed>> => {
801
- try {
802
- if (
803
- input.created.length === 0
804
- || input.deleted.length === 0
805
- || renames.size === 0
806
- ) {
807
- return {
808
- created: input.created,
809
- moved: [],
810
- renamed: [],
811
- deleted: input.deleted,
812
- };
813
- }
814
-
815
- let createdViews = [...input.created];
816
- let deletedViews = [...input.deleted];
817
-
818
- const result: {
819
- created: ViewSquashed[];
820
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
821
- renamed: { from: ViewSquashed; to: ViewSquashed }[];
822
- deleted: ViewSquashed[];
823
- } = { created: [], renamed: [], deleted: [], moved: [] };
824
-
825
- for (let rename of renames) {
826
- const [from, to] = rename.split('->');
827
-
828
- const idxFrom = deletedViews.findIndex((it) => {
829
- return `${it.schema || 'public'}.${it.name}` === from;
830
- });
831
-
832
- if (idxFrom >= 0) {
833
- const idxTo = createdViews.findIndex((it) => {
834
- return `${it.schema || 'public'}.${it.name}` === to;
835
- });
836
-
837
- const viewFrom = deletedViews[idxFrom];
838
- const viewTo = createdViews[idxFrom];
839
-
840
- if (viewFrom.schema !== viewTo.schema) {
841
- result.moved.push({
842
- name: viewFrom.name,
843
- schemaFrom: viewFrom.schema,
844
- schemaTo: viewTo.schema,
845
- });
846
- }
847
-
848
- if (viewFrom.name !== viewTo.name) {
849
- result.renamed.push({
850
- from: deletedViews[idxFrom],
851
- to: createdViews[idxTo],
852
- });
853
- }
854
-
855
- delete createdViews[idxTo];
856
- delete deletedViews[idxFrom];
857
-
858
- createdViews = createdViews.filter(Boolean);
859
- deletedViews = deletedViews.filter(Boolean);
860
- }
861
- }
862
-
863
- result.created = createdViews;
864
- result.deleted = deletedViews;
865
-
866
- return result;
867
- } catch (e) {
868
- console.error(e);
869
- throw e;
870
- }
871
- };
872
-
873
- export const testViewsResolverSingleStore = (renames: Set<string>) =>
874
- async (
875
- input: ResolverInput<ViewSquashed & { schema: '' }>,
876
- ): Promise<ResolverOutputWithMoved<ViewSquashed>> => {
877
- try {
878
- if (
879
- input.created.length === 0
880
- || input.deleted.length === 0
881
- || renames.size === 0
882
- ) {
883
- return {
884
- created: input.created,
885
- moved: [],
886
- renamed: [],
887
- deleted: input.deleted,
888
- };
889
- }
890
-
891
- let createdViews = [...input.created];
892
- let deletedViews = [...input.deleted];
893
-
894
- const result: {
895
- created: ViewSquashed[];
896
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
897
- renamed: { from: ViewSquashed; to: ViewSquashed }[];
898
- deleted: ViewSquashed[];
899
- } = { created: [], renamed: [], deleted: [], moved: [] };
900
-
901
- for (let rename of renames) {
902
- const [from, to] = rename.split('->');
903
-
904
- const idxFrom = deletedViews.findIndex((it) => {
905
- return `${it.schema || 'public'}.${it.name}` === from;
906
- });
907
-
908
- if (idxFrom >= 0) {
909
- const idxTo = createdViews.findIndex((it) => {
910
- return `${it.schema || 'public'}.${it.name}` === to;
911
- });
912
-
913
- const viewFrom = deletedViews[idxFrom];
914
- const viewTo = createdViews[idxFrom];
915
-
916
- if (viewFrom.schema !== viewTo.schema) {
917
- result.moved.push({
918
- name: viewFrom.name,
919
- schemaFrom: viewFrom.schema,
920
- schemaTo: viewTo.schema,
921
- });
922
- }
923
-
924
- if (viewFrom.name !== viewTo.name) {
925
- result.renamed.push({
926
- from: deletedViews[idxFrom],
927
- to: createdViews[idxTo],
928
- });
929
- }
930
-
931
- delete createdViews[idxTo];
932
- delete deletedViews[idxFrom];
933
-
934
- createdViews = createdViews.filter(Boolean);
935
- deletedViews = deletedViews.filter(Boolean);
936
- }
937
- }
938
-
939
- result.created = createdViews;
940
- result.deleted = deletedViews;
941
-
942
- return result;
943
- } catch (e) {
944
- console.error(e);
945
- throw e;
946
- }
947
- };
948
-
949
- export const testViewsResolverSqlite = (renames: Set<string>) =>
950
- async (
951
- input: ResolverInput<SqliteView>,
952
- ): Promise<ResolverOutputWithMoved<SqliteView>> => {
953
- try {
954
- if (
955
- input.created.length === 0
956
- || input.deleted.length === 0
957
- || renames.size === 0
958
- ) {
959
- return {
960
- created: input.created,
961
- moved: [],
962
- renamed: [],
963
- deleted: input.deleted,
964
- };
965
- }
966
-
967
- let createdViews = [...input.created];
968
- let deletedViews = [...input.deleted];
969
-
970
- const result: {
971
- created: SqliteView[];
972
- moved: { name: string; schemaFrom: string; schemaTo: string }[];
973
- renamed: { from: SqliteView; to: SqliteView }[];
974
- deleted: SqliteView[];
975
- } = { created: [], renamed: [], deleted: [], moved: [] };
976
-
977
- for (let rename of renames) {
978
- const [from, to] = rename.split('->');
979
-
980
- const idxFrom = deletedViews.findIndex((it) => {
981
- return it.name === from;
982
- });
983
-
984
- if (idxFrom >= 0) {
985
- const idxTo = createdViews.findIndex((it) => {
986
- return it.name === to;
987
- });
988
-
989
- const viewFrom = deletedViews[idxFrom];
990
- const viewTo = createdViews[idxFrom];
991
-
992
- if (viewFrom.name !== viewTo.name) {
993
- result.renamed.push({
994
- from: deletedViews[idxFrom],
995
- to: createdViews[idxTo],
996
- });
997
- }
998
-
999
- delete createdViews[idxTo];
1000
- delete deletedViews[idxFrom];
1001
-
1002
- createdViews = createdViews.filter(Boolean);
1003
- deletedViews = deletedViews.filter(Boolean);
1004
- }
1005
- }
1006
-
1007
- result.created = createdViews;
1008
- result.deleted = deletedViews;
1009
-
1010
- return result;
1011
- } catch (e) {
1012
- console.error(e);
1013
- throw e;
1014
- }
1015
- };
1016
-
1017
- export const diffTestSchemasPush = async (
1018
- client: PGlite,
1019
- left: PostgresSchema,
1020
- right: PostgresSchema,
1021
- renamesArr: string[],
1022
- cli: boolean = false,
1023
- schemas: string[] = ['public'],
1024
- casing?: CasingType | undefined,
1025
- entities?: Entities,
1026
- sqlStatementsToRun: {
1027
- before?: string[];
1028
- after?: string[];
1029
- runApply?: boolean;
1030
- } = {
1031
- before: [],
1032
- after: [],
1033
- runApply: true,
1034
- },
1035
- ) => {
1036
- const shouldRunApply = sqlStatementsToRun.runApply === undefined
1037
- ? true
1038
- : sqlStatementsToRun.runApply;
1039
-
1040
- for (const st of sqlStatementsToRun.before ?? []) {
1041
- await client.query(st);
1042
- }
1043
-
1044
- if (shouldRunApply) {
1045
- const res = await applyPgDiffs(left, casing);
1046
- for (const st of res.sqlStatements) {
1047
- await client.query(st);
1048
- }
1049
- }
1050
-
1051
- for (const st of sqlStatementsToRun.after ?? []) {
1052
- await client.query(st);
1053
- }
1054
-
1055
- const materializedViewsForRefresh = Object.values(left).filter((it) =>
1056
- isPgMaterializedView(it)
1057
- ) as PgMaterializedView[];
1058
-
1059
- // refresh all mat views
1060
- for (const view of materializedViewsForRefresh) {
1061
- const viewConf = getMaterializedViewConfig(view);
1062
- if (viewConf.isExisting) continue;
1063
-
1064
- await client.exec(
1065
- `REFRESH MATERIALIZED VIEW "${viewConf.schema ?? 'public'}"."${viewConf.name}"${
1066
- viewConf.withNoData ? ' WITH NO DATA;' : ';'
1067
- }`,
1068
- );
1069
- }
1070
-
1071
- // do introspect into PgSchemaInternal
1072
- const introspectedSchema = await fromDatabase(
1073
- {
1074
- query: async (query: string, values?: any[] | undefined) => {
1075
- const res = await client.query(query, values);
1076
- return res.rows as any[];
1077
- },
1078
- },
1079
- undefined,
1080
- schemas,
1081
- entities,
1082
- );
1083
-
1084
- const leftTables = Object.values(right).filter((it) => is(it, PgTable)) as PgTable[];
1085
-
1086
- const leftSchemas = Object.values(right).filter((it) => is(it, PgSchema)) as PgSchema[];
1087
-
1088
- const leftEnums = Object.values(right).filter((it) => isPgEnum(it)) as PgEnum<any>[];
1089
-
1090
- const leftSequences = Object.values(right).filter((it) => isPgSequence(it)) as PgSequence[];
1091
-
1092
- const leftDomains = Object.values(right).filter((it) => isPgDomain(it)) as PgDomain<any>[];
1093
-
1094
- const leftRoles = Object.values(right).filter((it) => is(it, PgRole)) as PgRole[];
1095
-
1096
- const leftPolicies = Object.values(right).filter((it) => is(it, PgPolicy)) as PgPolicy[];
1097
-
1098
- const leftViews = Object.values(right).filter((it) => isPgView(it)) as PgView[];
1099
-
1100
- const leftMaterializedViews = Object.values(right).filter((it) => isPgMaterializedView(it)) as PgMaterializedView[];
1101
-
1102
- const serialized2 = generatePgSnapshot(
1103
- leftTables,
1104
- leftDomains,
1105
- leftEnums,
1106
- leftSchemas,
1107
- leftSequences,
1108
- leftRoles,
1109
- leftPolicies,
1110
- leftViews,
1111
- leftMaterializedViews,
1112
- casing,
1113
- );
1114
-
1115
- const { version: v1, dialect: d1, ...rest1 } = introspectedSchema;
1116
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1117
-
1118
- const sch1 = {
1119
- version: snapshotVersion,
1120
- dialect: 'postgresql',
1121
- id: '0',
1122
- prevId: '0',
1123
- ...rest1,
1124
- } as const;
1125
-
1126
- const sch2 = {
1127
- version: snapshotVersion,
1128
- dialect: 'postgresql',
1129
- id: '0',
1130
- prevId: '0',
1131
- ...rest2,
1132
- } as const;
1133
-
1134
- const sn1 = squashPgScheme(sch1, 'push');
1135
- const sn2 = squashPgScheme(sch2, 'push');
1136
-
1137
- const validatedPrev = pgSchema.parse(sch1);
1138
- const validatedCur = pgSchema.parse(sch2);
1139
-
1140
- const renames = new Set(renamesArr);
1141
-
1142
- if (!cli) {
1143
- const { sqlStatements, statements } = await applyPgSnapshotsDiff(
1144
- sn1,
1145
- sn2,
1146
- testSchemasResolver(renames),
1147
- testDomainsResolver(renames),
1148
- testEnumsResolver(renames),
1149
- testSequencesResolver(renames),
1150
- testPolicyResolver(renames),
1151
- testIndPolicyResolver(renames),
1152
- testRolesResolver(renames),
1153
- testTablesResolver(renames),
1154
- testColumnsResolver(renames),
1155
- testViewsResolver(renames),
1156
- validatedPrev,
1157
- validatedCur,
1158
- 'push',
1159
- );
1160
-
1161
- const {
1162
- shouldAskForApprove,
1163
- statementsToExecute,
1164
- columnsToRemove,
1165
- tablesToRemove,
1166
- tablesToTruncate,
1167
- infoToPrint,
1168
- schemasToRemove,
1169
- matViewsToRemove,
1170
- } = await pgSuggestions(
1171
- {
1172
- query: async <T>(sql: string, params: any[] = []) => {
1173
- return (await client.query(sql, params)).rows as T[];
1174
- },
1175
- },
1176
- statements,
1177
- );
1178
-
1179
- return {
1180
- sqlStatements: statementsToExecute,
1181
- statements,
1182
- shouldAskForApprove,
1183
- columnsToRemove,
1184
- tablesToRemove,
1185
- tablesToTruncate,
1186
- infoToPrint,
1187
- schemasToRemove,
1188
- matViewsToRemove,
1189
- };
1190
- } else {
1191
- const { sqlStatements, statements } = await applyPgSnapshotsDiff(
1192
- sn1,
1193
- sn2,
1194
- schemasResolver,
1195
- domainsResolver,
1196
- enumsResolver,
1197
- sequencesResolver,
1198
- policyResolver,
1199
- indPolicyResolver,
1200
- roleResolver,
1201
- tablesResolver,
1202
- columnsResolver,
1203
- viewsResolver,
1204
- validatedPrev,
1205
- validatedCur,
1206
- 'push',
1207
- );
1208
- return { sqlStatements, statements };
1209
- }
1210
- };
1211
-
1212
- export const applyPgDiffs = async (
1213
- sn: PostgresSchema,
1214
- casing: CasingType | undefined,
1215
- ) => {
1216
- const dryRun = {
1217
- version: snapshotVersion,
1218
- dialect: 'postgresql',
1219
- id: '0',
1220
- prevId: '0',
1221
- tables: {},
1222
- domains: {},
1223
- enums: {},
1224
- views: {},
1225
- schemas: {},
1226
- sequences: {},
1227
- policies: {},
1228
- roles: {},
1229
- _meta: {
1230
- schemas: {},
1231
- tables: {},
1232
- columns: {},
1233
- },
1234
- } as const;
1235
-
1236
- const tables = Object.values(sn).filter((it) => is(it, PgTable)) as PgTable[];
1237
-
1238
- const schemas = Object.values(sn).filter((it) => is(it, PgSchema)) as PgSchema[];
1239
-
1240
- const domains = Object.values(sn).filter((it) => isPgDomain(it)) as PgDomain<any>[];
1241
-
1242
- const enums = Object.values(sn).filter((it) => isPgEnum(it)) as PgEnum<any>[];
1243
-
1244
- const sequences = Object.values(sn).filter((it) => isPgSequence(it)) as PgSequence[];
1245
-
1246
- const roles = Object.values(sn).filter((it) => is(it, PgRole)) as PgRole[];
1247
-
1248
- const views = Object.values(sn).filter((it) => isPgView(it)) as PgView[];
1249
-
1250
- const policies = Object.values(sn).filter((it) => is(it, PgPolicy)) as PgPolicy[];
1251
-
1252
- const materializedViews = Object.values(sn).filter((it) => isPgMaterializedView(it)) as PgMaterializedView[];
1253
-
1254
- const serialized1 = generatePgSnapshot(
1255
- tables,
1256
- domains,
1257
- enums,
1258
- schemas,
1259
- sequences,
1260
- roles,
1261
- policies,
1262
- views,
1263
- materializedViews,
1264
- casing,
1265
- );
1266
-
1267
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
1268
-
1269
- const sch1 = {
1270
- version: snapshotVersion,
1271
- dialect: 'postgresql',
1272
- id: '0',
1273
- prevId: '0',
1274
- ...rest1,
1275
- } as const;
1276
-
1277
- const sn1 = squashPgScheme(sch1);
1278
-
1279
- const validatedPrev = pgSchema.parse(dryRun);
1280
- const validatedCur = pgSchema.parse(sch1);
1281
-
1282
- const { sqlStatements, statements } = await applyPgSnapshotsDiff(
1283
- dryRun,
1284
- sn1,
1285
- testSchemasResolver(new Set()),
1286
- testDomainsResolver(new Set()),
1287
- testEnumsResolver(new Set()),
1288
- testSequencesResolver(new Set()),
1289
- testPolicyResolver(new Set()),
1290
- testIndPolicyResolver(new Set()),
1291
- testRolesResolver(new Set()),
1292
- testTablesResolver(new Set()),
1293
- testColumnsResolver(new Set()),
1294
- testViewsResolver(new Set()),
1295
- validatedPrev,
1296
- validatedCur,
1297
- );
1298
- return { sqlStatements, statements };
1299
- };
1300
-
1301
- export const diffTestSchemas = async (
1302
- left: PostgresSchema,
1303
- right: PostgresSchema,
1304
- renamesArr: string[],
1305
- cli: boolean = false,
1306
- casing?: CasingType | undefined,
1307
- ) => {
1308
- const leftTables = Object.values(left).filter((it) => is(it, PgTable)) as PgTable[];
1309
-
1310
- const rightTables = Object.values(right).filter((it) => is(it, PgTable)) as PgTable[];
1311
-
1312
- const leftSchemas = Object.values(left).filter((it) => is(it, PgSchema)) as PgSchema[];
1313
-
1314
- const rightSchemas = Object.values(right).filter((it) => is(it, PgSchema)) as PgSchema[];
1315
-
1316
- const leftEnums = Object.values(left).filter((it) => isPgEnum(it)) as PgEnum<any>[];
1317
-
1318
- const rightEnums = Object.values(right).filter((it) => isPgEnum(it)) as PgEnum<any>[];
1319
-
1320
- const leftSequences = Object.values(left).filter((it) => isPgSequence(it)) as PgSequence[];
1321
-
1322
- const rightSequences = Object.values(right).filter((it) => isPgSequence(it)) as PgSequence[];
1323
-
1324
- const leftDomains = Object.values(left).filter((it) => isPgDomain(it)) as PgDomain<any>[];
1325
-
1326
- const rightDomains = Object.values(right).filter((it) => isPgDomain(it)) as PgDomain<any>[];
1327
-
1328
- const leftRoles = Object.values(left).filter((it) => is(it, PgRole)) as PgRole[];
1329
-
1330
- const rightRoles = Object.values(right).filter((it) => is(it, PgRole)) as PgRole[];
1331
-
1332
- const leftPolicies = Object.values(left).filter((it) => is(it, PgPolicy)) as PgPolicy[];
1333
-
1334
- const rightPolicies = Object.values(right).filter((it) => is(it, PgPolicy)) as PgPolicy[];
1335
-
1336
- const leftViews = Object.values(left).filter((it) => isPgView(it)) as PgView[];
1337
-
1338
- const rightViews = Object.values(right).filter((it) => isPgView(it)) as PgView[];
1339
-
1340
- const leftMaterializedViews = Object.values(left).filter((it) => isPgMaterializedView(it)) as PgMaterializedView[];
1341
-
1342
- const rightMaterializedViews = Object.values(right).filter((it) => isPgMaterializedView(it)) as PgMaterializedView[];
1343
-
1344
- const serialized1 = generatePgSnapshot(
1345
- leftTables,
1346
- leftDomains,
1347
- leftEnums,
1348
- leftSchemas,
1349
- leftSequences,
1350
- leftRoles,
1351
- leftPolicies,
1352
- leftViews,
1353
- leftMaterializedViews,
1354
- casing,
1355
- );
1356
- const serialized2 = generatePgSnapshot(
1357
- rightTables,
1358
- rightDomains,
1359
- rightEnums,
1360
- rightSchemas,
1361
- rightSequences,
1362
- rightRoles,
1363
- rightPolicies,
1364
- rightViews,
1365
- rightMaterializedViews,
1366
- casing,
1367
- );
1368
-
1369
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
1370
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1371
-
1372
- const sch1 = {
1373
- version: snapshotVersion,
1374
- dialect: 'postgresql',
1375
- id: '0',
1376
- prevId: '0',
1377
- ...rest1,
1378
- } as const;
1379
-
1380
- const sch2 = {
1381
- version: snapshotVersion,
1382
- dialect: 'postgresql',
1383
- id: '0',
1384
- prevId: '0',
1385
- ...rest2,
1386
- } as const;
1387
-
1388
- const sn1 = squashPgScheme(sch1);
1389
- const sn2 = squashPgScheme(sch2);
1390
-
1391
- const validatedPrev = pgSchema.parse(sch1);
1392
- const validatedCur = pgSchema.parse(sch2);
1393
-
1394
- const renames = new Set(renamesArr);
1395
-
1396
- if (!cli) {
1397
- const { sqlStatements, statements } = await applyPgSnapshotsDiff(
1398
- sn1,
1399
- sn2,
1400
- testSchemasResolver(renames),
1401
- testDomainsResolver(renames),
1402
- testEnumsResolver(renames),
1403
- testSequencesResolver(renames),
1404
- testPolicyResolver(renames),
1405
- testIndPolicyResolver(renames),
1406
- testRolesResolver(renames),
1407
- testTablesResolver(renames),
1408
- testColumnsResolver(renames),
1409
- testViewsResolver(renames),
1410
- validatedPrev,
1411
- validatedCur,
1412
- );
1413
- return { sqlStatements, statements };
1414
- } else {
1415
- const { sqlStatements, statements } = await applyPgSnapshotsDiff(
1416
- sn1,
1417
- sn2,
1418
- schemasResolver,
1419
- domainsResolver,
1420
- enumsResolver,
1421
- sequencesResolver,
1422
- policyResolver,
1423
- indPolicyResolver,
1424
- roleResolver,
1425
- tablesResolver,
1426
- columnsResolver,
1427
- viewsResolver,
1428
- validatedPrev,
1429
- validatedCur,
1430
- );
1431
- return { sqlStatements, statements };
1432
- }
1433
- };
1434
-
1435
- export const diffTestSchemasPushMysql = async (
1436
- client: Connection,
1437
- left: MysqlSchema,
1438
- right: MysqlSchema,
1439
- renamesArr: string[],
1440
- schema: string,
1441
- cli: boolean = false,
1442
- casing?: CasingType | undefined,
1443
- ) => {
1444
- const { sqlStatements } = await applyMySqlDiffs(left, casing);
1445
- for (const st of sqlStatements) {
1446
- await client.query(st);
1447
- }
1448
- // do introspect into PgSchemaInternal
1449
- const introspectedSchema = await fromMySqlDatabase(
1450
- {
1451
- query: async (sql: string, params?: any[]) => {
1452
- const res = await client.execute(sql, params);
1453
- return res[0] as any;
1454
- },
1455
- },
1456
- schema,
1457
- );
1458
-
1459
- const leftTables = Object.values(right).filter((it) => is(it, MySqlTable)) as MySqlTable[];
1460
-
1461
- const leftViews = Object.values(right).filter((it) => is(it, MySqlView)) as MySqlView[];
1462
-
1463
- const serialized2 = generateMySqlSnapshot(leftTables, leftViews, casing);
1464
-
1465
- const { version: v1, dialect: d1, ...rest1 } = introspectedSchema;
1466
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1467
-
1468
- const sch1 = {
1469
- version: '5',
1470
- dialect: 'mysql',
1471
- id: '0',
1472
- prevId: '0',
1473
- ...rest1,
1474
- } as const;
1475
-
1476
- const sch2 = {
1477
- version: '5',
1478
- dialect: 'mysql',
1479
- id: '0',
1480
- prevId: '0',
1481
- ...rest2,
1482
- } as const;
1483
-
1484
- const sn1 = squashMysqlScheme(sch1);
1485
- const sn2 = squashMysqlScheme(sch2);
1486
-
1487
- const validatedPrev = mysqlSchema.parse(sch1);
1488
- const validatedCur = mysqlSchema.parse(sch2);
1489
-
1490
- const renames = new Set(renamesArr);
1491
-
1492
- if (!cli) {
1493
- const { sqlStatements, statements } = await applyMysqlSnapshotsDiff(
1494
- sn1,
1495
- sn2,
1496
- testTablesResolver(renames),
1497
- testColumnsResolver(renames),
1498
- testViewsResolverMySql(renames),
1499
- validatedPrev,
1500
- validatedCur,
1501
- 'push',
1502
- );
1503
- return { sqlStatements, statements };
1504
- } else {
1505
- const { sqlStatements, statements } = await applyMysqlSnapshotsDiff(
1506
- sn1,
1507
- sn2,
1508
- tablesResolver,
1509
- columnsResolver,
1510
- mySqlViewsResolver,
1511
- validatedPrev,
1512
- validatedCur,
1513
- 'push',
1514
- );
1515
- return { sqlStatements, statements };
1516
- }
1517
- };
1518
-
1519
- export const applyMySqlDiffs = async (
1520
- sn: MysqlSchema,
1521
- casing: CasingType | undefined,
1522
- ) => {
1523
- const dryRun = {
1524
- version: '5',
1525
- dialect: 'mysql',
1526
- id: '0',
1527
- prevId: '0',
1528
- views: {},
1529
- tables: {},
1530
- enums: {},
1531
- schemas: {},
1532
- _meta: {
1533
- schemas: {},
1534
- tables: {},
1535
- columns: {},
1536
- },
1537
- } as const;
1538
-
1539
- const tables = Object.values(sn).filter((it) => is(it, MySqlTable)) as MySqlTable[];
1540
-
1541
- const views = Object.values(sn).filter((it) => is(it, MySqlView)) as MySqlView[];
1542
-
1543
- const serialized1 = generateMySqlSnapshot(tables, views, casing);
1544
-
1545
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
1546
-
1547
- const sch1 = {
1548
- version: '5',
1549
- dialect: 'mysql',
1550
- id: '0',
1551
- prevId: '0',
1552
- ...rest1,
1553
- } as const;
1554
-
1555
- const sn1 = squashMysqlScheme(sch1);
1556
-
1557
- const validatedPrev = mysqlSchema.parse(dryRun);
1558
- const validatedCur = mysqlSchema.parse(sch1);
1559
-
1560
- const { sqlStatements, statements } = await applyMysqlSnapshotsDiff(
1561
- dryRun,
1562
- sn1,
1563
- testTablesResolver(new Set()),
1564
- testColumnsResolver(new Set()),
1565
- testViewsResolverMySql(new Set()),
1566
- validatedPrev,
1567
- validatedCur,
1568
- );
1569
- return { sqlStatements, statements };
1570
- };
1571
-
1572
- export const diffTestSchemasMysql = async (
1573
- left: MysqlSchema,
1574
- right: MysqlSchema,
1575
- renamesArr: string[],
1576
- cli: boolean = false,
1577
- casing?: CasingType | undefined,
1578
- ) => {
1579
- const leftTables = Object.values(left).filter((it) => is(it, MySqlTable)) as MySqlTable[];
1580
-
1581
- const leftViews = Object.values(left).filter((it) => is(it, MySqlView)) as MySqlView[];
1582
-
1583
- const rightTables = Object.values(right).filter((it) => is(it, MySqlTable)) as MySqlTable[];
1584
-
1585
- const rightViews = Object.values(right).filter((it) => is(it, MySqlView)) as MySqlView[];
1586
-
1587
- const serialized1 = generateMySqlSnapshot(leftTables, leftViews, casing);
1588
- const serialized2 = generateMySqlSnapshot(rightTables, rightViews, casing);
1589
-
1590
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
1591
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1592
-
1593
- const sch1 = {
1594
- version: '5',
1595
- dialect: 'mysql',
1596
- id: '0',
1597
- prevId: '0',
1598
- ...rest1,
1599
- } as const;
1600
-
1601
- const sch2 = {
1602
- version: '5',
1603
- dialect: 'mysql',
1604
- id: '0',
1605
- prevId: '0',
1606
- ...rest2,
1607
- } as const;
1608
-
1609
- const sn1 = squashMysqlScheme(sch1);
1610
- const sn2 = squashMysqlScheme(sch2);
1611
-
1612
- const validatedPrev = mysqlSchema.parse(sch1);
1613
- const validatedCur = mysqlSchema.parse(sch2);
1614
-
1615
- const renames = new Set(renamesArr);
1616
-
1617
- if (!cli) {
1618
- const { sqlStatements, statements } = await applyMysqlSnapshotsDiff(
1619
- sn1,
1620
- sn2,
1621
- testTablesResolver(renames),
1622
- testColumnsResolver(renames),
1623
- testViewsResolverMySql(renames),
1624
- validatedPrev,
1625
- validatedCur,
1626
- );
1627
- return { sqlStatements, statements };
1628
- }
1629
-
1630
- const { sqlStatements, statements } = await applyMysqlSnapshotsDiff(
1631
- sn1,
1632
- sn2,
1633
- tablesResolver,
1634
- columnsResolver,
1635
- mySqlViewsResolver,
1636
- validatedPrev,
1637
- validatedCur,
1638
- );
1639
- return { sqlStatements, statements };
1640
- };
1641
-
1642
- export const diffTestSchemasSingleStore = async (
1643
- left: SinglestoreSchema,
1644
- right: SinglestoreSchema,
1645
- renamesArr: string[],
1646
- cli: boolean = false,
1647
- casing?: CasingType | undefined,
1648
- ) => {
1649
- const leftTables = Object.values(left).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[];
1650
-
1651
- /* const leftViews = Object.values(left).filter((it) => is(it, SingleStoreView)) as SingleStoreView[]; */
1652
-
1653
- const rightTables = Object.values(right).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[];
1654
-
1655
- /* const rightViews = Object.values(right).filter((it) => is(it, SingleStoreView)) as SingleStoreView[]; */
1656
-
1657
- const serialized1 = generateSingleStoreSnapshot(
1658
- leftTables,
1659
- /* leftViews, */
1660
- casing,
1661
- );
1662
- const serialized2 = generateSingleStoreSnapshot(
1663
- rightTables,
1664
- /* rightViews, */
1665
- casing,
1666
- );
1667
-
1668
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
1669
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1670
-
1671
- const sch1 = {
1672
- version: '1',
1673
- dialect: 'singlestore',
1674
- id: '0',
1675
- prevId: '0',
1676
- ...rest1,
1677
- } as const;
1678
-
1679
- const sch2 = {
1680
- version: '1',
1681
- dialect: 'singlestore',
1682
- id: '0',
1683
- prevId: '0',
1684
- ...rest2,
1685
- } as const;
1686
-
1687
- const sn1 = squashSingleStoreScheme(sch1);
1688
- const sn2 = squashSingleStoreScheme(sch2);
1689
-
1690
- const validatedPrev = singlestoreSchema.parse(sch1);
1691
- const validatedCur = singlestoreSchema.parse(sch2);
1692
-
1693
- const renames = new Set(renamesArr);
1694
-
1695
- if (!cli) {
1696
- const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff(
1697
- sn1,
1698
- sn2,
1699
- testTablesResolver(renames),
1700
- testColumnsResolver(renames),
1701
- /* testViewsResolverSingleStore(renames), */
1702
- validatedPrev,
1703
- validatedCur,
1704
- );
1705
- return { sqlStatements, statements };
1706
- }
1707
-
1708
- const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff(
1709
- sn1,
1710
- sn2,
1711
- tablesResolver,
1712
- columnsResolver,
1713
- /* singleStoreViewsResolver, */
1714
- validatedPrev,
1715
- validatedCur,
1716
- );
1717
- return { sqlStatements, statements };
1718
- };
1719
-
1720
- export const diffTestSchemasPushSingleStore = async (
1721
- client: Connection,
1722
- left: SinglestoreSchema,
1723
- right: SinglestoreSchema,
1724
- renamesArr: string[],
1725
- schema: string,
1726
- cli: boolean = false,
1727
- casing?: CasingType | undefined,
1728
- sqlStatementsToRun: {
1729
- before?: string[];
1730
- after?: string[];
1731
- runApply?: boolean;
1732
- } = {
1733
- before: [],
1734
- after: [],
1735
- runApply: true,
1736
- },
1737
- ) => {
1738
- const shouldRunApply = sqlStatementsToRun.runApply === undefined
1739
- ? true
1740
- : sqlStatementsToRun.runApply;
1741
-
1742
- for (const st of sqlStatementsToRun.before ?? []) {
1743
- await client.query(st);
1744
- }
1745
-
1746
- if (shouldRunApply) {
1747
- const res = await applySingleStoreDiffs(left, casing);
1748
- for (const st of res.sqlStatements) {
1749
- await client.query(st);
1750
- }
1751
- }
1752
-
1753
- for (const st of sqlStatementsToRun.after ?? []) {
1754
- await client.query(st);
1755
- }
1756
-
1757
- // do introspect into PgSchemaInternal
1758
- const introspectedSchema = await fromSingleStoreDatabase(
1759
- {
1760
- query: async (sql: string, params?: any[]) => {
1761
- const res = await client.execute(sql, params);
1762
- return res[0] as any;
1763
- },
1764
- },
1765
- schema,
1766
- );
1767
-
1768
- const leftTables = Object.values(right).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[];
1769
-
1770
- /* const leftViews = Object.values(right).filter((it) => is(it, SingleStoreView)) as SingleStoreView[]; */
1771
-
1772
- const serialized2 = generateSingleStoreSnapshot(
1773
- leftTables,
1774
- /* leftViews, */
1775
- casing,
1776
- );
1777
-
1778
- const { version: v1, dialect: d1, ...rest1 } = introspectedSchema;
1779
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1780
-
1781
- const sch1 = {
1782
- version: '1',
1783
- dialect: 'singlestore',
1784
- id: '0',
1785
- prevId: '0',
1786
- ...rest1,
1787
- } as const;
1788
-
1789
- const sch2 = {
1790
- version: '1',
1791
- dialect: 'singlestore',
1792
- id: '0',
1793
- prevId: '0',
1794
- ...rest2,
1795
- } as const;
1796
-
1797
- const sn1 = squashSingleStoreScheme(sch1);
1798
- const sn2 = squashSingleStoreScheme(sch2);
1799
-
1800
- const validatedPrev = singlestoreSchema.parse(sch1);
1801
- const validatedCur = singlestoreSchema.parse(sch2);
1802
-
1803
- const renames = new Set(renamesArr);
1804
-
1805
- if (!cli) {
1806
- const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff(
1807
- sn1,
1808
- sn2,
1809
- testTablesResolver(renames),
1810
- testColumnsResolver(renames),
1811
- /* testViewsResolverSingleStore(renames), */
1812
- validatedPrev,
1813
- validatedCur,
1814
- 'push',
1815
- );
1816
-
1817
- const {
1818
- statementsToExecute,
1819
- columnsToRemove,
1820
- infoToPrint,
1821
- shouldAskForApprove,
1822
- tablesToRemove,
1823
- tablesToTruncate,
1824
- } = await singleStoreLogSuggestionsAndReturn(
1825
- {
1826
- query: async <T>(sql: string, params?: any[]) => {
1827
- const res = await client.execute(sql, params);
1828
- return res[0] as T[];
1829
- },
1830
- },
1831
- statements,
1832
- sn1,
1833
- sn2,
1834
- );
1835
-
1836
- return {
1837
- sqlStatements: statementsToExecute,
1838
- statements,
1839
- columnsToRemove,
1840
- infoToPrint,
1841
- shouldAskForApprove,
1842
- tablesToRemove,
1843
- tablesToTruncate,
1844
- };
1845
- } else {
1846
- const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff(
1847
- sn1,
1848
- sn2,
1849
- tablesResolver,
1850
- columnsResolver,
1851
- /* singleStoreViewsResolver, */
1852
- validatedPrev,
1853
- validatedCur,
1854
- 'push',
1855
- );
1856
- return { sqlStatements, statements };
1857
- }
1858
- };
1859
-
1860
- export const applySingleStoreDiffs = async (
1861
- sn: SinglestoreSchema,
1862
- casing: CasingType | undefined,
1863
- ) => {
1864
- const dryRun = {
1865
- version: '1',
1866
- dialect: 'singlestore',
1867
- id: '0',
1868
- prevId: '0',
1869
- tables: {},
1870
- views: {},
1871
- enums: {},
1872
- schemas: {},
1873
- _meta: {
1874
- schemas: {},
1875
- tables: {},
1876
- columns: {},
1877
- },
1878
- } as const;
1879
-
1880
- const tables = Object.values(sn).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[];
1881
-
1882
- /* const views = Object.values(sn).filter((it) => is(it, SingleStoreView)) as SingleStoreView[]; */
1883
-
1884
- const serialized1 = generateSingleStoreSnapshot(tables, /* views, */ casing);
1885
-
1886
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
1887
-
1888
- const sch1 = {
1889
- version: '1',
1890
- dialect: 'singlestore',
1891
- id: '0',
1892
- prevId: '0',
1893
- ...rest1,
1894
- } as const;
1895
-
1896
- const sn1 = squashSingleStoreScheme(sch1);
1897
-
1898
- const validatedPrev = singlestoreSchema.parse(dryRun);
1899
- const validatedCur = singlestoreSchema.parse(sch1);
1900
-
1901
- const { sqlStatements, statements } = await applySingleStoreSnapshotsDiff(
1902
- dryRun,
1903
- sn1,
1904
- testTablesResolver(new Set()),
1905
- testColumnsResolver(new Set()),
1906
- /* testViewsResolverSingleStore(new Set()), */
1907
- validatedPrev,
1908
- validatedCur,
1909
- );
1910
- return { sqlStatements, statements };
1911
- };
1912
-
1913
- export const diffTestSchemasPushSqlite = async (
1914
- client: Database,
1915
- left: SqliteSchema,
1916
- right: SqliteSchema,
1917
- renamesArr: string[],
1918
- cli: boolean = false,
1919
- seedStatements: string[] = [],
1920
- casing?: CasingType | undefined,
1921
- ) => {
1922
- const { sqlStatements } = await applySqliteDiffs(left, 'push');
1923
-
1924
- for (const st of sqlStatements) {
1925
- client.exec(st);
1926
- }
1927
-
1928
- for (const st of seedStatements) {
1929
- client.exec(st);
1930
- }
1931
-
1932
- // do introspect into PgSchemaInternal
1933
- const introspectedSchema = await fromSqliteDatabase(
1934
- {
1935
- query: async <T>(sql: string, params: any[] = []) => {
1936
- return client.prepare(sql).bind(params).all() as T[];
1937
- },
1938
- run: async (query: string) => {
1939
- client.prepare(query).run();
1940
- },
1941
- },
1942
- undefined,
1943
- );
1944
-
1945
- const rightTables = Object.values(right).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
1946
-
1947
- const rightViews = Object.values(right).filter((it) => is(it, SQLiteView)) as SQLiteView[];
1948
-
1949
- const serialized2 = generateSqliteSnapshot(rightTables, rightViews, casing);
1950
-
1951
- const { version: v1, dialect: d1, ...rest1 } = introspectedSchema;
1952
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
1953
-
1954
- const sch1 = {
1955
- version: '6',
1956
- dialect: 'sqlite',
1957
- id: '0',
1958
- prevId: '0',
1959
- ...rest1,
1960
- } as const;
1961
-
1962
- const sch2 = {
1963
- version: '6',
1964
- dialect: 'sqlite',
1965
- id: '0',
1966
- prevId: '0',
1967
- ...rest2,
1968
- } as const;
1969
-
1970
- const sn1 = squashSqliteScheme(sch1, 'push');
1971
- const sn2 = squashSqliteScheme(sch2, 'push');
1972
-
1973
- const renames = new Set(renamesArr);
1974
-
1975
- if (!cli) {
1976
- const { sqlStatements, statements, _meta } = await applySqliteSnapshotsDiff(
1977
- sn1,
1978
- sn2,
1979
- testTablesResolver(renames),
1980
- testColumnsResolver(renames),
1981
- testViewsResolverSqlite(renames),
1982
- sch1,
1983
- sch2,
1984
- 'push',
1985
- );
1986
-
1987
- const {
1988
- statementsToExecute,
1989
- columnsToRemove,
1990
- infoToPrint,
1991
- schemasToRemove,
1992
- shouldAskForApprove,
1993
- tablesToRemove,
1994
- tablesToTruncate,
1995
- } = await logSuggestionsAndReturn(
1996
- {
1997
- query: async <T>(sql: string, params: any[] = []) => {
1998
- return client.prepare(sql).bind(params).all() as T[];
1999
- },
2000
- run: async (query: string) => {
2001
- client.prepare(query).run();
2002
- },
2003
- },
2004
- statements,
2005
- sn1,
2006
- sn2,
2007
- _meta!,
2008
- );
2009
-
2010
- return {
2011
- sqlStatements: statementsToExecute,
2012
- statements,
2013
- columnsToRemove,
2014
- infoToPrint,
2015
- schemasToRemove,
2016
- shouldAskForApprove,
2017
- tablesToRemove,
2018
- tablesToTruncate,
2019
- };
2020
- } else {
2021
- const { sqlStatements, statements } = await applySqliteSnapshotsDiff(
2022
- sn1,
2023
- sn2,
2024
- tablesResolver,
2025
- columnsResolver,
2026
- sqliteViewsResolver,
2027
- sch1,
2028
- sch2,
2029
- 'push',
2030
- );
2031
- return { sqlStatements, statements };
2032
- }
2033
- };
2034
-
2035
- export async function diffTestSchemasPushLibSQL(
2036
- client: Client,
2037
- left: SqliteSchema,
2038
- right: SqliteSchema,
2039
- renamesArr: string[],
2040
- cli: boolean = false,
2041
- seedStatements: string[] = [],
2042
- casing?: CasingType | undefined,
2043
- ) {
2044
- const { sqlStatements } = await applyLibSQLDiffs(left, 'push');
2045
-
2046
- for (const st of sqlStatements) {
2047
- await client.execute(st);
2048
- }
2049
-
2050
- for (const st of seedStatements) {
2051
- await client.execute(st);
2052
- }
2053
-
2054
- const introspectedSchema = await fromSqliteDatabase(
2055
- {
2056
- query: async <T>(sql: string, params?: any[]) => {
2057
- const res = await client.execute({ sql, args: params || [] });
2058
- return res.rows as T[];
2059
- },
2060
- run: async (query: string) => {
2061
- await client.execute(query);
2062
- },
2063
- },
2064
- undefined,
2065
- );
2066
-
2067
- const leftTables = Object.values(right).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2068
-
2069
- const leftViews = Object.values(right).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2070
-
2071
- const serialized2 = generateSqliteSnapshot(leftTables, leftViews, casing);
2072
-
2073
- const { version: v1, dialect: d1, ...rest1 } = introspectedSchema;
2074
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
2075
-
2076
- const sch1 = {
2077
- version: '6',
2078
- dialect: 'sqlite',
2079
- id: '0',
2080
- prevId: '0',
2081
- ...rest1,
2082
- } as const;
2083
-
2084
- const sch2 = {
2085
- version: '6',
2086
- dialect: 'sqlite',
2087
- id: '0',
2088
- prevId: '0',
2089
- ...rest2,
2090
- } as const;
2091
-
2092
- const sn1 = squashSqliteScheme(sch1, 'push');
2093
- const sn2 = squashSqliteScheme(sch2, 'push');
2094
-
2095
- const renames = new Set(renamesArr);
2096
-
2097
- if (!cli) {
2098
- const { sqlStatements, statements, _meta } = await applyLibSQLSnapshotsDiff(
2099
- sn1,
2100
- sn2,
2101
- testTablesResolver(renames),
2102
- testColumnsResolver(renames),
2103
- testViewsResolverSqlite(renames),
2104
- sch1,
2105
- sch2,
2106
- 'push',
2107
- );
2108
-
2109
- const {
2110
- statementsToExecute,
2111
- columnsToRemove,
2112
- infoToPrint,
2113
- shouldAskForApprove,
2114
- tablesToRemove,
2115
- tablesToTruncate,
2116
- } = await libSqlLogSuggestionsAndReturn(
2117
- {
2118
- query: async <T>(sql: string, params?: any[]) => {
2119
- const res = await client.execute({ sql, args: params || [] });
2120
- return res.rows as T[];
2121
- },
2122
- run: async (query: string) => {
2123
- await client.execute(query);
2124
- },
2125
- },
2126
- statements,
2127
- sn1,
2128
- sn2,
2129
- _meta!,
2130
- );
2131
-
2132
- return {
2133
- sqlStatements: statementsToExecute,
2134
- statements,
2135
- columnsToRemove,
2136
- infoToPrint,
2137
- shouldAskForApprove,
2138
- tablesToRemove,
2139
- tablesToTruncate,
2140
- };
2141
- } else {
2142
- const { sqlStatements, statements } = await applyLibSQLSnapshotsDiff(
2143
- sn1,
2144
- sn2,
2145
- tablesResolver,
2146
- columnsResolver,
2147
- sqliteViewsResolver,
2148
- sch1,
2149
- sch2,
2150
- 'push',
2151
- );
2152
- return { sqlStatements, statements };
2153
- }
2154
- }
2155
-
2156
- export const applySqliteDiffs = async (
2157
- sn: SqliteSchema,
2158
- action?: 'push' | undefined,
2159
- casing?: CasingType | undefined,
2160
- ) => {
2161
- const dryRun = {
2162
- version: '6',
2163
- dialect: 'sqlite',
2164
- id: '0',
2165
- prevId: '0',
2166
- tables: {},
2167
- enums: {},
2168
- views: {},
2169
- schemas: {},
2170
- _meta: {
2171
- schemas: {},
2172
- tables: {},
2173
- columns: {},
2174
- },
2175
- } as const;
2176
-
2177
- const tables = Object.values(sn).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2178
-
2179
- const views = Object.values(sn).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2180
-
2181
- const serialized1 = generateSqliteSnapshot(tables, views, casing);
2182
-
2183
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
2184
-
2185
- const sch1 = {
2186
- version: '6',
2187
- dialect: 'sqlite',
2188
- id: '0',
2189
- prevId: '0',
2190
- ...rest1,
2191
- } as const;
2192
-
2193
- const sn1 = squashSqliteScheme(sch1, action);
2194
-
2195
- const { sqlStatements, statements } = await applySqliteSnapshotsDiff(
2196
- dryRun,
2197
- sn1,
2198
- testTablesResolver(new Set()),
2199
- testColumnsResolver(new Set()),
2200
- testViewsResolverSqlite(new Set()),
2201
- dryRun,
2202
- sch1,
2203
- action,
2204
- );
2205
-
2206
- return { sqlStatements, statements };
2207
- };
2208
-
2209
- export const applyLibSQLDiffs = async (
2210
- sn: SqliteSchema,
2211
- action?: 'push' | undefined,
2212
- casing?: CasingType | undefined,
2213
- ) => {
2214
- const dryRun = {
2215
- version: '6',
2216
- dialect: 'sqlite',
2217
- id: '0',
2218
- prevId: '0',
2219
- tables: {},
2220
- views: {},
2221
- enums: {},
2222
- schemas: {},
2223
- _meta: {
2224
- schemas: {},
2225
- tables: {},
2226
- columns: {},
2227
- },
2228
- } as const;
2229
-
2230
- const tables = Object.values(sn).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2231
-
2232
- const views = Object.values(sn).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2233
-
2234
- const serialized1 = generateSqliteSnapshot(tables, views, casing);
2235
-
2236
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
2237
-
2238
- const sch1 = {
2239
- version: '6',
2240
- dialect: 'sqlite',
2241
- id: '0',
2242
- prevId: '0',
2243
- ...rest1,
2244
- } as const;
2245
-
2246
- const sn1 = squashSqliteScheme(sch1, action);
2247
-
2248
- const { sqlStatements, statements } = await applyLibSQLSnapshotsDiff(
2249
- dryRun,
2250
- sn1,
2251
- testTablesResolver(new Set()),
2252
- testColumnsResolver(new Set()),
2253
- testViewsResolverSqlite(new Set()),
2254
- dryRun,
2255
- sch1,
2256
- action,
2257
- );
2258
-
2259
- return { sqlStatements, statements };
2260
- };
2261
-
2262
- export const diffTestSchemasSqlite = async (
2263
- left: SqliteSchema,
2264
- right: SqliteSchema,
2265
- renamesArr: string[],
2266
- cli: boolean = false,
2267
- casing?: CasingType | undefined,
2268
- ) => {
2269
- const leftTables = Object.values(left).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2270
-
2271
- const leftViews = Object.values(left).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2272
-
2273
- const rightTables = Object.values(right).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2274
-
2275
- const rightViews = Object.values(right).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2276
-
2277
- const serialized1 = generateSqliteSnapshot(leftTables, leftViews, casing);
2278
- const serialized2 = generateSqliteSnapshot(rightTables, rightViews, casing);
2279
-
2280
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
2281
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
2282
-
2283
- const sch1 = {
2284
- version: '6',
2285
- dialect: 'sqlite',
2286
- id: '0',
2287
- prevId: '0',
2288
- ...rest1,
2289
- } as const;
2290
-
2291
- const sch2 = {
2292
- version: '6',
2293
- dialect: 'sqlite',
2294
- id: '0',
2295
- prevId: '0',
2296
- ...rest2,
2297
- } as const;
2298
-
2299
- const sn1 = squashSqliteScheme(sch1);
2300
- const sn2 = squashSqliteScheme(sch2);
2301
-
2302
- const renames = new Set(renamesArr);
2303
-
2304
- if (!cli) {
2305
- const { sqlStatements, statements } = await applySqliteSnapshotsDiff(
2306
- sn1,
2307
- sn2,
2308
- testTablesResolver(renames),
2309
- testColumnsResolver(renames),
2310
- testViewsResolverSqlite(renames),
2311
- sch1,
2312
- sch2,
2313
- );
2314
- return { sqlStatements, statements };
2315
- }
2316
-
2317
- const { sqlStatements, statements } = await applySqliteSnapshotsDiff(
2318
- sn1,
2319
- sn2,
2320
- tablesResolver,
2321
- columnsResolver,
2322
- sqliteViewsResolver,
2323
- sch1,
2324
- sch2,
2325
- );
2326
- return { sqlStatements, statements };
2327
- };
2328
-
2329
- export const diffTestSchemasLibSQL = async (
2330
- left: SqliteSchema,
2331
- right: SqliteSchema,
2332
- renamesArr: string[],
2333
- cli: boolean = false,
2334
- casing?: CasingType | undefined,
2335
- ) => {
2336
- const leftTables = Object.values(left).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2337
-
2338
- const leftViews = Object.values(left).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2339
-
2340
- const rightTables = Object.values(right).filter((it) => is(it, SQLiteTable)) as SQLiteTable[];
2341
-
2342
- const rightViews = Object.values(right).filter((it) => is(it, SQLiteView)) as SQLiteView[];
2343
-
2344
- const serialized1 = generateSqliteSnapshot(leftTables, leftViews, casing);
2345
- const serialized2 = generateSqliteSnapshot(rightTables, rightViews, casing);
2346
-
2347
- const { version: v1, dialect: d1, ...rest1 } = serialized1;
2348
- const { version: v2, dialect: d2, ...rest2 } = serialized2;
2349
-
2350
- const sch1 = {
2351
- version: '6',
2352
- dialect: 'sqlite',
2353
- id: '0',
2354
- prevId: '0',
2355
- ...rest1,
2356
- } as const;
2357
-
2358
- const sch2 = {
2359
- version: '6',
2360
- dialect: 'sqlite',
2361
- id: '0',
2362
- prevId: '0',
2363
- ...rest2,
2364
- } as const;
2365
-
2366
- const sn1 = squashSqliteScheme(sch1);
2367
- const sn2 = squashSqliteScheme(sch2);
2368
-
2369
- const renames = new Set(renamesArr);
2370
-
2371
- if (!cli) {
2372
- const { sqlStatements, statements } = await applyLibSQLSnapshotsDiff(
2373
- sn1,
2374
- sn2,
2375
- testTablesResolver(renames),
2376
- testColumnsResolver(renames),
2377
- testViewsResolverSqlite(renames),
2378
- sch1,
2379
- sch2,
2380
- );
2381
- return { sqlStatements, statements };
2382
- }
2383
-
2384
- const { sqlStatements, statements } = await applyLibSQLSnapshotsDiff(
2385
- sn1,
2386
- sn2,
2387
- tablesResolver,
2388
- columnsResolver,
2389
- sqliteViewsResolver,
2390
- sch1,
2391
- sch2,
2392
- );
2393
- return { sqlStatements, statements };
2394
- };
2395
-
2396
- // --- Introspect to file helpers ---
2397
-
2398
- export const introspectPgToFile = async (
2399
- client: PGlite,
2400
- initSchema: PostgresSchema,
2401
- testName: string,
2402
- schemas: string[] = ['public'],
2403
- entities?: Entities,
2404
- casing?: CasingType | undefined,
2405
- ) => {
2406
- // put in db
2407
- const { sqlStatements } = await applyPgDiffs(initSchema, casing);
2408
- for (const st of sqlStatements) {
2409
- await client.query(st);
2410
- }
2411
-
2412
- // introspect to schema
2413
- const introspectedSchema = await fromDatabase(
2414
- {
2415
- query: async (query: string, values?: any[] | undefined) => {
2416
- const res = await client.query(query, values);
2417
- return res.rows as any[];
2418
- },
2419
- },
2420
- undefined,
2421
- schemas,
2422
- entities,
2423
- );
2424
-
2425
- const { version: initV, dialect: initD, ...initRest } = introspectedSchema;
2426
-
2427
- const initSch = {
2428
- version: snapshotVersion,
2429
- dialect: 'postgresql',
2430
- id: '0',
2431
- prevId: '0',
2432
- ...initRest,
2433
- } as const;
2434
-
2435
- const initSn = squashPgScheme(initSch);
2436
- const validatedCur = pgSchema.parse(initSch);
2437
-
2438
- // write to ts file
2439
- const file = schemaToTypeScript(introspectedSchema, 'camel');
2440
-
2441
- fs.writeFileSync(`tests/introspect/postgres/${testName}.ts`, file.file);
2442
-
2443
- // generate snapshot from ts file
2444
- const response = await prepareFromPgImports([
2445
- `tests/introspect/postgres/${testName}.ts`,
2446
- ]);
2447
-
2448
- const afterFileImports = generatePgSnapshot(
2449
- response.tables,
2450
- response.domains,
2451
- response.enums,
2452
- response.schemas,
2453
- response.sequences,
2454
- response.roles,
2455
- response.policies,
2456
- response.views,
2457
- response.matViews,
2458
- casing,
2459
- );
2460
-
2461
- const { version: v2, dialect: d2, ...rest2 } = afterFileImports;
2462
-
2463
- const sch2 = {
2464
- version: snapshotVersion,
2465
- dialect: 'postgresql',
2466
- id: '0',
2467
- prevId: '0',
2468
- ...rest2,
2469
- } as const;
2470
-
2471
- const sn2AfterIm = squashPgScheme(sch2);
2472
- const validatedCurAfterImport = pgSchema.parse(sch2);
2473
-
2474
- const {
2475
- sqlStatements: afterFileSqlStatements,
2476
- statements: afterFileStatements,
2477
- } = await applyPgSnapshotsDiff(
2478
- initSn,
2479
- sn2AfterIm,
2480
- testSchemasResolver(new Set()),
2481
- testDomainsResolver(new Set()),
2482
- testEnumsResolver(new Set()),
2483
- testSequencesResolver(new Set()),
2484
- testPolicyResolver(new Set()),
2485
- testIndPolicyResolver(new Set()),
2486
- testRolesResolver(new Set()),
2487
- testTablesResolver(new Set()),
2488
- testColumnsResolver(new Set()),
2489
- testViewsResolver(new Set()),
2490
- validatedCur,
2491
- validatedCurAfterImport,
2492
- );
2493
-
2494
- fs.rmSync(`tests/introspect/postgres/${testName}.ts`);
2495
-
2496
- return {
2497
- sqlStatements: afterFileSqlStatements,
2498
- statements: afterFileStatements,
2499
- };
2500
- };
2501
-
2502
- export const introspectMySQLToFile = async (
2503
- client: Connection,
2504
- initSchema: MysqlSchema,
2505
- testName: string,
2506
- schema: string,
2507
- casing?: CasingType | undefined,
2508
- ) => {
2509
- // put in db
2510
- const { sqlStatements } = await applyMySqlDiffs(initSchema, casing);
2511
- for (const st of sqlStatements) {
2512
- await client.query(st);
2513
- }
2514
-
2515
- // introspect to schema
2516
- const introspectedSchema = await fromMySqlDatabase(
2517
- {
2518
- query: async (sql: string, params?: any[] | undefined) => {
2519
- const res = await client.execute(sql, params);
2520
- return res[0] as any;
2521
- },
2522
- },
2523
- schema,
2524
- );
2525
-
2526
- const { version: initV, dialect: initD, ...initRest } = introspectedSchema;
2527
-
2528
- const initSch = {
2529
- version: '5',
2530
- dialect: 'mysql',
2531
- id: '0',
2532
- prevId: '0',
2533
- ...initRest,
2534
- } as const;
2535
-
2536
- const initSn = squashMysqlScheme(initSch);
2537
- const validatedCur = mysqlSchema.parse(initSch);
2538
-
2539
- const file = schemaToTypeScriptMySQL(introspectedSchema, 'camel');
2540
-
2541
- fs.writeFileSync(`tests/introspect/mysql/${testName}.ts`, file.file);
2542
-
2543
- const response = await prepareFromMySqlImports([
2544
- `tests/introspect/mysql/${testName}.ts`,
2545
- ]);
2546
-
2547
- const afterFileImports = generateMySqlSnapshot(
2548
- response.tables,
2549
- response.views,
2550
- casing,
2551
- );
2552
-
2553
- const { version: v2, dialect: d2, ...rest2 } = afterFileImports;
2554
-
2555
- const sch2 = {
2556
- version: '5',
2557
- dialect: 'mysql',
2558
- id: '0',
2559
- prevId: '0',
2560
- ...rest2,
2561
- } as const;
2562
-
2563
- const sn2AfterIm = squashMysqlScheme(sch2);
2564
- const validatedCurAfterImport = mysqlSchema.parse(sch2);
2565
-
2566
- const {
2567
- sqlStatements: afterFileSqlStatements,
2568
- statements: afterFileStatements,
2569
- } = await applyMysqlSnapshotsDiff(
2570
- sn2AfterIm,
2571
- initSn,
2572
- testTablesResolver(new Set()),
2573
- testColumnsResolver(new Set()),
2574
- testViewsResolverMySql(new Set()),
2575
- validatedCurAfterImport,
2576
- validatedCur,
2577
- );
2578
-
2579
- fs.rmSync(`tests/introspect/mysql/${testName}.ts`);
2580
-
2581
- return {
2582
- sqlStatements: afterFileSqlStatements,
2583
- statements: afterFileStatements,
2584
- };
2585
- };
2586
-
2587
- export const introspectSingleStoreToFile = async (
2588
- client: Connection,
2589
- initSchema: SinglestoreSchema,
2590
- testName: string,
2591
- schema: string,
2592
- casing?: CasingType | undefined,
2593
- ) => {
2594
- // put in db
2595
- const { sqlStatements } = await applySingleStoreDiffs(initSchema, casing);
2596
- for (const st of sqlStatements) {
2597
- await client.query(st);
2598
- }
2599
-
2600
- // introspect to schema
2601
- const introspectedSchema = await fromSingleStoreDatabase(
2602
- {
2603
- query: async (sql: string, params?: any[] | undefined) => {
2604
- const res = await client.execute(sql, params);
2605
- return res[0] as any;
2606
- },
2607
- },
2608
- schema,
2609
- );
2610
-
2611
- const file = schemaToTypeScriptSingleStore(introspectedSchema, 'camel');
2612
-
2613
- fs.writeFileSync(`tests/introspect/singlestore/${testName}.ts`, file.file);
2614
-
2615
- const response = await prepareFromSingleStoreImports([
2616
- `tests/introspect/singlestore/${testName}.ts`,
2617
- ]);
2618
-
2619
- const afterFileImports = generateSingleStoreSnapshot(
2620
- response.tables,
2621
- /* response.views, */
2622
- casing,
2623
- );
2624
-
2625
- const { version: v2, dialect: d2, ...rest2 } = afterFileImports;
2626
-
2627
- const sch2 = {
2628
- version: '1',
2629
- dialect: 'singlestore',
2630
- id: '0',
2631
- prevId: '0',
2632
- ...rest2,
2633
- } as const;
2634
-
2635
- const sn2AfterIm = squashSingleStoreScheme(sch2);
2636
- const validatedCurAfterImport = singlestoreSchema.parse(sch2);
2637
-
2638
- const leftTables = Object.values(initSchema).filter((it) => is(it, SingleStoreTable)) as SingleStoreTable[];
2639
-
2640
- const initSnapshot = generateSingleStoreSnapshot(
2641
- leftTables,
2642
- /* response.views, */
2643
- casing,
2644
- );
2645
-
2646
- const { version: initV, dialect: initD, ...initRest } = initSnapshot;
2647
-
2648
- const initSch = {
2649
- version: '1',
2650
- dialect: 'singlestore',
2651
- id: '0',
2652
- prevId: '0',
2653
- ...initRest,
2654
- } as const;
2655
-
2656
- const initSn = squashSingleStoreScheme(initSch);
2657
- const validatedCur = singlestoreSchema.parse(initSch);
2658
-
2659
- const {
2660
- sqlStatements: afterFileSqlStatements,
2661
- statements: afterFileStatements,
2662
- } = await applySingleStoreSnapshotsDiff(
2663
- sn2AfterIm,
2664
- initSn,
2665
- testTablesResolver(new Set()),
2666
- testColumnsResolver(new Set()),
2667
- /* testViewsResolverSingleStore(new Set()), */
2668
- validatedCurAfterImport,
2669
- validatedCur,
2670
- );
2671
-
2672
- fs.rmSync(`tests/introspect/singlestore/${testName}.ts`);
2673
-
2674
- return {
2675
- sqlStatements: afterFileSqlStatements,
2676
- statements: afterFileStatements,
2677
- };
2678
- };
2679
-
2680
- export const introspectSQLiteToFile = async (
2681
- client: Database,
2682
- initSchema: SqliteSchema,
2683
- testName: string,
2684
- casing?: CasingType | undefined,
2685
- ) => {
2686
- // put in db
2687
- const { sqlStatements } = await applySqliteDiffs(initSchema);
2688
- for (const st of sqlStatements) {
2689
- client.exec(st);
2690
- }
2691
-
2692
- // introspect to schema
2693
- const introspectedSchema = await fromSqliteDatabase(
2694
- {
2695
- query: async <T>(sql: string, params: any[] = []) => {
2696
- return client.prepare(sql).bind(params).all() as T[];
2697
- },
2698
- run: async (query: string) => {
2699
- client.prepare(query).run();
2700
- },
2701
- },
2702
- undefined,
2703
- );
2704
-
2705
- const { version: initV, dialect: initD, ...initRest } = introspectedSchema;
2706
-
2707
- const initSch = {
2708
- version: '6',
2709
- dialect: 'sqlite',
2710
- id: '0',
2711
- prevId: '0',
2712
- ...initRest,
2713
- } as const;
2714
-
2715
- const initSn = squashSqliteScheme(initSch);
2716
-
2717
- const validatedCur = sqliteSchema.parse(initSch);
2718
-
2719
- const file = schemaToTypeScriptSQLite(introspectedSchema, 'camel');
2720
-
2721
- fs.writeFileSync(`tests/introspect/sqlite/${testName}.ts`, file.file);
2722
-
2723
- const response = await prepareFromSqliteImports([
2724
- `tests/introspect/sqlite/${testName}.ts`,
2725
- ]);
2726
-
2727
- const afterFileImports = generateSqliteSnapshot(
2728
- response.tables,
2729
- response.views,
2730
- casing,
2731
- );
2732
-
2733
- const { version: v2, dialect: d2, ...rest2 } = afterFileImports;
2734
-
2735
- const sch2 = {
2736
- version: '6',
2737
- dialect: 'sqlite',
2738
- id: '0',
2739
- prevId: '0',
2740
- ...rest2,
2741
- } as const;
2742
-
2743
- const sn2AfterIm = squashSqliteScheme(sch2);
2744
- const validatedCurAfterImport = sqliteSchema.parse(sch2);
2745
-
2746
- const {
2747
- sqlStatements: afterFileSqlStatements,
2748
- statements: afterFileStatements,
2749
- } = await applySqliteSnapshotsDiff(
2750
- sn2AfterIm,
2751
- initSn,
2752
- testTablesResolver(new Set()),
2753
- testColumnsResolver(new Set()),
2754
- testViewsResolverSqlite(new Set()),
2755
- validatedCurAfterImport,
2756
- validatedCur,
2757
- );
2758
-
2759
- fs.rmSync(`tests/introspect/sqlite/${testName}.ts`);
2760
-
2761
- return {
2762
- sqlStatements: afterFileSqlStatements,
2763
- statements: afterFileStatements,
2764
- };
2765
- };
2766
-
2767
- export const introspectLibSQLToFile = async (
2768
- client: Client,
2769
- initSchema: SqliteSchema,
2770
- testName: string,
2771
- casing?: CasingType | undefined,
2772
- ) => {
2773
- // put in db
2774
- const { sqlStatements } = await applyLibSQLDiffs(initSchema);
2775
- for (const st of sqlStatements) {
2776
- client.execute(st);
2777
- }
2778
-
2779
- // introspect to schema
2780
- const introspectedSchema = await fromSqliteDatabase(
2781
- {
2782
- query: async <T>(sql: string, params: any[] = []) => {
2783
- return (await client.execute({ sql, args: params })).rows as T[];
2784
- },
2785
- run: async (query: string) => {
2786
- client.execute(query);
2787
- },
2788
- },
2789
- undefined,
2790
- );
2791
-
2792
- const { version: initV, dialect: initD, ...initRest } = introspectedSchema;
2793
-
2794
- const initSch = {
2795
- version: '6',
2796
- dialect: 'sqlite',
2797
- id: '0',
2798
- prevId: '0',
2799
- ...initRest,
2800
- } as const;
2801
-
2802
- const initSn = squashSqliteScheme(initSch);
2803
-
2804
- const validatedCur = sqliteSchema.parse(initSch);
2805
-
2806
- const file = schemaToTypeScriptSQLite(introspectedSchema, 'camel');
2807
-
2808
- fs.writeFileSync(`tests/introspect/libsql/${testName}.ts`, file.file);
2809
-
2810
- const response = await prepareFromSqliteImports([
2811
- `tests/introspect/libsql/${testName}.ts`,
2812
- ]);
2813
-
2814
- const afterFileImports = generateSqliteSnapshot(
2815
- response.tables,
2816
- response.views,
2817
- casing,
2818
- );
2819
-
2820
- const { version: v2, dialect: d2, ...rest2 } = afterFileImports;
2821
-
2822
- const sch2 = {
2823
- version: '6',
2824
- dialect: 'sqlite',
2825
- id: '0',
2826
- prevId: '0',
2827
- ...rest2,
2828
- } as const;
2829
-
2830
- const sn2AfterIm = squashSqliteScheme(sch2);
2831
- const validatedCurAfterImport = sqliteSchema.parse(sch2);
2832
-
2833
- const {
2834
- sqlStatements: afterFileSqlStatements,
2835
- statements: afterFileStatements,
2836
- } = await applyLibSQLSnapshotsDiff(
2837
- sn2AfterIm,
2838
- initSn,
2839
- testTablesResolver(new Set()),
2840
- testColumnsResolver(new Set()),
2841
- testViewsResolverSqlite(new Set()),
2842
- validatedCurAfterImport,
2843
- validatedCur,
2844
- );
2845
-
2846
- fs.rmSync(`tests/introspect/libsql/${testName}.ts`);
2847
-
2848
- return {
2849
- sqlStatements: afterFileSqlStatements,
2850
- statements: afterFileStatements,
2851
- };
2852
- };