Skip to content

Commit f397839

Browse files
committed
feat: multi-statement queries & arrayMode
1 parent a1fe900 commit f397839

File tree

4 files changed

+105
-36
lines changed

4 files changed

+105
-36
lines changed

src/lib/PostgresMeta.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ import PostgresMetaTypes from './PostgresMetaTypes'
1414
import PostgresMetaVersion from './PostgresMetaVersion'
1515
import PostgresMetaViews from './PostgresMetaViews'
1616
import { init } from './db'
17-
import { PostgresMetaResult } from './types'
1817
export default class PostgresMeta {
19-
query: (sql: string) => Promise<PostgresMetaResult<any>>
18+
query: (sql: string) => Promise<any>
2019
end: () => Promise<void>
2120
columns: PostgresMetaColumns
2221
config: PostgresMetaConfig
@@ -37,21 +36,21 @@ export default class PostgresMeta {
3736
format = Parser.Format
3837

3938
constructor(config: PoolConfig) {
40-
const { query, end } = init(config)
41-
this.query = query
39+
const { query, queryArrayMode, end } = init(config)
40+
this.query = queryArrayMode
4241
this.end = end
43-
this.columns = new PostgresMetaColumns(this.query)
44-
this.config = new PostgresMetaConfig(this.query)
45-
this.extensions = new PostgresMetaExtensions(this.query)
46-
this.functions = new PostgresMetaFunctions(this.query)
47-
this.policies = new PostgresMetaPolicies(this.query)
48-
this.publications = new PostgresMetaPublications(this.query)
49-
this.roles = new PostgresMetaRoles(this.query)
50-
this.schemas = new PostgresMetaSchemas(this.query)
51-
this.tables = new PostgresMetaTables(this.query)
52-
this.triggers = new PostgresMetaTriggers(this.query)
53-
this.types = new PostgresMetaTypes(this.query)
54-
this.version = new PostgresMetaVersion(this.query)
55-
this.views = new PostgresMetaViews(this.query)
42+
this.columns = new PostgresMetaColumns(query)
43+
this.config = new PostgresMetaConfig(query)
44+
this.extensions = new PostgresMetaExtensions(query)
45+
this.functions = new PostgresMetaFunctions(query)
46+
this.policies = new PostgresMetaPolicies(query)
47+
this.publications = new PostgresMetaPublications(query)
48+
this.roles = new PostgresMetaRoles(query)
49+
this.schemas = new PostgresMetaSchemas(query)
50+
this.tables = new PostgresMetaTables(query)
51+
this.triggers = new PostgresMetaTriggers(query)
52+
this.types = new PostgresMetaTypes(query)
53+
this.version = new PostgresMetaVersion(query)
54+
this.views = new PostgresMetaViews(query)
5655
}
5756
}

src/lib/db.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ types.setTypeParser(1185, parseArray) // _timestamptz
1212

1313
export const init: (config: PoolConfig) => {
1414
query: (sql: string) => Promise<PostgresMetaResult<any>>
15+
queryArrayMode: (sql: string) => Promise<any>
1516
end: () => Promise<void>
1617
} = (config) => {
1718
// NOTE: Race condition could happen here: one async task may be doing
@@ -38,6 +39,45 @@ export const init: (config: PoolConfig) => {
3839
}
3940
},
4041

42+
async queryArrayMode(sql) {
43+
try {
44+
if (!pool) {
45+
const pool = new Pool(config)
46+
let res: any = await pool.query({
47+
rowMode: 'array',
48+
text: sql,
49+
})
50+
if (!Array.isArray(res)) {
51+
res = [res]
52+
}
53+
return {
54+
data: res.map(({ fields, rows }: any) => ({
55+
columns: fields.map((x: any) => x.name),
56+
rows,
57+
})),
58+
error: null,
59+
}
60+
}
61+
62+
let res: any = await pool.query({
63+
rowMode: 'array',
64+
text: sql,
65+
})
66+
if (!Array.isArray(res)) {
67+
res = [res]
68+
}
69+
return {
70+
data: res.map(({ fields, rows }: any) => ({
71+
columns: fields.map((x: any) => x.name),
72+
rows,
73+
})),
74+
error: null,
75+
}
76+
} catch (e: any) {
77+
return { data: null, error: { message: e.message } }
78+
}
79+
},
80+
4181
async end() {
4282
const _pool = pool
4383
pool = null

test/lib/columns.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,14 @@ AND i.indisprimary;
235235
Object {
236236
"data": Array [
237237
Object {
238-
"attname": "c",
238+
"columns": Array [
239+
"attname",
240+
],
241+
"rows": Array [
242+
Array [
243+
"c",
244+
],
245+
],
239246
},
240247
],
241248
"error": null,
@@ -267,7 +274,14 @@ AND i.indisunique;
267274
Object {
268275
"data": Array [
269276
Object {
270-
"attname": "c",
277+
"columns": Array [
278+
"attname",
279+
],
280+
"rows": Array [
281+
Array [
282+
"c",
283+
],
284+
],
271285
},
272286
],
273287
"error": null,
@@ -387,7 +401,14 @@ SELECT pg_get_constraintdef((
387401
Object {
388402
"data": Array [
389403
Object {
390-
"pg_get_constraintdef": null,
404+
"columns": Array [
405+
"pg_get_constraintdef",
406+
],
407+
"rows": Array [
408+
Array [
409+
null,
410+
],
411+
],
391412
},
392413
],
393414
"error": null,

test/lib/query.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@ test('query', async () => {
66
Object {
77
"data": Array [
88
Object {
9-
"id": 1,
10-
"name": "Joe Bloggs",
11-
"status": "ACTIVE",
12-
},
13-
Object {
14-
"id": 2,
15-
"name": "Jane Doe",
16-
"status": "ACTIVE",
9+
"columns": Array [
10+
"id",
11+
"name",
12+
"status",
13+
],
14+
"rows": Array [
15+
Array [
16+
1,
17+
"Joe Bloggs",
18+
"ACTIVE",
19+
],
20+
Array [
21+
2,
22+
"Jane Doe",
23+
"ACTIVE",
24+
],
25+
],
1726
},
1827
],
1928
"error": null,
@@ -463,14 +472,14 @@ CREATE TABLE table_name (
463472

464473
const deparse = pgMeta.deparse(res.data!)
465474
expect(deparse.data).toMatchInlineSnapshot(`
466-
"CREATE TABLE table_name (
467-
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
468-
inserted_at pg_catalog.timestamptz DEFAULT ( timezone('utc'::text, now()) ) NOT NULL,
469-
updated_at pg_catalog.timestamptz DEFAULT ( timezone('utc'::text, now()) ) NOT NULL,
470-
data jsonb,
471-
name text
472-
);"
473-
`)
475+
"CREATE TABLE table_name (
476+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
477+
inserted_at pg_catalog.timestamptz DEFAULT ( timezone('utc'::text, now()) ) NOT NULL,
478+
updated_at pg_catalog.timestamptz DEFAULT ( timezone('utc'::text, now()) ) NOT NULL,
479+
data jsonb,
480+
name text
481+
);"
482+
`)
474483
})
475484

476485
test('formatter', async () => {

0 commit comments

Comments
 (0)