-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathparser.ts
45 lines (38 loc) · 1.36 KB
/
parser.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
import { constant } from "fp-ts/lib/function";
import { tryCatch } from "fp-ts/lib/TaskEither";
import * as pg from "pg";
import { parse } from "postgres-array";
import { makeTypeParserSetupError } from "./errors";
import { parseInterval } from "./pgTypes/interval";
import { TypeParser, TypeParsers } from "./types";
import { SQL } from "./utils/sql";
interface RowType {
oid: number;
typarray: number;
typname: string;
}
const typeQuery = (name: string) => SQL`
SELECT typname, oid, typarray
FROM pg_type
WHERE typname = ${name}
ORDER BY oid;`;
const arrayParser = (typeParser: TypeParser<any>) => (input: string) => parse(input, typeParser);
export const setupParsers = (pool: pg.Pool) => (parsers: TypeParsers) => {
const parserSet: TypeParsers = { interval: parseInterval, ...parsers };
const queries = Object.keys(parserSet).map(name => pool.query(typeQuery(name)));
return tryCatch(
() =>
Promise.all(queries)
.then(results => results.map<RowType>(({ rows: [type] }) => type))
.then(types => {
types.map(type => {
const parser = parserSet[type.typname];
pg.types.setTypeParser(type.oid, parser);
if (type.typarray) {
pg.types.setTypeParser(type.typarray, arrayParser(parser));
}
});
}),
makeTypeParserSetupError,
).map(constant(pool));
};