@remix-run/data-table 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -5
- package/dist/cli.d.ts +23 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +25 -0
- package/dist/lib/database/relations.js +34 -15
- package/dist/lib/migrations/runner.js +1 -1
- package/dist/lib/operators.d.ts +7 -6
- package/dist/lib/operators.d.ts.map +1 -1
- package/dist/lib/operators.js +14 -10
- package/package.json +1 -1
- package/src/cli.ts +59 -0
- package/src/lib/database/relations.ts +44 -15
- package/src/lib/migrations/runner.ts +1 -1
- package/src/lib/operators.ts +23 -10
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Typed relational query toolkit for JavaScript runtimes.
|
|
|
11
11
|
- **Relation-First Queries**: `hasMany`, `hasOne`, `belongsTo`, `hasManyThrough`, and nested eager loading
|
|
12
12
|
- **Safe Scoped Writes**: `update`/`delete` with `orderBy`/`limit` run safely in a transaction
|
|
13
13
|
- **First-Class Migrations**: Plain SQL `up.sql`/`down.sql` files with a journaling runner and dry-run planning
|
|
14
|
-
- **Database Lifecycle Commands**: Wipe, migrate, inspect, seed, and reset through `remix db`
|
|
14
|
+
- **Database Lifecycle Commands**: Wipe, migrate, rollback, inspect, seed, and reset through `remix db`
|
|
15
15
|
- **Raw SQL Escape Hatch**: Execute SQL directly with `db.exec(sql\`...\`)`
|
|
16
16
|
|
|
17
17
|
`data-table` gives you two complementary APIs:
|
|
@@ -409,7 +409,7 @@ environment variable at command runtime, and paths are resolved relative to `rem
|
|
|
409
409
|
|
|
410
410
|
```jsonc
|
|
411
411
|
{
|
|
412
|
-
"$schema": "
|
|
412
|
+
"$schema": "./node_modules/remix/schema/remix.json",
|
|
413
413
|
"db": {
|
|
414
414
|
"adapter": {
|
|
415
415
|
"type": "postgres",
|
|
@@ -433,12 +433,16 @@ Run lifecycle commands through the Remix CLI:
|
|
|
433
433
|
remix db status
|
|
434
434
|
remix db migrate
|
|
435
435
|
remix db migrate --to 20260301113000_add_user_status
|
|
436
|
+
remix db rollback
|
|
437
|
+
remix db rollback --step 2
|
|
438
|
+
remix db rollback --to 20260301113000_add_user_status
|
|
439
|
+
remix db rollback --dry-run
|
|
436
440
|
remix db seed
|
|
437
|
-
remix db reset
|
|
438
|
-
remix db wipe
|
|
441
|
+
remix db reset --force
|
|
442
|
+
remix db wipe --force
|
|
439
443
|
```
|
|
440
444
|
|
|
441
|
-
`--to
|
|
445
|
+
`rollback` reverts the most recently applied migration by default. Bound it with either `--step <count>` or `--to <migration>`, which reverts through the target migration inclusively. Migration targets accept a bare migration id (`20260301113000`) or the full directory name (`20260301113000_add_user_status`). Use `--dry-run` to report what would be reverted without changing the database.
|
|
442
446
|
|
|
443
447
|
`remix db status` reports applied migrations whose files are no longer present as `missing`. If the journal table does not exist, it reports every migration as pending without creating the table. Forward migration runs stop before executing SQL when an applied journal entry is missing from the current migration set. Rollbacks skip those orphaned journal entries so migrations that are still present can be reverted.
|
|
444
448
|
|
|
@@ -473,6 +477,15 @@ for (let script of plan.sql) console.log(script)
|
|
|
473
477
|
|
|
474
478
|
`to` and `step` are mutually exclusive. Omit `journalTable` to use `data_table_migrations`.
|
|
475
479
|
|
|
480
|
+
Hosts that embed the database CLI can invoke the same rollback behavior through `runRemixDb()`:
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import { runRemixDb } from 'remix/data-table/cli'
|
|
484
|
+
|
|
485
|
+
await runRemixDb({ command: 'rollback', db, migrations })
|
|
486
|
+
await runRemixDb({ command: 'rollback', db, migrations, step: 2, dryRun: true })
|
|
487
|
+
```
|
|
488
|
+
|
|
476
489
|
Database drivers with migration locking run the complete migration and journal lifecycle through the
|
|
477
490
|
connection that owns the lock. This keeps advisory locks correctly paired when the driver uses a
|
|
478
491
|
connection pool, including pools configured with a single connection.
|
package/dist/cli.d.ts
CHANGED
|
@@ -4,6 +4,28 @@ interface DatabaseCommandOptions {
|
|
|
4
4
|
/** Database instance used by the command. */
|
|
5
5
|
db: Database;
|
|
6
6
|
}
|
|
7
|
+
type RollbackBoundOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* Reverts back through this migration, inclusive. Accepts a bare
|
|
10
|
+
* migration id or the full `id_name` directory form.
|
|
11
|
+
*/
|
|
12
|
+
to: string;
|
|
13
|
+
step?: never;
|
|
14
|
+
} | {
|
|
15
|
+
to?: never;
|
|
16
|
+
/** Reverts this many migrations. Defaults to `1`. */
|
|
17
|
+
step?: number;
|
|
18
|
+
};
|
|
19
|
+
type RollbackCommandOptions = DatabaseCommandOptions & RollbackBoundOptions & {
|
|
20
|
+
/** Reverts applied migrations, newest first. */
|
|
21
|
+
command: 'rollback';
|
|
22
|
+
/** Migrations to revert. */
|
|
23
|
+
migrations: Migrations;
|
|
24
|
+
/** Reports what would be reverted without running it. */
|
|
25
|
+
dryRun?: boolean;
|
|
26
|
+
/** Migration journal table. */
|
|
27
|
+
journalTable?: string;
|
|
28
|
+
};
|
|
7
29
|
/** Structured invocation options accepted by {@link runRemixDb}. */
|
|
8
30
|
export type RunRemixDbOptions = (DatabaseCommandOptions & {
|
|
9
31
|
/** Applies pending migrations. */
|
|
@@ -17,7 +39,7 @@ export type RunRemixDbOptions = (DatabaseCommandOptions & {
|
|
|
17
39
|
to?: string;
|
|
18
40
|
/** Migration journal table. */
|
|
19
41
|
journalTable?: string;
|
|
20
|
-
}) | (DatabaseCommandOptions & {
|
|
42
|
+
}) | RollbackCommandOptions | (DatabaseCommandOptions & {
|
|
21
43
|
/** Wipes, migrates, and optionally seeds the database. */
|
|
22
44
|
command: 'reset';
|
|
23
45
|
/** Migrations to apply after wiping the database. */
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAE3D,UAAU,sBAAsB;IAC9B,6CAA6C;IAC7C,EAAE,EAAE,QAAQ,CAAA;CACb;AAED,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GACzB,CAAC,sBAAsB,GAAG;IACxB,kCAAkC;IAClC,OAAO,EAAE,SAAS,CAAA;IAClB,2BAA2B;IAC3B,UAAU,EAAE,UAAU,CAAA;IACtB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAA;IAChB,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAA;IACtB,yDAAyD;IACzD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,IAAI,EAAE,IAAI,CAAA;CACX,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,8CAA8C;IAC9C,OAAO,EAAE,QAAQ,CAAA;IACjB,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAA;IACtB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEN;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAE3D,UAAU,sBAAsB;IAC9B,6CAA6C;IAC7C,EAAE,EAAE,QAAQ,CAAA;CACb;AAED,KAAK,oBAAoB,GACrB;IACE;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,KAAK,CAAA;CACb,GACD;IACE,EAAE,CAAC,EAAE,KAAK,CAAA;IACV,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAEL,KAAK,sBAAsB,GAAG,sBAAsB,GAClD,oBAAoB,GAAG;IACrB,gDAAgD;IAChD,OAAO,EAAE,UAAU,CAAA;IACnB,4BAA4B;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAEH,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GACzB,CAAC,sBAAsB,GAAG;IACxB,kCAAkC;IAClC,OAAO,EAAE,SAAS,CAAA;IAClB,2BAA2B;IAC3B,UAAU,EAAE,UAAU,CAAA;IACtB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,sBAAsB,GACtB,CAAC,sBAAsB,GAAG;IACxB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAA;IAChB,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAA;IACtB,yDAAyD;IACzD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,IAAI,EAAE,IAAI,CAAA;CACX,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,8CAA8C;IAC9C,OAAO,EAAE,QAAQ,CAAA;IACjB,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAA;IACtB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEN;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2F5E"}
|
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,31 @@ export async function runRemixDb(options) {
|
|
|
19
19
|
}
|
|
20
20
|
return 0;
|
|
21
21
|
}
|
|
22
|
+
if (options.command === 'rollback') {
|
|
23
|
+
if (options.to !== undefined && options.step !== undefined) {
|
|
24
|
+
throw new Error('Cannot combine "to" and "step" migration options in the same run');
|
|
25
|
+
}
|
|
26
|
+
let result = options.to === undefined
|
|
27
|
+
? await options.db.migrate(options.migrations, {
|
|
28
|
+
direction: 'down',
|
|
29
|
+
step: options.step ?? 1,
|
|
30
|
+
dryRun: options.dryRun,
|
|
31
|
+
journalTable: options.journalTable,
|
|
32
|
+
})
|
|
33
|
+
: await options.db.migrate(options.migrations, {
|
|
34
|
+
direction: 'down',
|
|
35
|
+
to: options.to,
|
|
36
|
+
dryRun: options.dryRun,
|
|
37
|
+
journalTable: options.journalTable,
|
|
38
|
+
});
|
|
39
|
+
if (result.reverted.length === 0) {
|
|
40
|
+
console.log('no migrations to revert');
|
|
41
|
+
}
|
|
42
|
+
for (let entry of result.reverted) {
|
|
43
|
+
console.log((options.dryRun ? 'would revert ' : 'reverted ') + entry.id + '_' + entry.name);
|
|
44
|
+
}
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
22
47
|
if (options.command === 'reset') {
|
|
23
48
|
await options.db.reset({
|
|
24
49
|
migrations: options.migrations,
|
|
@@ -62,10 +62,11 @@ async function loadHasManyThroughValues(database, sourceRows, relation) {
|
|
|
62
62
|
if (!relation.through) {
|
|
63
63
|
throw new DataTableQueryError('hasManyThrough relation is missing through metadata');
|
|
64
64
|
}
|
|
65
|
+
let through = relation.through;
|
|
65
66
|
if (sourceRows.length === 0) {
|
|
66
67
|
return [];
|
|
67
68
|
}
|
|
68
|
-
let throughRelation =
|
|
69
|
+
let throughRelation = through.relation;
|
|
69
70
|
let sourceTuples = uniqueTuples(sourceRows, throughRelation.sourceKey);
|
|
70
71
|
if (sourceTuples.length === 0) {
|
|
71
72
|
return sourceRows.map(() => []);
|
|
@@ -92,12 +93,12 @@ async function loadHasManyThroughValues(database, sourceRows, relation) {
|
|
|
92
93
|
pagedThroughRowsBySource.set(sourceKey, pagedMatchedRows);
|
|
93
94
|
pagedThroughRows.push(...pagedMatchedRows);
|
|
94
95
|
}
|
|
95
|
-
let throughTuples = uniqueTuples(pagedThroughRows,
|
|
96
|
+
let throughTuples = uniqueTuples(pagedThroughRows, through.throughSourceKey);
|
|
96
97
|
if (throughTuples.length === 0) {
|
|
97
98
|
return sourceRows.map(() => []);
|
|
98
99
|
}
|
|
99
100
|
let targetQuery = createQuery(relation.targetTable);
|
|
100
|
-
let targetPredicate = buildLinkPredicate(
|
|
101
|
+
let targetPredicate = buildLinkPredicate(through.throughTargetKey, throughTuples);
|
|
101
102
|
if (targetPredicate) {
|
|
102
103
|
targetQuery = targetQuery.where(targetPredicate);
|
|
103
104
|
}
|
|
@@ -105,23 +106,41 @@ async function loadHasManyThroughValues(database, sourceRows, relation) {
|
|
|
105
106
|
includePagination: false,
|
|
106
107
|
});
|
|
107
108
|
let relatedRows = await loadRowsWithRelationsForQuery(database, targetQuery);
|
|
108
|
-
let
|
|
109
|
-
|
|
109
|
+
let sourceKeysByThroughKey = new Map();
|
|
110
|
+
let outputRowsBySourceKey = new Map();
|
|
111
|
+
for (let sourceRow of sourceRows) {
|
|
110
112
|
let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey);
|
|
111
113
|
let matchedThroughRows = pagedThroughRowsBySource.get(sourceKey) ?? [];
|
|
112
|
-
|
|
113
|
-
let seen = new Set();
|
|
114
|
+
outputRowsBySourceKey.set(sourceKey, new Map());
|
|
114
115
|
for (let throughRow of matchedThroughRows) {
|
|
115
|
-
let throughKey = getCompositeKey(throughRow,
|
|
116
|
-
let
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
let throughKey = getCompositeKey(throughRow, through.throughSourceKey);
|
|
117
|
+
let sourceKeys = sourceKeysByThroughKey.get(throughKey);
|
|
118
|
+
if (!sourceKeys) {
|
|
119
|
+
sourceKeys = new Set();
|
|
120
|
+
sourceKeysByThroughKey.set(throughKey, sourceKeys);
|
|
121
|
+
}
|
|
122
|
+
sourceKeys.add(sourceKey);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let targetPrimaryKey = getTablePrimaryKey(relation.targetTable);
|
|
126
|
+
for (let row of relatedRows) {
|
|
127
|
+
let throughKey = getCompositeKey(row, through.throughTargetKey);
|
|
128
|
+
let sourceKeys = sourceKeysByThroughKey.get(throughKey);
|
|
129
|
+
if (!sourceKeys) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
let rowIdentity = getCompositeKey(row, targetPrimaryKey);
|
|
133
|
+
for (let sourceKey of sourceKeys) {
|
|
134
|
+
let outputRows = outputRowsBySourceKey.get(sourceKey);
|
|
135
|
+
if (!outputRows || outputRows.has(rowIdentity)) {
|
|
136
|
+
continue;
|
|
123
137
|
}
|
|
138
|
+
outputRows.set(rowIdentity, row);
|
|
124
139
|
}
|
|
140
|
+
}
|
|
141
|
+
return sourceRows.map((sourceRow) => {
|
|
142
|
+
let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey);
|
|
143
|
+
let outputRows = Array.from(outputRowsBySourceKey.get(sourceKey)?.values() ?? []);
|
|
125
144
|
return applyPagination(outputRows, relation.modifiers.limit, relation.modifiers.offset);
|
|
126
145
|
});
|
|
127
146
|
}
|
package/dist/lib/operators.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export type WhereObject<column extends string = string> = Partial<Record<column,
|
|
|
42
42
|
* User-facing where input accepted by `query.where()` and relation modifiers.
|
|
43
43
|
*/
|
|
44
44
|
export type WhereInput<column extends string = string> = Predicate<column> | WhereObject<column>;
|
|
45
|
+
type WhereInputColumn<input extends WhereInput> = input extends Predicate<infer column> ? column : keyof input & string;
|
|
45
46
|
/**
|
|
46
47
|
* Builds an equality predicate.
|
|
47
48
|
*/
|
|
@@ -121,17 +122,17 @@ export declare function isNull<column extends string | ColumnReferenceLike>(colu
|
|
|
121
122
|
*/
|
|
122
123
|
export declare function notNull<column extends string | ColumnReferenceLike>(column: column): Predicate<PredicateColumn<column>>;
|
|
123
124
|
/**
|
|
124
|
-
* Combines
|
|
125
|
-
* @param
|
|
125
|
+
* Combines where inputs with logical `AND`.
|
|
126
|
+
* @param inputs Child predicates or object shorthand filters.
|
|
126
127
|
* @returns A logical `and` predicate.
|
|
127
128
|
*/
|
|
128
|
-
export declare function and<
|
|
129
|
+
export declare function and<inputs extends WhereInput[]>(...inputs: inputs): Predicate<WhereInputColumn<inputs[number]>>;
|
|
129
130
|
/**
|
|
130
|
-
* Combines
|
|
131
|
-
* @param
|
|
131
|
+
* Combines where inputs with logical `OR`.
|
|
132
|
+
* @param inputs Child predicates or object shorthand filters.
|
|
132
133
|
* @returns A logical `or` predicate.
|
|
133
134
|
*/
|
|
134
|
-
export declare function or<
|
|
135
|
+
export declare function or<inputs extends WhereInput[]>(...inputs: inputs): Predicate<WhereInputColumn<inputs[number]>>;
|
|
135
136
|
/**
|
|
136
137
|
* Returns `true` when a value is a normalized predicate object.
|
|
137
138
|
* @param value Value to inspect.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/lib/operators.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/lib/operators.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/operators.js
CHANGED
|
@@ -109,22 +109,26 @@ export function notNull(column) {
|
|
|
109
109
|
return { type: 'null', operator: 'notNull', column: resolvePredicateColumn(column) };
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
-
* Combines
|
|
113
|
-
* @param
|
|
112
|
+
* Combines where inputs with logical `AND`.
|
|
113
|
+
* @param inputs Child predicates or object shorthand filters.
|
|
114
114
|
* @returns A logical `and` predicate.
|
|
115
115
|
*/
|
|
116
|
-
export function and(...
|
|
117
|
-
let
|
|
118
|
-
|
|
116
|
+
export function and(...inputs) {
|
|
117
|
+
let predicates = inputs
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.map((input) => normalizeWhereInput(input));
|
|
120
|
+
return { type: 'logical', operator: 'and', predicates };
|
|
119
121
|
}
|
|
120
122
|
/**
|
|
121
|
-
* Combines
|
|
122
|
-
* @param
|
|
123
|
+
* Combines where inputs with logical `OR`.
|
|
124
|
+
* @param inputs Child predicates or object shorthand filters.
|
|
123
125
|
* @returns A logical `or` predicate.
|
|
124
126
|
*/
|
|
125
|
-
export function or(...
|
|
126
|
-
let
|
|
127
|
-
|
|
127
|
+
export function or(...inputs) {
|
|
128
|
+
let predicates = inputs
|
|
129
|
+
.filter(Boolean)
|
|
130
|
+
.map((input) => normalizeWhereInput(input));
|
|
131
|
+
return { type: 'logical', operator: 'or', predicates };
|
|
128
132
|
}
|
|
129
133
|
/**
|
|
130
134
|
* Returns `true` when a value is a normalized predicate object.
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -6,6 +6,33 @@ interface DatabaseCommandOptions {
|
|
|
6
6
|
db: Database
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
type RollbackBoundOptions =
|
|
10
|
+
| {
|
|
11
|
+
/**
|
|
12
|
+
* Reverts back through this migration, inclusive. Accepts a bare
|
|
13
|
+
* migration id or the full `id_name` directory form.
|
|
14
|
+
*/
|
|
15
|
+
to: string
|
|
16
|
+
step?: never
|
|
17
|
+
}
|
|
18
|
+
| {
|
|
19
|
+
to?: never
|
|
20
|
+
/** Reverts this many migrations. Defaults to `1`. */
|
|
21
|
+
step?: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type RollbackCommandOptions = DatabaseCommandOptions &
|
|
25
|
+
RollbackBoundOptions & {
|
|
26
|
+
/** Reverts applied migrations, newest first. */
|
|
27
|
+
command: 'rollback'
|
|
28
|
+
/** Migrations to revert. */
|
|
29
|
+
migrations: Migrations
|
|
30
|
+
/** Reports what would be reverted without running it. */
|
|
31
|
+
dryRun?: boolean
|
|
32
|
+
/** Migration journal table. */
|
|
33
|
+
journalTable?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
9
36
|
/** Structured invocation options accepted by {@link runRemixDb}. */
|
|
10
37
|
export type RunRemixDbOptions =
|
|
11
38
|
| (DatabaseCommandOptions & {
|
|
@@ -21,6 +48,7 @@ export type RunRemixDbOptions =
|
|
|
21
48
|
/** Migration journal table. */
|
|
22
49
|
journalTable?: string
|
|
23
50
|
})
|
|
51
|
+
| RollbackCommandOptions
|
|
24
52
|
| (DatabaseCommandOptions & {
|
|
25
53
|
/** Wipes, migrates, and optionally seeds the database. */
|
|
26
54
|
command: 'reset'
|
|
@@ -76,6 +104,37 @@ export async function runRemixDb(options: RunRemixDbOptions): Promise<number> {
|
|
|
76
104
|
return 0
|
|
77
105
|
}
|
|
78
106
|
|
|
107
|
+
if (options.command === 'rollback') {
|
|
108
|
+
if (options.to !== undefined && options.step !== undefined) {
|
|
109
|
+
throw new Error('Cannot combine "to" and "step" migration options in the same run')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let result =
|
|
113
|
+
options.to === undefined
|
|
114
|
+
? await options.db.migrate(options.migrations, {
|
|
115
|
+
direction: 'down',
|
|
116
|
+
step: options.step ?? 1,
|
|
117
|
+
dryRun: options.dryRun,
|
|
118
|
+
journalTable: options.journalTable,
|
|
119
|
+
})
|
|
120
|
+
: await options.db.migrate(options.migrations, {
|
|
121
|
+
direction: 'down',
|
|
122
|
+
to: options.to,
|
|
123
|
+
dryRun: options.dryRun,
|
|
124
|
+
journalTable: options.journalTable,
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
if (result.reverted.length === 0) {
|
|
128
|
+
console.log('no migrations to revert')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (let entry of result.reverted) {
|
|
132
|
+
console.log((options.dryRun ? 'would revert ' : 'reverted ') + entry.id + '_' + entry.name)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return 0
|
|
136
|
+
}
|
|
137
|
+
|
|
79
138
|
if (options.command === 'reset') {
|
|
80
139
|
await options.db.reset({
|
|
81
140
|
migrations: options.migrations,
|
|
@@ -116,11 +116,13 @@ async function loadHasManyThroughValues(
|
|
|
116
116
|
throw new DataTableQueryError('hasManyThrough relation is missing through metadata')
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
let through = relation.through
|
|
120
|
+
|
|
119
121
|
if (sourceRows.length === 0) {
|
|
120
122
|
return []
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
let throughRelation =
|
|
125
|
+
let throughRelation = through.relation
|
|
124
126
|
let sourceTuples = uniqueTuples(sourceRows, throughRelation.sourceKey)
|
|
125
127
|
|
|
126
128
|
if (sourceTuples.length === 0) {
|
|
@@ -163,14 +165,14 @@ async function loadHasManyThroughValues(
|
|
|
163
165
|
pagedThroughRows.push(...pagedMatchedRows)
|
|
164
166
|
}
|
|
165
167
|
|
|
166
|
-
let throughTuples = uniqueTuples(pagedThroughRows,
|
|
168
|
+
let throughTuples = uniqueTuples(pagedThroughRows, through.throughSourceKey)
|
|
167
169
|
|
|
168
170
|
if (throughTuples.length === 0) {
|
|
169
171
|
return sourceRows.map(() => [])
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
let targetQuery = createQuery(relation.targetTable)
|
|
173
|
-
let targetPredicate = buildLinkPredicate(
|
|
175
|
+
let targetPredicate = buildLinkPredicate(through.throughTargetKey, throughTuples)
|
|
174
176
|
|
|
175
177
|
if (targetPredicate) {
|
|
176
178
|
targetQuery = targetQuery.where(
|
|
@@ -183,27 +185,54 @@ async function loadHasManyThroughValues(
|
|
|
183
185
|
})
|
|
184
186
|
|
|
185
187
|
let relatedRows = await loadRowsWithRelationsForQuery(database, targetQuery)
|
|
186
|
-
let
|
|
188
|
+
let sourceKeysByThroughKey = new Map<string, Set<string>>()
|
|
189
|
+
let outputRowsBySourceKey = new Map<string, Map<string, Record<string, unknown>>>()
|
|
187
190
|
|
|
188
|
-
|
|
191
|
+
for (let sourceRow of sourceRows) {
|
|
189
192
|
let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey)
|
|
190
193
|
let matchedThroughRows = pagedThroughRowsBySource.get(sourceKey) ?? []
|
|
191
|
-
|
|
192
|
-
|
|
194
|
+
|
|
195
|
+
outputRowsBySourceKey.set(sourceKey, new Map())
|
|
193
196
|
|
|
194
197
|
for (let throughRow of matchedThroughRows) {
|
|
195
|
-
let throughKey = getCompositeKey(throughRow,
|
|
196
|
-
let
|
|
198
|
+
let throughKey = getCompositeKey(throughRow, through.throughSourceKey)
|
|
199
|
+
let sourceKeys = sourceKeysByThroughKey.get(throughKey)
|
|
200
|
+
|
|
201
|
+
if (!sourceKeys) {
|
|
202
|
+
sourceKeys = new Set()
|
|
203
|
+
sourceKeysByThroughKey.set(throughKey, sourceKeys)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
sourceKeys.add(sourceKey)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
let targetPrimaryKey = getTablePrimaryKey(relation.targetTable)
|
|
197
211
|
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
for (let row of relatedRows) {
|
|
213
|
+
let throughKey = getCompositeKey(row, through.throughTargetKey)
|
|
214
|
+
let sourceKeys = sourceKeysByThroughKey.get(throughKey)
|
|
200
215
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
216
|
+
if (!sourceKeys) {
|
|
217
|
+
continue
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let rowIdentity = getCompositeKey(row, targetPrimaryKey)
|
|
221
|
+
|
|
222
|
+
for (let sourceKey of sourceKeys) {
|
|
223
|
+
let outputRows = outputRowsBySourceKey.get(sourceKey)
|
|
224
|
+
|
|
225
|
+
if (!outputRows || outputRows.has(rowIdentity)) {
|
|
226
|
+
continue
|
|
205
227
|
}
|
|
228
|
+
|
|
229
|
+
outputRows.set(rowIdentity, row)
|
|
206
230
|
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return sourceRows.map((sourceRow) => {
|
|
234
|
+
let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey)
|
|
235
|
+
let outputRows = Array.from(outputRowsBySourceKey.get(sourceKey)?.values() ?? [])
|
|
207
236
|
|
|
208
237
|
return applyPagination(outputRows, relation.modifiers.limit, relation.modifiers.offset)
|
|
209
238
|
})
|
package/src/lib/operators.ts
CHANGED
|
@@ -66,6 +66,9 @@ export type WhereObject<column extends string = string> = Partial<Record<column,
|
|
|
66
66
|
*/
|
|
67
67
|
export type WhereInput<column extends string = string> = Predicate<column> | WhereObject<column>
|
|
68
68
|
|
|
69
|
+
type WhereInputColumn<input extends WhereInput> =
|
|
70
|
+
input extends Predicate<infer column> ? column : keyof input & string
|
|
71
|
+
|
|
69
72
|
/**
|
|
70
73
|
* Builds an equality predicate.
|
|
71
74
|
*/
|
|
@@ -293,23 +296,33 @@ export function notNull<column extends string | ColumnReferenceLike>(
|
|
|
293
296
|
}
|
|
294
297
|
|
|
295
298
|
/**
|
|
296
|
-
* Combines
|
|
297
|
-
* @param
|
|
299
|
+
* Combines where inputs with logical `AND`.
|
|
300
|
+
* @param inputs Child predicates or object shorthand filters.
|
|
298
301
|
* @returns A logical `and` predicate.
|
|
299
302
|
*/
|
|
300
|
-
export function and<
|
|
301
|
-
|
|
302
|
-
|
|
303
|
+
export function and<inputs extends WhereInput[]>(
|
|
304
|
+
...inputs: inputs
|
|
305
|
+
): Predicate<WhereInputColumn<inputs[number]>> {
|
|
306
|
+
type column = WhereInputColumn<inputs[number]>
|
|
307
|
+
let predicates = inputs
|
|
308
|
+
.filter(Boolean)
|
|
309
|
+
.map((input) => normalizeWhereInput(input) as Predicate<column>)
|
|
310
|
+
return { type: 'logical', operator: 'and', predicates }
|
|
303
311
|
}
|
|
304
312
|
|
|
305
313
|
/**
|
|
306
|
-
* Combines
|
|
307
|
-
* @param
|
|
314
|
+
* Combines where inputs with logical `OR`.
|
|
315
|
+
* @param inputs Child predicates or object shorthand filters.
|
|
308
316
|
* @returns A logical `or` predicate.
|
|
309
317
|
*/
|
|
310
|
-
export function or<
|
|
311
|
-
|
|
312
|
-
|
|
318
|
+
export function or<inputs extends WhereInput[]>(
|
|
319
|
+
...inputs: inputs
|
|
320
|
+
): Predicate<WhereInputColumn<inputs[number]>> {
|
|
321
|
+
type column = WhereInputColumn<inputs[number]>
|
|
322
|
+
let predicates = inputs
|
|
323
|
+
.filter(Boolean)
|
|
324
|
+
.map((input) => normalizeWhereInput(input) as Predicate<column>)
|
|
325
|
+
return { type: 'logical', operator: 'or', predicates }
|
|
313
326
|
}
|
|
314
327
|
|
|
315
328
|
/**
|