-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfetching.ts
61 lines (58 loc) · 2.01 KB
/
fetching.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import type { Table } from '.';
import { organizeObjectsByUniqueValue, type AnnotatedMap } from '../util';
import type { InstanceDataOfModel, Model } from './util/raw-model';
import type {
InstanceOfVersionedModel,
VersionedModel,
} from './util/versioned-model';
/**
* Generic type that can be used to obtain the type of an instance of either a
* standard table, or a versioned table.
*/
type InstanceOf<T extends Table> =
T extends Model<any>
? InstanceDataOfModel<T>
: T extends VersionedModel<any, any, any>
? InstanceOfVersionedModel<T>
: never;
/**
* Fetch a number of items of a particular type from the database,
* and organize them into an AnnotatedMap by a unique property.
*
* The property selected must non-null for every instance retrieved from the
* database, otherwise an error will be thrown
*/
export const findAndOrganizeObjectsByUniqueProperty = <
T extends Table,
P extends keyof InstanceOf<T>,
>(
table: T,
fetch: (tbl: T) => Promise<Iterable<InstanceOf<T>>>,
property: P
): Promise<AnnotatedMap<Exclude<InstanceOf<T>[P], null>, InstanceOf<T>>> => {
return findAndOrganizeObjectsByUniqueValue(table, fetch, (item) => {
const val = item[property];
if (val === null) {
throw new Error(
`Unexpected null value in ${property.toString()} for ${item}`
);
}
return val as Exclude<InstanceOf<T>[P], null>;
});
};
/**
* Fetch a number of items of a particular type from the database,
* and organize them into an AnnotatedMap by a unique value.
*/
export const findAndOrganizeObjectsByUniqueValue = async <T extends Table, V>(
table: T,
fetch: (tbl: T) => Promise<Iterable<InstanceOf<T>>>,
getValue: (i: InstanceOf<T>) => Exclude<V, null>
): Promise<AnnotatedMap<Exclude<V, null>, InstanceOf<T>>> => {
const values = await fetch(table);
const tableName =
table._internals.type === 'single-table'
? table._internals.tableName
: table._internals.root.tableName;
return organizeObjectsByUniqueValue(values, getValue, tableName);
};