@remix-run/data-table 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -74
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/adapter.d.ts +10 -271
- package/dist/lib/adapter.d.ts.map +1 -1
- package/dist/lib/column.d.ts.map +1 -1
- package/dist/lib/column.js +10 -1
- package/dist/lib/migrations/directive.d.ts +12 -0
- package/dist/lib/migrations/directive.d.ts.map +1 -0
- package/dist/lib/migrations/directive.js +28 -0
- package/dist/lib/migrations/directory-name.d.ts +12 -0
- package/dist/lib/migrations/directory-name.d.ts.map +1 -0
- package/dist/lib/migrations/directory-name.js +18 -0
- package/dist/lib/migrations/journal-store.d.ts +1 -1
- package/dist/lib/migrations/journal-store.d.ts.map +1 -1
- package/dist/lib/migrations/journal-store.js +18 -18
- package/dist/lib/migrations/registry.d.ts +1 -1
- package/dist/lib/migrations/registry.js +1 -1
- package/dist/lib/migrations/runner.d.ts +2 -2
- package/dist/lib/migrations/runner.d.ts.map +1 -1
- package/dist/lib/migrations/runner.js +44 -71
- package/dist/lib/migrations-node.d.ts +7 -4
- package/dist/lib/migrations-node.d.ts.map +1 -1
- package/dist/lib/migrations-node.js +52 -41
- package/dist/lib/migrations.d.ts +19 -200
- package/dist/lib/migrations.d.ts.map +1 -1
- package/dist/lib/migrations.js +1 -38
- package/dist/lib/query.d.ts +33 -0
- package/dist/lib/query.d.ts.map +1 -1
- package/dist/lib/query.js +28 -0
- package/dist/lib/sql-helpers.d.ts +1 -7
- package/dist/lib/sql-helpers.d.ts.map +1 -1
- package/dist/lib/sql-helpers.js +0 -16
- package/dist/migrations.d.ts +2 -5
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +1 -3
- package/dist/sql-helpers.d.ts +1 -1
- package/dist/sql-helpers.d.ts.map +1 -1
- package/dist/sql-helpers.js +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -34
- package/src/lib/adapter.ts +10 -330
- package/src/lib/column.ts +14 -2
- package/src/lib/migrations/directive.ts +38 -0
- package/src/lib/migrations/directory-name.ts +23 -0
- package/src/lib/migrations/journal-store.ts +22 -18
- package/src/lib/migrations/registry.ts +1 -1
- package/src/lib/migrations/runner.ts +51 -85
- package/src/lib/migrations-node.ts +58 -38
- package/src/lib/migrations.ts +19 -224
- package/src/lib/query.ts +33 -0
- package/src/lib/sql-helpers.ts +1 -22
- package/src/migrations.ts +3 -13
- package/src/sql-helpers.ts +0 -1
- package/dist/lib/migrations/filename.d.ts +0 -12
- package/dist/lib/migrations/filename.d.ts.map +0 -1
- package/dist/lib/migrations/filename.js +0 -20
- package/dist/lib/migrations/helpers.d.ts +0 -11
- package/dist/lib/migrations/helpers.d.ts.map +0 -1
- package/dist/lib/migrations/helpers.js +0 -77
- package/dist/lib/migrations/schema-api.d.ts +0 -7
- package/dist/lib/migrations/schema-api.d.ts.map +0 -1
- package/dist/lib/migrations/schema-api.js +0 -326
- package/src/lib/migrations/filename.ts +0 -25
- package/src/lib/migrations/helpers.ts +0 -108
- package/src/lib/migrations/schema-api.ts +0 -417
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { createDatabase, createDatabaseWithTransaction } from '../database.ts'
|
|
2
|
-
import type { Database } from '../database.ts'
|
|
3
1
|
import type { DatabaseAdapter, TransactionToken } from '../adapter.ts'
|
|
4
|
-
import type { SqlStatement } from '../sql.ts'
|
|
5
2
|
import type {
|
|
6
3
|
MigrateOptions,
|
|
7
4
|
MigrateResult,
|
|
8
|
-
MigrationContext,
|
|
9
5
|
MigrationDescriptor,
|
|
10
6
|
MigrationDirection,
|
|
11
7
|
MigrationJournalRow,
|
|
@@ -14,8 +10,10 @@ import type {
|
|
|
14
10
|
MigrationRunnerOptions,
|
|
15
11
|
MigrationStatus,
|
|
16
12
|
MigrationStatusEntry,
|
|
13
|
+
MigrationTransactionMode,
|
|
17
14
|
} from '../migrations.ts'
|
|
18
15
|
|
|
16
|
+
import { parseTransactionDirective } from './directive.ts'
|
|
19
17
|
import {
|
|
20
18
|
deleteJournalRow,
|
|
21
19
|
ensureMigrationJournal,
|
|
@@ -23,10 +21,9 @@ import {
|
|
|
23
21
|
hasMigrationJournal,
|
|
24
22
|
insertJournalRow,
|
|
25
23
|
loadJournalRows,
|
|
26
|
-
|
|
24
|
+
computeChecksum,
|
|
27
25
|
} from './journal-store.ts'
|
|
28
26
|
import { resolveMigrations } from './registry.ts'
|
|
29
|
-
import { createMigrationSchema } from './schema-api.ts'
|
|
30
27
|
|
|
31
28
|
type RunMigrationsInput = {
|
|
32
29
|
adapter: DatabaseAdapter
|
|
@@ -64,10 +61,10 @@ function assertTargetOption(migrations: MigrationDescriptor[], to: string | unde
|
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
63
|
|
|
67
|
-
function assertNoMigrationDrift(
|
|
64
|
+
async function assertNoMigrationDrift(
|
|
68
65
|
migrations: MigrationDescriptor[],
|
|
69
66
|
journal: MigrationJournalRow[],
|
|
70
|
-
): void {
|
|
67
|
+
): Promise<void> {
|
|
71
68
|
let migrationMap = new Map(migrations.map((migration) => [migration.id, migration]))
|
|
72
69
|
|
|
73
70
|
for (let row of journal) {
|
|
@@ -77,7 +74,7 @@ function assertNoMigrationDrift(
|
|
|
77
74
|
continue
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
let expected =
|
|
77
|
+
let expected = await computeChecksum(migration)
|
|
81
78
|
|
|
82
79
|
if (expected !== row.checksum) {
|
|
83
80
|
throw new Error(
|
|
@@ -93,34 +90,18 @@ function assertNoMigrationDrift(
|
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
throw error
|
|
93
|
+
function resolveTransactionMode(migration: MigrationDescriptor): MigrationTransactionMode {
|
|
94
|
+
if (migration.transaction) {
|
|
95
|
+
return migration.transaction
|
|
100
96
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
async hasTable(table) {
|
|
108
|
-
return adapter.hasTable(table)
|
|
109
|
-
},
|
|
110
|
-
async hasColumn(table, column) {
|
|
111
|
-
return adapter.hasColumn(table, column)
|
|
112
|
-
},
|
|
113
|
-
execute: throwDryRunError,
|
|
114
|
-
migrate: throwDryRunError,
|
|
115
|
-
beginTransaction: throwDryRunError,
|
|
116
|
-
commitTransaction: throwDryRunError,
|
|
117
|
-
rollbackTransaction: throwDryRunError,
|
|
118
|
-
createSavepoint: throwDryRunError,
|
|
119
|
-
rollbackToSavepoint: throwDryRunError,
|
|
120
|
-
releaseSavepoint: throwDryRunError,
|
|
97
|
+
|
|
98
|
+
let directive = parseTransactionDirective(migration.up)
|
|
99
|
+
|
|
100
|
+
if (directive) {
|
|
101
|
+
return directive
|
|
121
102
|
}
|
|
122
103
|
|
|
123
|
-
return
|
|
104
|
+
return 'auto'
|
|
124
105
|
}
|
|
125
106
|
|
|
126
107
|
async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult> {
|
|
@@ -135,7 +116,7 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
135
116
|
assertStepOption(step)
|
|
136
117
|
assertTargetOption(migrations, target)
|
|
137
118
|
|
|
138
|
-
let sql:
|
|
119
|
+
let sql: string[] = []
|
|
139
120
|
|
|
140
121
|
await adapter.acquireMigrationLock?.()
|
|
141
122
|
|
|
@@ -154,7 +135,7 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
154
135
|
}
|
|
155
136
|
|
|
156
137
|
let appliedMap = new Map(journal.map((row) => [row.id, row]))
|
|
157
|
-
assertNoMigrationDrift(migrations, journal)
|
|
138
|
+
await assertNoMigrationDrift(migrations, journal)
|
|
158
139
|
let toRun: MigrationDescriptor[] = []
|
|
159
140
|
|
|
160
141
|
if (input.direction === 'up') {
|
|
@@ -172,19 +153,21 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
172
153
|
toRun = toRun.slice(0, step)
|
|
173
154
|
}
|
|
174
155
|
} else {
|
|
175
|
-
|
|
176
|
-
.filter((migration) => appliedMap.has(migration.id))
|
|
177
|
-
.reverse()
|
|
156
|
+
toRun = migrations.filter((migration) => appliedMap.has(migration.id)).reverse()
|
|
178
157
|
|
|
179
158
|
if (target) {
|
|
180
|
-
|
|
159
|
+
toRun = toRun.filter((migration) => migration.id >= target)
|
|
181
160
|
}
|
|
182
161
|
|
|
183
162
|
if (step !== undefined) {
|
|
184
|
-
|
|
163
|
+
toRun = toRun.slice(0, step)
|
|
185
164
|
}
|
|
186
165
|
|
|
187
|
-
toRun
|
|
166
|
+
for (let migration of toRun) {
|
|
167
|
+
if (migration.down === undefined) {
|
|
168
|
+
throw new Error('Migration "' + migration.id + '" has no down script')
|
|
169
|
+
}
|
|
170
|
+
}
|
|
188
171
|
}
|
|
189
172
|
|
|
190
173
|
let applied: MigrationStatusEntry[] = []
|
|
@@ -192,10 +175,10 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
192
175
|
let batch = getBatch(journal)
|
|
193
176
|
|
|
194
177
|
for (let migration of toRun) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
) {
|
|
178
|
+
let script = (input.direction === 'up' ? migration.up : migration.down) as string
|
|
179
|
+
let mode = resolveTransactionMode(migration)
|
|
180
|
+
|
|
181
|
+
if (mode === 'required' && !adapter.capabilities.transactionalDdl) {
|
|
199
182
|
throw new Error(
|
|
200
183
|
'Migration "' +
|
|
201
184
|
migration.id +
|
|
@@ -203,43 +186,23 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
203
186
|
)
|
|
204
187
|
}
|
|
205
188
|
|
|
206
|
-
let shouldUseTransaction =
|
|
207
|
-
!dryRun &&
|
|
208
|
-
migration.migration.transaction !== 'none' &&
|
|
209
|
-
adapter.capabilities.transactionalDdl
|
|
189
|
+
let shouldUseTransaction = !dryRun && mode !== 'none' && adapter.capabilities.transactionalDdl
|
|
210
190
|
let token: TransactionToken | undefined
|
|
211
191
|
|
|
212
192
|
if (shouldUseTransaction) {
|
|
213
193
|
token = await adapter.beginTransaction()
|
|
214
194
|
}
|
|
215
195
|
|
|
216
|
-
|
|
217
|
-
? createDryRunDatabase(adapter)
|
|
218
|
-
: token
|
|
219
|
-
? createDatabaseWithTransaction(adapter, token)
|
|
220
|
-
: createDatabase(adapter)
|
|
221
|
-
|
|
222
|
-
let schema = createMigrationSchema(
|
|
223
|
-
db,
|
|
224
|
-
async (operation) => {
|
|
225
|
-
let compiled = adapter.compileSql(operation)
|
|
226
|
-
sql.push(...compiled)
|
|
196
|
+
sql.push(script)
|
|
227
197
|
|
|
228
|
-
|
|
229
|
-
|
|
198
|
+
try {
|
|
199
|
+
if (!dryRun) {
|
|
200
|
+
if (script.trim().length > 0) {
|
|
201
|
+
await adapter.executeScript(script, token)
|
|
230
202
|
}
|
|
231
|
-
}
|
|
232
|
-
{ transaction: token },
|
|
233
|
-
)
|
|
234
|
-
let context: MigrationContext = {
|
|
235
|
-
db,
|
|
236
|
-
schema,
|
|
237
|
-
}
|
|
203
|
+
}
|
|
238
204
|
|
|
239
|
-
try {
|
|
240
205
|
if (input.direction === 'up') {
|
|
241
|
-
await migration.migration.up(context)
|
|
242
|
-
|
|
243
206
|
if (!dryRun) {
|
|
244
207
|
await insertJournalRow(
|
|
245
208
|
adapter,
|
|
@@ -247,7 +210,7 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
247
210
|
{
|
|
248
211
|
id: migration.id,
|
|
249
212
|
name: migration.name,
|
|
250
|
-
checksum:
|
|
213
|
+
checksum: await computeChecksum(migration),
|
|
251
214
|
batch,
|
|
252
215
|
},
|
|
253
216
|
token,
|
|
@@ -260,8 +223,6 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
260
223
|
status: 'applied',
|
|
261
224
|
})
|
|
262
225
|
} else {
|
|
263
|
-
await migration.migration.down(context)
|
|
264
|
-
|
|
265
226
|
if (!dryRun) {
|
|
266
227
|
await deleteJournalRow(adapter, journalTable, migration.id, token)
|
|
267
228
|
}
|
|
@@ -296,8 +257,8 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
|
|
|
296
257
|
}
|
|
297
258
|
|
|
298
259
|
/**
|
|
299
|
-
* Creates a migration runner for applying/reverting migrations against an adapter.
|
|
300
|
-
* @param adapter Database adapter used to
|
|
260
|
+
* Creates a migration runner for applying/reverting SQL migrations against an adapter.
|
|
261
|
+
* @param adapter Database adapter used to execute migration scripts.
|
|
301
262
|
* @param migrations Migration descriptors or registry.
|
|
302
263
|
* @param options Optional runner configuration.
|
|
303
264
|
* @returns A migration runner instance.
|
|
@@ -344,20 +305,23 @@ export function createMigrationRunner(
|
|
|
344
305
|
let journalMap = new Map(journal.map((row) => [row.id, row]))
|
|
345
306
|
let sortedMigrations = resolveMigrations(migrations)
|
|
346
307
|
|
|
347
|
-
|
|
308
|
+
let statuses: MigrationStatusEntry[] = []
|
|
309
|
+
|
|
310
|
+
for (let migration of sortedMigrations) {
|
|
348
311
|
let journalRow = journalMap.get(migration.id)
|
|
349
312
|
|
|
350
313
|
if (!journalRow) {
|
|
351
|
-
|
|
314
|
+
statuses.push({
|
|
352
315
|
id: migration.id,
|
|
353
316
|
name: migration.name,
|
|
354
317
|
status: 'pending' as MigrationStatus,
|
|
355
|
-
}
|
|
318
|
+
})
|
|
319
|
+
continue
|
|
356
320
|
}
|
|
357
321
|
|
|
358
|
-
let checksum =
|
|
322
|
+
let checksum = await computeChecksum(migration)
|
|
359
323
|
|
|
360
|
-
|
|
324
|
+
statuses.push({
|
|
361
325
|
id: migration.id,
|
|
362
326
|
name: migration.name,
|
|
363
327
|
status:
|
|
@@ -367,8 +331,10 @@ export function createMigrationRunner(
|
|
|
367
331
|
appliedAt: journalRow.appliedAt,
|
|
368
332
|
batch: journalRow.batch,
|
|
369
333
|
checksum: journalRow.checksum,
|
|
370
|
-
}
|
|
371
|
-
}
|
|
334
|
+
})
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return statuses
|
|
372
338
|
},
|
|
373
339
|
}
|
|
374
340
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
2
1
|
import { promises as fs } from 'node:fs'
|
|
3
2
|
import path from 'node:path'
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
3
|
+
|
|
4
|
+
import type { MigrationDescriptor } from './migrations.ts'
|
|
5
|
+
import { parseMigrationDirectoryName } from './migrations/directory-name.ts'
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
* Loads
|
|
8
|
+
* Loads SQL-file migrations from a directory on Node.js.
|
|
9
|
+
*
|
|
10
|
+
* Each migration is a directory named `YYYYMMDDHHmmss_<slug>` containing:
|
|
11
|
+
* - `up.sql` (required)
|
|
12
|
+
* - `down.sql` (optional; omit for irreversible migrations)
|
|
10
13
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @param directory Absolute or relative directory containing migration files.
|
|
14
|
+
* `id` and `name` are inferred from the directory name.
|
|
15
|
+
* @param directory Absolute or relative directory containing migration directories.
|
|
14
16
|
* @returns A sorted list of loaded migration descriptors.
|
|
15
17
|
* @example
|
|
16
18
|
* ```ts
|
|
@@ -20,52 +22,70 @@ import { parseMigrationFilename } from './migrations/filename.ts'
|
|
|
20
22
|
* ```
|
|
21
23
|
*/
|
|
22
24
|
export async function loadMigrations(directory: string): Promise<MigrationDescriptor[]> {
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
+
let entries = await fs.readdir(directory, { withFileTypes: true })
|
|
26
|
+
let directories = entries
|
|
27
|
+
.filter((entry) => entry.isDirectory())
|
|
25
28
|
.map((entry) => entry.name)
|
|
26
29
|
.sort((left, right) => left.localeCompare(right))
|
|
27
|
-
let files: Array<{ file: string; id: string; name: string }> = []
|
|
28
|
-
|
|
29
|
-
for (let file of allFiles) {
|
|
30
|
-
if (!/\.(?:m?ts|m?js|cts|cjs)$/.test(file)) {
|
|
31
|
-
continue
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let parsed = parseMigrationFilename(file)
|
|
35
|
-
files.push({ file, id: parsed.id, name: parsed.name })
|
|
36
|
-
}
|
|
37
30
|
|
|
38
31
|
let migrations: MigrationDescriptor[] = []
|
|
39
32
|
let seenIds = new Set<string>()
|
|
40
33
|
|
|
41
|
-
for (let
|
|
42
|
-
|
|
34
|
+
for (let directoryName of directories) {
|
|
35
|
+
let parsed = parseMigrationDirectoryName(directoryName)
|
|
36
|
+
|
|
37
|
+
if (seenIds.has(parsed.id)) {
|
|
43
38
|
throw new Error(
|
|
44
|
-
'Duplicate migration id "' +
|
|
39
|
+
'Duplicate migration id "' +
|
|
40
|
+
parsed.id +
|
|
41
|
+
'" inferred from directory "' +
|
|
42
|
+
directoryName +
|
|
43
|
+
'"',
|
|
45
44
|
)
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
seenIds.add(
|
|
49
|
-
let fullPath = path.join(directory, entry.file)
|
|
50
|
-
let source = await fs.readFile(fullPath, 'utf8')
|
|
51
|
-
let checksum = createHash('sha256').update(source).digest('hex')
|
|
52
|
-
let module = (await import(pathToFileURL(fullPath).href)) as { default?: Migration }
|
|
53
|
-
let migration = module.default
|
|
47
|
+
seenIds.add(parsed.id)
|
|
54
48
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
let directoryPath = path.join(directory, directoryName)
|
|
50
|
+
let upPath = path.join(directoryPath, 'up.sql')
|
|
51
|
+
let downPath = path.join(directoryPath, 'down.sql')
|
|
52
|
+
|
|
53
|
+
let up: string
|
|
54
|
+
try {
|
|
55
|
+
up = await fs.readFile(upPath, 'utf8')
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (isNodeFileNotFoundError(error)) {
|
|
58
|
+
throw new Error('Migration directory "' + directoryName + '" is missing up.sql')
|
|
59
|
+
}
|
|
60
|
+
throw error
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let down: string | undefined
|
|
64
|
+
try {
|
|
65
|
+
down = await fs.readFile(downPath, 'utf8')
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (!isNodeFileNotFoundError(error)) {
|
|
68
|
+
throw error
|
|
69
|
+
}
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
migrations.push({
|
|
62
|
-
id:
|
|
63
|
-
name:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
id: parsed.id,
|
|
74
|
+
name: parsed.name,
|
|
75
|
+
up,
|
|
76
|
+
down,
|
|
77
|
+
path: directoryPath,
|
|
67
78
|
})
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
return migrations
|
|
71
82
|
}
|
|
83
|
+
|
|
84
|
+
function isNodeFileNotFoundError(error: unknown): boolean {
|
|
85
|
+
return (
|
|
86
|
+
typeof error === 'object' &&
|
|
87
|
+
error !== null &&
|
|
88
|
+
'code' in error &&
|
|
89
|
+
(error as { code?: unknown }).code === 'ENOENT'
|
|
90
|
+
)
|
|
91
|
+
}
|
package/src/lib/migrations.ts
CHANGED
|
@@ -1,94 +1,31 @@
|
|
|
1
|
-
import type { Database } from './database.ts'
|
|
2
|
-
import type { ColumnDefinition, ForeignKeyAction, IndexDefinition } from './adapter.ts'
|
|
3
|
-
import type { ColumnBuilder } from './column.ts'
|
|
4
|
-
import type { SqlStatement } from './sql.ts'
|
|
5
|
-
import type { AnyTable } from './table.ts'
|
|
6
|
-
|
|
7
1
|
/**
|
|
8
2
|
* Controls how each migration is wrapped in transactions.
|
|
9
|
-
*/
|
|
10
|
-
export type MigrationTransactionMode = 'auto' | 'required' | 'none'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Runtime context passed to migration `up`/`down` handlers.
|
|
14
|
-
*/
|
|
15
|
-
export type MigrationContext = {
|
|
16
|
-
/**
|
|
17
|
-
* Immediate data runtime (`query/create/update/exec/transaction`).
|
|
18
|
-
*/
|
|
19
|
-
db: Database
|
|
20
|
-
/**
|
|
21
|
-
* Migration schema runtime (`createTable/alterTable/createIndex/...`).
|
|
22
|
-
*/
|
|
23
|
-
schema: MigrationSchema
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Authoring shape for `createMigration(...)`.
|
|
28
|
-
*/
|
|
29
|
-
export type CreateMigrationInput = {
|
|
30
|
-
up: (context: MigrationContext) => Promise<void> | void
|
|
31
|
-
down: (context: MigrationContext) => Promise<void> | void
|
|
32
|
-
transaction?: MigrationTransactionMode
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Normalized migration object consumed by the registry/runner.
|
|
37
|
-
*/
|
|
38
|
-
export type Migration = {
|
|
39
|
-
up: CreateMigrationInput['up']
|
|
40
|
-
down: CreateMigrationInput['down']
|
|
41
|
-
transaction: MigrationTransactionMode
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Creates a migration descriptor with normalized defaults.
|
|
46
|
-
* @param input Migration handlers and transaction mode.
|
|
47
|
-
* @returns A normalized migration object.
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* import { createMigration, column as c } from 'remix/data-table/migrations'
|
|
51
|
-
* import { table } from 'remix/data-table'
|
|
52
|
-
*
|
|
53
|
-
* let users = table({
|
|
54
|
-
* name: 'users',
|
|
55
|
-
* columns: {
|
|
56
|
-
* id: c.integer().primaryKey().autoIncrement(),
|
|
57
|
-
* email: c.varchar(255).notNull().unique(),
|
|
58
|
-
* },
|
|
59
|
-
* })
|
|
60
3
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* if (db.adapter.dialect === 'sqlite') {
|
|
66
|
-
* await db.exec('pragma foreign_keys = on')
|
|
67
|
-
* }
|
|
68
|
-
* },
|
|
69
|
-
* async down({ schema }) {
|
|
70
|
-
* await schema.dropTable('users', { ifExists: true })
|
|
71
|
-
* },
|
|
72
|
-
* })
|
|
73
|
-
* ```
|
|
4
|
+
* - `auto` (default): wrap when the adapter supports transactional DDL.
|
|
5
|
+
* - `required`: wrap; throws when the adapter does not support transactional DDL.
|
|
6
|
+
* - `none`: never wrap.
|
|
74
7
|
*/
|
|
75
|
-
export
|
|
76
|
-
return {
|
|
77
|
-
up: input.up,
|
|
78
|
-
down: input.down,
|
|
79
|
-
transaction: input.transaction ?? 'auto',
|
|
80
|
-
}
|
|
81
|
-
}
|
|
8
|
+
export type MigrationTransactionMode = 'auto' | 'required' | 'none'
|
|
82
9
|
|
|
83
10
|
/**
|
|
84
|
-
* Migration metadata
|
|
11
|
+
* Migration metadata + SQL consumed by the registry/runner.
|
|
85
12
|
*/
|
|
86
13
|
export type MigrationDescriptor = {
|
|
14
|
+
/** Migration id (typically a `YYYYMMDDHHmmss` timestamp). */
|
|
87
15
|
id: string
|
|
16
|
+
/** Human-readable migration slug. */
|
|
88
17
|
name: string
|
|
18
|
+
/** SQL executed for `runner.up(...)`. May contain multiple statements. */
|
|
19
|
+
up: string
|
|
20
|
+
/**
|
|
21
|
+
* SQL executed for `runner.down(...)`. May contain multiple statements.
|
|
22
|
+
* Omit (or pass `undefined`) for irreversible migrations.
|
|
23
|
+
*/
|
|
24
|
+
down?: string
|
|
25
|
+
/** Transaction wrapping mode. Defaults to `auto`. */
|
|
26
|
+
transaction?: MigrationTransactionMode
|
|
27
|
+
/** Optional source path used in error messages. */
|
|
89
28
|
path?: string
|
|
90
|
-
checksum?: string
|
|
91
|
-
migration: Migration
|
|
92
29
|
}
|
|
93
30
|
|
|
94
31
|
/**
|
|
@@ -152,151 +89,9 @@ export type MigrateResult = {
|
|
|
152
89
|
applied: MigrationStatusEntry[]
|
|
153
90
|
reverted: MigrationStatusEntry[]
|
|
154
91
|
/**
|
|
155
|
-
*
|
|
156
|
-
* Includes planned SQL when running with `dryRun: true`.
|
|
157
|
-
*/
|
|
158
|
-
sql: SqlStatement[]
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Options for `schema.createTable(...)` migration operations.
|
|
163
|
-
*/
|
|
164
|
-
export type CreateTableOptions = { ifNotExists?: boolean }
|
|
165
|
-
/**
|
|
166
|
-
* Options for `schema.alterTable(...)` migration operations.
|
|
167
|
-
*/
|
|
168
|
-
export type AlterTableOptions = { ifExists?: boolean }
|
|
169
|
-
/**
|
|
170
|
-
* Options for `schema.dropTable(...)` migration operations.
|
|
171
|
-
*/
|
|
172
|
-
export type DropTableOptions = { ifExists?: boolean; cascade?: boolean }
|
|
173
|
-
/**
|
|
174
|
-
* Accepts either one index column or multiple (compound index).
|
|
175
|
-
*/
|
|
176
|
-
export type IndexColumns = string | string[]
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Accepts either one key column or multiple (compound key).
|
|
180
|
-
*/
|
|
181
|
-
export type KeyColumns = string | string[]
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Accepts either a SQL table name or a `table(...)` object.
|
|
185
|
-
*/
|
|
186
|
-
export type TableInput = string | AnyTable
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Optional name override for constraints and indexes.
|
|
190
|
-
*/
|
|
191
|
-
export type NamedConstraintOptions = {
|
|
192
|
-
name?: string
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Foreign key options for migration APIs.
|
|
197
|
-
*/
|
|
198
|
-
export type ForeignKeyOptions = NamedConstraintOptions & {
|
|
199
|
-
onDelete?: ForeignKeyAction
|
|
200
|
-
onUpdate?: ForeignKeyAction
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Index options for migration APIs.
|
|
205
|
-
*/
|
|
206
|
-
export type CreateIndexOptions = NamedConstraintOptions &
|
|
207
|
-
Omit<IndexDefinition, 'table' | 'name' | 'columns'> & {
|
|
208
|
-
ifNotExists?: boolean
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Builder API available inside `schema.alterTable(name, table => ...)`.
|
|
213
|
-
*/
|
|
214
|
-
export interface AlterTableBuilder {
|
|
215
|
-
/** Adds a column during an `alterTable` migration. */
|
|
216
|
-
addColumn(name: string, definition: ColumnDefinition | ColumnBuilder): void
|
|
217
|
-
/** Changes an existing column during an `alterTable` migration. */
|
|
218
|
-
changeColumn(name: string, definition: ColumnDefinition | ColumnBuilder): void
|
|
219
|
-
/** Renames a column during an `alterTable` migration. */
|
|
220
|
-
renameColumn(from: string, to: string): void
|
|
221
|
-
/** Drops a column during an `alterTable` migration. */
|
|
222
|
-
dropColumn(name: string, options?: { ifExists?: boolean }): void
|
|
223
|
-
/** Adds a primary key during an `alterTable` migration. */
|
|
224
|
-
addPrimaryKey(columns: KeyColumns, options?: NamedConstraintOptions): void
|
|
225
|
-
/** Drops a primary key during an `alterTable` migration. */
|
|
226
|
-
dropPrimaryKey(name: string): void
|
|
227
|
-
/** Adds a unique constraint during an `alterTable` migration. */
|
|
228
|
-
addUnique(columns: KeyColumns, options?: NamedConstraintOptions): void
|
|
229
|
-
/** Drops a unique constraint during an `alterTable` migration. */
|
|
230
|
-
dropUnique(name: string): void
|
|
231
|
-
/** Adds a foreign key during an `alterTable` migration. */
|
|
232
|
-
addForeignKey(
|
|
233
|
-
columns: KeyColumns,
|
|
234
|
-
refTable: TableInput,
|
|
235
|
-
refColumns?: KeyColumns,
|
|
236
|
-
options?: ForeignKeyOptions,
|
|
237
|
-
): void
|
|
238
|
-
/** Drops a foreign key during an `alterTable` migration. */
|
|
239
|
-
dropForeignKey(name: string): void
|
|
240
|
-
/** Adds a check constraint during an `alterTable` migration. */
|
|
241
|
-
addCheck(expression: string, options?: NamedConstraintOptions): void
|
|
242
|
-
/** Drops a check constraint during an `alterTable` migration. */
|
|
243
|
-
dropCheck(name: string): void
|
|
244
|
-
/** Adds an index during an `alterTable` migration. */
|
|
245
|
-
addIndex(columns: IndexColumns, options?: CreateIndexOptions): void
|
|
246
|
-
/** Drops an index during an `alterTable` migration. */
|
|
247
|
-
dropIndex(name: string): void
|
|
248
|
-
/** Sets the table comment during an `alterTable` migration. */
|
|
249
|
-
comment(text: string): void
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* DDL-focused operations mixed into the migration `db` object.
|
|
254
|
-
*/
|
|
255
|
-
export interface MigrationSchema {
|
|
256
|
-
/** Creates a table in the migration schema. */
|
|
257
|
-
createTable<table extends AnyTable>(table: table, options?: CreateTableOptions): Promise<void>
|
|
258
|
-
/** Alters an existing table in the migration schema. */
|
|
259
|
-
alterTable(
|
|
260
|
-
table: TableInput,
|
|
261
|
-
migrate: (table: AlterTableBuilder) => void,
|
|
262
|
-
options?: AlterTableOptions,
|
|
263
|
-
): Promise<void>
|
|
264
|
-
/** Renames a table in the migration schema. */
|
|
265
|
-
renameTable(from: TableInput, to: string): Promise<void>
|
|
266
|
-
/** Drops a table from the migration schema. */
|
|
267
|
-
dropTable(table: TableInput, options?: DropTableOptions): Promise<void>
|
|
268
|
-
/** Creates an index in the migration schema. */
|
|
269
|
-
createIndex(table: TableInput, columns: IndexColumns, options?: CreateIndexOptions): Promise<void>
|
|
270
|
-
/** Drops an index from the migration schema. */
|
|
271
|
-
dropIndex(table: TableInput, name: string, options?: { ifExists?: boolean }): Promise<void>
|
|
272
|
-
/** Renames an index in the migration schema. */
|
|
273
|
-
renameIndex(table: TableInput, from: string, to: string): Promise<void>
|
|
274
|
-
/** Adds a foreign key in the migration schema. */
|
|
275
|
-
addForeignKey(
|
|
276
|
-
table: TableInput,
|
|
277
|
-
columns: KeyColumns,
|
|
278
|
-
refTable: TableInput,
|
|
279
|
-
refColumns?: KeyColumns,
|
|
280
|
-
options?: ForeignKeyOptions,
|
|
281
|
-
): Promise<void>
|
|
282
|
-
/** Drops a foreign key in the migration schema. */
|
|
283
|
-
dropForeignKey(table: TableInput, name: string): Promise<void>
|
|
284
|
-
/** Adds a check constraint in the migration schema. */
|
|
285
|
-
addCheck(table: TableInput, expression: string, options?: NamedConstraintOptions): Promise<void>
|
|
286
|
-
/** Drops a check constraint in the migration schema. */
|
|
287
|
-
dropCheck(table: TableInput, name: string): Promise<void>
|
|
288
|
-
/**
|
|
289
|
-
* Adds raw SQL to the migration plan as a migration operation.
|
|
290
|
-
*/
|
|
291
|
-
plan(sql: string | SqlStatement): Promise<void>
|
|
292
|
-
/**
|
|
293
|
-
* Returns `true` when the table exists in the current database.
|
|
294
|
-
*/
|
|
295
|
-
hasTable(table: TableInput): Promise<boolean>
|
|
296
|
-
/**
|
|
297
|
-
* Returns `true` when the column exists on the given table.
|
|
92
|
+
* SQL scripts that were (or, for `dryRun`, would have been) executed.
|
|
298
93
|
*/
|
|
299
|
-
|
|
94
|
+
sql: string[]
|
|
300
95
|
}
|
|
301
96
|
|
|
302
97
|
/**
|