@supabase/postgrest-typegen 0.2.0 → 0.2.2
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 +12 -0
- package/dist/collation.d.ts +2 -0
- package/dist/collation.js +15 -0
- package/dist/generation/go.js +30 -2
- package/dist/generation/index.d.ts +1 -1
- package/dist/generation/python.js +24 -10
- package/dist/generation/swift.js +52 -3
- package/dist/generation/typescript.d.ts +18 -7
- package/dist/generation/typescript.js +122 -82
- package/dist/introspection/index.js +6 -23
- package/dist/introspection/relationships.d.ts +4 -4
- package/dist/introspection/relationships.js +4 -11
- package/dist/introspection/sql/columns.sql.d.ts +2 -7
- package/dist/introspection/sql/columns.sql.js +32 -9
- package/dist/introspection/sql/common.d.ts +7 -15
- package/dist/introspection/sql/foreign_tables.sql.d.ts +2 -6
- package/dist/introspection/sql/foreign_tables.sql.js +0 -5
- package/dist/introspection/sql/functions.sql.d.ts +2 -5
- package/dist/introspection/sql/functions.sql.js +0 -33
- package/dist/introspection/sql/helpers.d.ts +1 -1
- package/dist/introspection/sql/helpers.js +2 -2
- package/dist/introspection/sql/materialized_views.sql.d.ts +2 -4
- package/dist/introspection/sql/materialized_views.sql.js +0 -5
- package/dist/introspection/sql/pg-format.d.ts +21 -0
- package/dist/introspection/sql/pg-format.js +92 -0
- package/dist/introspection/sql/primary_keys.sql.d.ts +2 -4
- package/dist/introspection/sql/primary_keys.sql.js +0 -4
- package/dist/introspection/sql/schemas.sql.d.ts +2 -6
- package/dist/introspection/sql/schemas.sql.js +2 -6
- package/dist/introspection/sql/table.sql.d.ts +2 -4
- package/dist/introspection/sql/table.sql.js +0 -5
- package/dist/introspection/sql/table_relationships.sql.d.ts +2 -2
- package/dist/introspection/sql/types.sql.d.ts +5 -5
- package/dist/introspection/sql/types.sql.js +6 -17
- package/dist/introspection/sql/views.sql.d.ts +2 -4
- package/dist/introspection/sql/views.sql.js +6 -5
- package/dist/introspection/sql/views_key_dependencies.sql.d.ts +2 -2
- package/dist/introspection/sql/views_key_dependencies.sql.js +64 -75
- package/dist/sort.js +16 -15
- package/dist/types.d.ts +4 -0
- package/dist/types.js +11 -0
- package/package.json +3 -5
- package/src/collation.ts +16 -0
- package/src/generation/go.ts +31 -2
- package/src/generation/index.ts +1 -0
- package/src/generation/python.ts +25 -10
- package/src/generation/swift.ts +53 -3
- package/src/generation/typescript.ts +187 -107
- package/src/introspection/index.ts +7 -32
- package/src/introspection/relationships.ts +10 -19
- package/src/introspection/sql/columns.sql.ts +34 -18
- package/src/introspection/sql/common.ts +7 -17
- package/src/introspection/sql/foreign_tables.sql.ts +2 -13
- package/src/introspection/sql/functions.sql.ts +2 -44
- package/src/introspection/sql/helpers.ts +2 -2
- package/src/introspection/sql/materialized_views.sql.ts +2 -11
- package/src/introspection/sql/pg-format.ts +101 -0
- package/src/introspection/sql/primary_keys.sql.ts +2 -10
- package/src/introspection/sql/schemas.sql.ts +4 -14
- package/src/introspection/sql/table.sql.ts +2 -11
- package/src/introspection/sql/table_relationships.sql.ts +2 -4
- package/src/introspection/sql/types.sql.ts +6 -26
- package/src/introspection/sql/views.sql.ts +8 -11
- package/src/introspection/sql/views_key_dependencies.sql.ts +83 -77
- package/src/sort.ts +20 -15
- package/src/types.ts +11 -0
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryPropsWithSchemaFilter } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const COLUMNS_SQL = (
|
|
5
|
-
props: SQLQueryPropsWithSchemaFilter & {
|
|
6
|
-
tableIdFilter?: string;
|
|
7
|
-
tableIdentifierFilter?: string;
|
|
8
|
-
columnNameFilter?: string;
|
|
9
|
-
idsFilter?: string;
|
|
10
|
-
},
|
|
11
|
-
) => /* SQL */ `
|
|
3
|
+
export const COLUMNS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
12
4
|
-- Adapted from information_schema.columns
|
|
13
5
|
|
|
14
6
|
SELECT
|
|
@@ -45,14 +37,44 @@ SELECT
|
|
|
45
37
|
WHEN 'd' THEN 'BY DEFAULT'
|
|
46
38
|
ELSE NULL
|
|
47
39
|
END AS identity_generation,
|
|
48
|
-
|
|
40
|
+
-- 's' = stored, 'v' = virtual (PostgreSQL 18+); neither accepts writes.
|
|
41
|
+
a.attgenerated IN ('s', 'v') AS is_generated,
|
|
49
42
|
NOT (
|
|
50
43
|
a.attnotnull
|
|
51
44
|
OR t.typtype = 'd' AND t.typnotnull
|
|
52
45
|
) AS is_nullable,
|
|
53
46
|
(
|
|
54
47
|
c.relkind IN ('r', 'p')
|
|
55
|
-
|
|
48
|
+
-- Columns of views made writable by INSTEAD OF triggers or unconditional
|
|
49
|
+
-- INSTEAD rules can be written through PostgREST even though the view is
|
|
50
|
+
-- not auto-updatable, so they must not degrade to \`?: never\` in generated
|
|
51
|
+
-- Insert/Update types. pg_column_is_updatable cannot express this: it
|
|
52
|
+
-- requires the relation to support both UPDATE and DELETE, so a view with
|
|
53
|
+
-- only an INSTEAD OF INSERT or only an INSTEAD OF UPDATE trigger reports
|
|
54
|
+
-- every column as non-updatable regardless of include_triggers. Triggers
|
|
55
|
+
-- and rules rewrite whole rows, so their presence makes every column
|
|
56
|
+
-- writable (tgtype bits: 64 = INSTEAD, 4 = INSERT, 16 = UPDATE;
|
|
57
|
+
-- pg_rewrite ev_type: '2' = UPDATE, '3' = INSERT; ev_qual is '<>' for
|
|
58
|
+
-- unconditional rules, and only unconditional INSTEAD rules make a view
|
|
59
|
+
-- writable). Which events a view accepts is gated per view via
|
|
60
|
+
-- is_insert_enabled / is_update_enabled.
|
|
61
|
+
OR c.relkind IN ('v', 'f') AND (
|
|
62
|
+
pg_column_is_updatable(c.oid, a.attnum, FALSE)
|
|
63
|
+
OR EXISTS (
|
|
64
|
+
SELECT 1 FROM pg_trigger tg
|
|
65
|
+
WHERE tg.tgrelid = c.oid
|
|
66
|
+
AND tg.tgtype & 64 <> 0
|
|
67
|
+
AND tg.tgtype & 20 <> 0
|
|
68
|
+
AND NOT tg.tgisinternal
|
|
69
|
+
)
|
|
70
|
+
OR EXISTS (
|
|
71
|
+
SELECT 1 FROM pg_rewrite rw
|
|
72
|
+
WHERE rw.ev_class = c.oid
|
|
73
|
+
AND rw.is_instead
|
|
74
|
+
AND rw.ev_type IN ('2', '3')
|
|
75
|
+
AND rw.ev_qual :: text = '<>'
|
|
76
|
+
)
|
|
77
|
+
)
|
|
56
78
|
) AS is_updatable,
|
|
57
79
|
uniques.table_id IS NOT NULL AS is_unique,
|
|
58
80
|
check_constraints.definition AS "check",
|
|
@@ -110,10 +132,6 @@ FROM
|
|
|
110
132
|
) AS check_constraints ON check_constraints.table_id = c.oid AND check_constraints.ordinal_position = a.attnum
|
|
111
133
|
WHERE
|
|
112
134
|
${props.schemaFilter ? `nc.nspname ${props.schemaFilter} AND` : ""}
|
|
113
|
-
${props.idsFilter ? `(c.oid || '.' || a.attnum) ${props.idsFilter} AND` : ""}
|
|
114
|
-
${props.columnNameFilter ? `(c.relname || '.' || a.attname) ${props.columnNameFilter} AND` : ""}
|
|
115
|
-
${props.tableIdFilter ? `c.oid ${props.tableIdFilter} AND` : ""}
|
|
116
|
-
${props.tableIdentifierFilter ? `nc.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ""}
|
|
117
135
|
NOT pg_is_other_temp_schema(nc.oid)
|
|
118
136
|
AND a.attnum > 0
|
|
119
137
|
AND NOT a.attisdropped
|
|
@@ -126,6 +144,4 @@ WHERE
|
|
|
126
144
|
'SELECT, INSERT, UPDATE, REFERENCES'
|
|
127
145
|
)
|
|
128
146
|
)
|
|
129
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
130
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
131
147
|
`;
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
offset?: number;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type SQLQueryPropsWithSchemaFilter = SQLQueryProps & {
|
|
12
|
-
schemaFilter?: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type SQLQueryPropsWithSchemaFilterAndIdsFilter = SQLQueryProps & {
|
|
16
|
-
schemaFilter?: string;
|
|
17
|
-
idsFilter?: string;
|
|
1
|
+
/** The only option the introspection passes to its SQL builders. */
|
|
2
|
+
export type SchemaFilterProps = {
|
|
3
|
+
/**
|
|
4
|
+
* An `IN (…)` or `NOT IN (…)` fragment from `filterByList`, or the empty
|
|
5
|
+
* string for no filter.
|
|
6
|
+
*/
|
|
7
|
+
schemaFilter: string;
|
|
18
8
|
};
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryProps } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const FOREIGN_TABLES_SQL = (
|
|
5
|
-
props: SQLQueryProps & {
|
|
6
|
-
schemaFilter?: string;
|
|
7
|
-
idsFilter?: string;
|
|
8
|
-
tableIdentifierFilter?: string;
|
|
9
|
-
},
|
|
10
|
-
) => /* SQL */ `
|
|
3
|
+
export const FOREIGN_TABLES_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
11
4
|
SELECT
|
|
12
5
|
c.oid :: int8 AS id,
|
|
13
6
|
n.nspname AS schema,
|
|
@@ -18,9 +11,5 @@ FROM
|
|
|
18
11
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
19
12
|
WHERE
|
|
20
13
|
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ""}
|
|
21
|
-
${props.idsFilter ? `c.oid ${props.idsFilter} AND` : ""}
|
|
22
|
-
${props.tableIdentifierFilter ? `(n.nspname || '.' || c.relname) ${props.tableIdentifierFilter} AND` : ""}
|
|
23
14
|
c.relkind = 'f'
|
|
24
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
25
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
26
15
|
`;
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
// builder, which interpolates the `args` string[] into the SQL (relying on Array#toString). The
|
|
3
|
-
// expression sits inside a template literal where a targeted disable comment would corrupt the SQL.
|
|
4
|
-
import { literal } from "pg-format";
|
|
5
|
-
import type { SQLQueryPropsWithSchemaFilterAndIdsFilter } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
6
2
|
|
|
7
|
-
export const FUNCTIONS_SQL = (
|
|
8
|
-
props: SQLQueryPropsWithSchemaFilterAndIdsFilter & {
|
|
9
|
-
nameFilter?: string;
|
|
10
|
-
args?: string[];
|
|
11
|
-
},
|
|
12
|
-
) => /* SQL */ `
|
|
3
|
+
export const FUNCTIONS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
13
4
|
-- CTE with sane arg_modes, arg_names, and arg_types.
|
|
14
5
|
-- All three are always of the same length.
|
|
15
6
|
-- All three include all args, including OUT and TABLE args.
|
|
@@ -36,37 +27,6 @@ with functions as (
|
|
|
36
27
|
${props.schemaFilter ? `join pg_namespace n on p.pronamespace = n.oid` : ""}
|
|
37
28
|
where
|
|
38
29
|
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ""}
|
|
39
|
-
${props.idsFilter ? `p.oid ${props.idsFilter} AND` : ""}
|
|
40
|
-
${props.nameFilter ? `p.proname ${props.nameFilter} AND` : ""}
|
|
41
|
-
${
|
|
42
|
-
props.args === undefined
|
|
43
|
-
? ""
|
|
44
|
-
: props.args.length > 0
|
|
45
|
-
? `p.proargtypes::text = ${
|
|
46
|
-
props.args.length
|
|
47
|
-
? `(
|
|
48
|
-
SELECT STRING_AGG(type_oid::text, ' ') FROM (
|
|
49
|
-
SELECT (
|
|
50
|
-
split_args.arr[
|
|
51
|
-
array_length(
|
|
52
|
-
split_args.arr,
|
|
53
|
-
1
|
|
54
|
-
)
|
|
55
|
-
]::regtype::oid
|
|
56
|
-
) AS type_oid FROM (
|
|
57
|
-
SELECT STRING_TO_ARRAY(
|
|
58
|
-
UNNEST(
|
|
59
|
-
ARRAY[${props.args}]
|
|
60
|
-
),
|
|
61
|
-
' '
|
|
62
|
-
) AS arr
|
|
63
|
-
) AS split_args
|
|
64
|
-
) args
|
|
65
|
-
)`
|
|
66
|
-
: "''"
|
|
67
|
-
} AND`
|
|
68
|
-
: ""
|
|
69
|
-
}
|
|
70
30
|
p.prokind = 'f'
|
|
71
31
|
)
|
|
72
32
|
select
|
|
@@ -154,6 +114,4 @@ from
|
|
|
154
114
|
group by
|
|
155
115
|
t1.oid
|
|
156
116
|
) f_args on f_args.oid = f.oid
|
|
157
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
158
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
159
117
|
`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { literal } from "pg-format";
|
|
1
|
+
import { literal } from "./pg-format.ts";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Schemas that postgres-meta excludes by default when `includeSystemSchemas`
|
|
@@ -13,7 +13,7 @@ export const DEFAULT_SYSTEM_SCHEMAS = [
|
|
|
13
13
|
/**
|
|
14
14
|
* Build a SQL `IN (...)` / `NOT IN (...)` fragment for an include/exclude list,
|
|
15
15
|
* ported verbatim from `postgres-meta/src/lib/helpers.ts`. Values are escaped
|
|
16
|
-
* with pg-format
|
|
16
|
+
* with the inlined pg-format `literal`. Returns an empty string when there is nothing to
|
|
17
17
|
* filter, so callers interpolate it conditionally.
|
|
18
18
|
*/
|
|
19
19
|
export const filterByList = (
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryPropsWithSchemaFilterAndIdsFilter } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const MATERIALIZED_VIEWS_SQL = (
|
|
5
|
-
props: SQLQueryPropsWithSchemaFilterAndIdsFilter & {
|
|
6
|
-
materializedViewIdentifierFilter?: string;
|
|
7
|
-
},
|
|
8
|
-
) => /* SQL */ `
|
|
3
|
+
export const MATERIALIZED_VIEWS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
9
4
|
select
|
|
10
5
|
c.oid::int8 as id,
|
|
11
6
|
n.nspname as schema,
|
|
@@ -17,9 +12,5 @@ from
|
|
|
17
12
|
join pg_namespace n on n.oid = c.relnamespace
|
|
18
13
|
where
|
|
19
14
|
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ""}
|
|
20
|
-
${props.idsFilter ? `c.oid ${props.idsFilter} AND` : ""}
|
|
21
|
-
${props.materializedViewIdentifierFilter ? `(n.nspname || '.' || c.relname) ${props.materializedViewIdentifierFilter} AND` : ""}
|
|
22
15
|
c.relkind = 'm'
|
|
23
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
24
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
25
16
|
`;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal inline port of the `pg-format` helpers this package uses, so the
|
|
3
|
+
* package carries no runtime dependency for them (the CommonJS-only
|
|
4
|
+
* `pg-format` package is awkward to consume from ESM/bundled CLIs).
|
|
5
|
+
*
|
|
6
|
+
* Mirrors `pg-format@1.0.4` byte-for-byte for the inputs postgres-meta feeds
|
|
7
|
+
* it — in particular numbers are quoted (`literal(10)` is `'10'`), because
|
|
8
|
+
* that is what postgres-meta's SQL emits and this package is byte-parity
|
|
9
|
+
* constrained against it. The `supabase/supabase` `packages/pg-meta` port
|
|
10
|
+
* deliberately diverges here (unquoted numbers); do not "fix" this to match it.
|
|
11
|
+
*
|
|
12
|
+
* Originally ported from PostgreSQL's `src/interfaces/libpq/fe-exec.c`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Convert a JS ISO string to Postgres' default ISO 8601 form. */
|
|
16
|
+
function formatDate(date: string): string {
|
|
17
|
+
return date.replace("T", " ").replace("Z", "+00");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function arrayToList(
|
|
21
|
+
useSpace: boolean,
|
|
22
|
+
array: unknown[],
|
|
23
|
+
formatter: (value: unknown) => string,
|
|
24
|
+
): string {
|
|
25
|
+
let sql = useSpace ? " (" : "(";
|
|
26
|
+
for (const [index, element] of array.entries()) {
|
|
27
|
+
sql += (index === 0 ? "" : ", ") + formatter(element);
|
|
28
|
+
}
|
|
29
|
+
sql += ")";
|
|
30
|
+
return sql;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Quote a value as a SQL literal. `null`/`undefined` become `NULL`, booleans
|
|
35
|
+
* `'t'`/`'f'`, dates ISO 8601 strings, arrays comma-separated lists (nested
|
|
36
|
+
* arrays become parenthesised groups), plain objects `'…'::jsonb`, and
|
|
37
|
+
* everything else — including numbers — a single-quoted string with embedded
|
|
38
|
+
* quotes doubled. Strings containing a backslash use the `E'…'` form.
|
|
39
|
+
*/
|
|
40
|
+
export function literal(value?: unknown): string {
|
|
41
|
+
let text: string;
|
|
42
|
+
let explicitCast: string | undefined;
|
|
43
|
+
|
|
44
|
+
if (value === undefined || value === null) {
|
|
45
|
+
return "NULL";
|
|
46
|
+
}
|
|
47
|
+
if (value === false) {
|
|
48
|
+
return "'f'";
|
|
49
|
+
}
|
|
50
|
+
if (value === true) {
|
|
51
|
+
return "'t'";
|
|
52
|
+
}
|
|
53
|
+
if (value instanceof Date) {
|
|
54
|
+
return `'${formatDate(value.toISOString())}'`;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
const parts: string[] = [];
|
|
58
|
+
for (const [index, element] of value.entries()) {
|
|
59
|
+
if (Array.isArray(element)) {
|
|
60
|
+
parts.push(arrayToList(index !== 0, element, literal));
|
|
61
|
+
} else {
|
|
62
|
+
parts.push(literal(element));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return parts.toString();
|
|
66
|
+
}
|
|
67
|
+
if (typeof value === "string") {
|
|
68
|
+
text = value;
|
|
69
|
+
} else if (typeof value === "number" || typeof value === "bigint") {
|
|
70
|
+
text = value.toString();
|
|
71
|
+
} else {
|
|
72
|
+
explicitCast = "jsonb";
|
|
73
|
+
text = JSON.stringify(value);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let hasBackslash = false;
|
|
77
|
+
let quoted = "'";
|
|
78
|
+
|
|
79
|
+
for (const c of text) {
|
|
80
|
+
if (c === "'") {
|
|
81
|
+
quoted += c + c;
|
|
82
|
+
} else if (c === "\\") {
|
|
83
|
+
quoted += c + c;
|
|
84
|
+
hasBackslash = true;
|
|
85
|
+
} else {
|
|
86
|
+
quoted += c;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
quoted += "'";
|
|
91
|
+
|
|
92
|
+
if (hasBackslash) {
|
|
93
|
+
quoted = `E${quoted}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (explicitCast) {
|
|
97
|
+
quoted += `::${explicitCast}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return quoted;
|
|
101
|
+
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryPropsWithSchemaFilter } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const PRIMARY_KEYS_SQL = (
|
|
5
|
-
props: SQLQueryPropsWithSchemaFilter & {
|
|
6
|
-
tableIdentifierFilter?: string;
|
|
7
|
-
},
|
|
8
|
-
) => /* SQL */ `
|
|
3
|
+
export const PRIMARY_KEYS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
9
4
|
SELECT
|
|
10
5
|
c.oid :: int8 AS table_id,
|
|
11
6
|
n.nspname AS schema,
|
|
@@ -18,7 +13,6 @@ FROM
|
|
|
18
13
|
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(i.indkey)
|
|
19
14
|
WHERE
|
|
20
15
|
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ""}
|
|
21
|
-
${props.tableIdentifierFilter ? `n.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ""}
|
|
22
16
|
i.indisprimary
|
|
23
17
|
AND c.relkind IN ('r', 'p')
|
|
24
18
|
AND NOT pg_is_other_temp_schema(n.oid)
|
|
@@ -33,6 +27,4 @@ WHERE
|
|
|
33
27
|
ORDER BY
|
|
34
28
|
c.oid,
|
|
35
29
|
array_position(i.indkey, a.attnum)
|
|
36
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
37
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
38
30
|
`;
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryProps } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const SCHEMAS_SQL = (
|
|
5
|
-
props: SQLQueryProps & {
|
|
6
|
-
nameFilter?: string;
|
|
7
|
-
idsFilter?: string;
|
|
8
|
-
includeSystemSchemas?: boolean;
|
|
9
|
-
},
|
|
10
|
-
) => /* SQL */ `
|
|
3
|
+
export const SCHEMAS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
11
4
|
-- Adapted from information_schema.schemata
|
|
12
5
|
select
|
|
13
6
|
n.oid::int8 as id,
|
|
@@ -18,15 +11,12 @@ from
|
|
|
18
11
|
pg_roles u
|
|
19
12
|
where
|
|
20
13
|
n.nspowner = u.oid
|
|
21
|
-
${props.
|
|
22
|
-
|
|
23
|
-
${!props.includeSystemSchemas ? `and not pg_catalog.starts_with(n.nspname, 'pg_')` : ""}
|
|
14
|
+
${props.schemaFilter ? `and n.nspname ${props.schemaFilter}` : ""}
|
|
15
|
+
and not pg_catalog.starts_with(n.nspname, 'pg_')
|
|
24
16
|
and (
|
|
25
17
|
pg_has_role(n.nspowner, 'USAGE')
|
|
26
18
|
or has_schema_privilege(n.oid, 'CREATE, USAGE')
|
|
27
19
|
)
|
|
28
20
|
and not pg_catalog.starts_with(n.nspname, 'pg_temp_')
|
|
29
21
|
and not pg_catalog.starts_with(n.nspname, 'pg_toast_temp_')
|
|
30
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
31
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
32
22
|
`;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryPropsWithSchemaFilterAndIdsFilter } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const TABLES_SQL = (
|
|
5
|
-
props: SQLQueryPropsWithSchemaFilterAndIdsFilter & {
|
|
6
|
-
tableIdentifierFilter?: string;
|
|
7
|
-
},
|
|
8
|
-
) => /* SQL */ `
|
|
3
|
+
export const TABLES_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
9
4
|
SELECT
|
|
10
5
|
c.oid :: int8 AS id,
|
|
11
6
|
nc.nspname AS schema,
|
|
@@ -30,8 +25,6 @@ FROM
|
|
|
30
25
|
JOIN pg_class c ON nc.oid = c.relnamespace
|
|
31
26
|
WHERE
|
|
32
27
|
${props.schemaFilter ? `nc.nspname ${props.schemaFilter} AND` : ""}
|
|
33
|
-
${props.idsFilter ? `c.oid ${props.idsFilter} AND` : ""}
|
|
34
|
-
${props.tableIdentifierFilter ? `nc.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ""}
|
|
35
28
|
c.relkind IN ('r', 'p')
|
|
36
29
|
AND NOT pg_is_other_temp_schema(nc.oid)
|
|
37
30
|
AND (
|
|
@@ -42,6 +35,4 @@ WHERE
|
|
|
42
35
|
)
|
|
43
36
|
OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')
|
|
44
37
|
)
|
|
45
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
46
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
47
38
|
`;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
2
2
|
|
|
3
|
-
export const TABLE_RELATIONSHIPS_SQL = (
|
|
4
|
-
props: SQLQueryPropsWithSchemaFilter,
|
|
5
|
-
) => /* SQL */ `
|
|
3
|
+
export const TABLE_RELATIONSHIPS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
6
4
|
-- Adapted from
|
|
7
5
|
-- https://github.com/PostgREST/postgrest/blob/f9f0f79fa914ac00c11fbf7f4c558e14821e67e2/src/PostgREST/SchemaCache.hs#L722
|
|
8
6
|
WITH
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
includeTableTypes?: boolean;
|
|
7
|
-
includeArrayTypes?: boolean;
|
|
8
|
-
},
|
|
9
|
-
) => /* SQL */ `
|
|
1
|
+
/**
|
|
2
|
+
* Every type of every schema, including the row types of tables and views
|
|
3
|
+
* and the array types, since a column of any schema may use them.
|
|
4
|
+
*/
|
|
5
|
+
export const TYPES_SQL = /* SQL */ `
|
|
10
6
|
select
|
|
11
7
|
t.oid::int8 as id,
|
|
12
8
|
t.typname as name,
|
|
@@ -48,27 +44,11 @@ from
|
|
|
48
44
|
t.typrelid = 0
|
|
49
45
|
or (
|
|
50
46
|
select
|
|
51
|
-
c.relkind
|
|
47
|
+
c.relkind in ('c', 'r', 'v', 'm', 'p', 'f')
|
|
52
48
|
from
|
|
53
49
|
pg_class c
|
|
54
50
|
where
|
|
55
51
|
c.oid = t.typrelid
|
|
56
52
|
)
|
|
57
53
|
)
|
|
58
|
-
${
|
|
59
|
-
!props.includeArrayTypes
|
|
60
|
-
? `and not exists (
|
|
61
|
-
select
|
|
62
|
-
from
|
|
63
|
-
pg_type el
|
|
64
|
-
where
|
|
65
|
-
el.oid = t.typelem
|
|
66
|
-
and el.typarray = t.oid
|
|
67
|
-
)`
|
|
68
|
-
: ""
|
|
69
|
-
}
|
|
70
|
-
${props.schemaFilter ? `and n.nspname ${props.schemaFilter}` : ""}
|
|
71
|
-
${props.idsFilter ? `and t.oid ${props.idsFilter}` : ""}
|
|
72
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
73
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
74
54
|
`;
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SQLQueryPropsWithSchemaFilterAndIdsFilter } from "./common.ts";
|
|
1
|
+
import type { SchemaFilterProps } from "./common.ts";
|
|
3
2
|
|
|
4
|
-
export const VIEWS_SQL = (
|
|
5
|
-
props: SQLQueryPropsWithSchemaFilterAndIdsFilter & {
|
|
6
|
-
viewIdentifierFilter?: string;
|
|
7
|
-
},
|
|
8
|
-
) => /* SQL */ `
|
|
3
|
+
export const VIEWS_SQL = (props: SchemaFilterProps) => /* SQL */ `
|
|
9
4
|
SELECT
|
|
10
5
|
c.oid :: int8 AS id,
|
|
11
6
|
n.nspname AS schema,
|
|
12
7
|
c.relname AS name,
|
|
13
8
|
-- See definition of information_schema.views
|
|
14
9
|
(pg_relation_is_updatable(c.oid, false) & 20) = 20 AS is_updatable,
|
|
10
|
+
-- Passing include_triggers => true also counts views made writable by
|
|
11
|
+
-- INSTEAD OF triggers (and INSTEAD rules), which PostgREST can write
|
|
12
|
+
-- through even when the view is not auto-updatable. Bit 8 is INSERT,
|
|
13
|
+
-- bit 4 is UPDATE (see information_schema.views).
|
|
14
|
+
(pg_relation_is_updatable(c.oid, true) & 8) = 8 AS is_insert_enabled,
|
|
15
|
+
(pg_relation_is_updatable(c.oid, true) & 4) = 4 AS is_update_enabled,
|
|
15
16
|
obj_description(c.oid) AS comment
|
|
16
17
|
FROM
|
|
17
18
|
pg_class c
|
|
18
19
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
19
20
|
WHERE
|
|
20
21
|
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ""}
|
|
21
|
-
${props.idsFilter ? `c.oid ${props.idsFilter} AND` : ""}
|
|
22
|
-
${props.viewIdentifierFilter ? `(n.nspname || '.' || c.relname) ${props.viewIdentifierFilter} AND` : ""}
|
|
23
22
|
c.relkind = 'v'
|
|
24
|
-
${props.limit ? `limit ${literal(props.limit)}` : ""}
|
|
25
|
-
${props.offset ? `offset ${literal(props.offset)}` : ""}
|
|
26
23
|
`;
|