relq 1.0.94 → 1.0.96
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/dist/cjs/cli/adapters/cockroachdb/index.cjs +1 -1
- package/dist/cjs/cli/adapters/cockroachdb/introspect.cjs +118 -0
- package/dist/cjs/cli/adapters/dsql/index.cjs +1 -1
- package/dist/cjs/cli/adapters/dsql/introspect.cjs +125 -0
- package/dist/cjs/cli/adapters/mysql/index.cjs +1 -1
- package/dist/cjs/cli/adapters/nile/index.cjs +1 -1
- package/dist/cjs/cli/adapters/nile/introspect.cjs +115 -0
- package/dist/cjs/cli/adapters/postgres/index.cjs +1 -1
- package/dist/cjs/cli/adapters/postgres/introspect.cjs +115 -0
- package/dist/cjs/cli/commands/generate.cjs +127 -18
- package/dist/cjs/cli/commands/push.cjs +139 -24
- package/dist/cjs/cli/utils/ast-transformer.cjs +19 -0
- package/dist/cjs/cli/utils/cockroachdb/introspect.cjs +115 -3
- package/dist/cjs/cli/utils/dsql/introspect.cjs +122 -3
- package/dist/cjs/cli/utils/migration-generator.cjs +278 -23
- package/dist/cjs/cli/utils/nile/introspect.cjs +112 -3
- package/dist/cjs/cli/utils/postgres/introspect.cjs +112 -3
- package/dist/cjs/cli/utils/schema-diff.cjs +73 -9
- package/dist/cjs/cli/utils/schema-hash.cjs +18 -14
- package/dist/cjs/cli/utils/schema-loader.cjs +43 -5
- package/dist/cjs/cli/utils/schema-to-ast.cjs +33 -15
- package/dist/cjs/core/helpers/ConnectedQueryBuilder.cjs +9 -0
- package/dist/cjs/core/helpers/ConnectedSelectBuilder.cjs +31 -0
- package/dist/cjs/core/helpers/query-convenience.cjs +125 -0
- package/dist/cjs/index.cjs +4 -2
- package/dist/cjs/insert/insert-from-select-builder.cjs +48 -0
- package/dist/cjs/raw/index.cjs +4 -1
- package/dist/cjs/raw/sql-template.cjs +73 -0
- package/dist/esm/cli/adapters/cockroachdb/index.js +1 -1
- package/dist/esm/cli/adapters/cockroachdb/introspect.js +118 -0
- package/dist/esm/cli/adapters/dsql/index.js +1 -1
- package/dist/esm/cli/adapters/dsql/introspect.js +125 -0
- package/dist/esm/cli/adapters/mysql/index.js +1 -1
- package/dist/esm/cli/adapters/nile/index.js +1 -1
- package/dist/esm/cli/adapters/nile/introspect.js +115 -0
- package/dist/esm/cli/adapters/postgres/index.js +1 -1
- package/dist/esm/cli/adapters/postgres/introspect.js +115 -0
- package/dist/esm/cli/commands/generate.js +129 -20
- package/dist/esm/cli/commands/push.js +141 -26
- package/dist/esm/cli/utils/ast-transformer.js +19 -0
- package/dist/esm/cli/utils/cockroachdb/introspect.js +115 -3
- package/dist/esm/cli/utils/dsql/introspect.js +122 -3
- package/dist/esm/cli/utils/migration-generator.js +277 -23
- package/dist/esm/cli/utils/nile/introspect.js +112 -3
- package/dist/esm/cli/utils/postgres/introspect.js +112 -3
- package/dist/esm/cli/utils/schema-diff.js +73 -9
- package/dist/esm/cli/utils/schema-hash.js +18 -14
- package/dist/esm/cli/utils/schema-loader.js +43 -5
- package/dist/esm/cli/utils/schema-to-ast.js +33 -15
- package/dist/esm/core/helpers/ConnectedQueryBuilder.js +10 -1
- package/dist/esm/core/helpers/ConnectedSelectBuilder.js +31 -0
- package/dist/esm/core/helpers/query-convenience.js +90 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/insert/insert-from-select-builder.js +41 -0
- package/dist/esm/raw/index.js +1 -0
- package/dist/esm/raw/sql-template.js +66 -0
- package/dist/index.d.ts +186 -0
- package/package.json +1 -1
|
@@ -157,7 +157,7 @@ class CockroachDBAdapter {
|
|
|
157
157
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
158
158
|
name VARCHAR(255) NOT NULL,
|
|
159
159
|
filename VARCHAR(255) NOT NULL,
|
|
160
|
-
hash VARCHAR(
|
|
160
|
+
hash VARCHAR(255) NOT NULL,
|
|
161
161
|
batch INTEGER NOT NULL,
|
|
162
162
|
applied_at TIMESTAMPTZ DEFAULT NOW(),
|
|
163
163
|
execution_time_ms INTEGER,
|
|
@@ -67,6 +67,12 @@ async function introspectCockroachDB(connection, options) {
|
|
|
67
67
|
const constraints = await introspectConstraints(pool);
|
|
68
68
|
options?.onProgress?.('fetching_enums');
|
|
69
69
|
const enums = await introspectEnums(pool);
|
|
70
|
+
options?.onProgress?.('fetching_domains');
|
|
71
|
+
const domains = await introspectDomains(pool);
|
|
72
|
+
options?.onProgress?.('fetching_sequences');
|
|
73
|
+
const sequences = await introspectSequences(pool);
|
|
74
|
+
options?.onProgress?.('fetching_composite_types');
|
|
75
|
+
const compositeTypes = await introspectCompositeTypes(pool);
|
|
70
76
|
let functions;
|
|
71
77
|
if (options?.includeFunctions) {
|
|
72
78
|
options?.onProgress?.('fetching_functions');
|
|
@@ -92,6 +98,9 @@ async function introspectCockroachDB(connection, options) {
|
|
|
92
98
|
indexes,
|
|
93
99
|
constraints,
|
|
94
100
|
enums,
|
|
101
|
+
domains,
|
|
102
|
+
sequences,
|
|
103
|
+
compositeTypes,
|
|
95
104
|
functions,
|
|
96
105
|
triggers,
|
|
97
106
|
schemas,
|
|
@@ -583,3 +592,112 @@ async function introspectTriggers(pool) {
|
|
|
583
592
|
enabled: row.enabled,
|
|
584
593
|
}));
|
|
585
594
|
}
|
|
595
|
+
async function introspectDomains(pool) {
|
|
596
|
+
const result = await pool.query(`
|
|
597
|
+
SELECT
|
|
598
|
+
t.typname as name,
|
|
599
|
+
n.nspname as schema,
|
|
600
|
+
pg_catalog.format_type(t.typbasetype, t.typtypmod) as base_type,
|
|
601
|
+
t.typnotnull as is_not_null,
|
|
602
|
+
pg_catalog.pg_get_expr(t.typdefaultbin, 0) as default_value,
|
|
603
|
+
(SELECT pg_catalog.pg_get_constraintdef(c.oid)
|
|
604
|
+
FROM pg_constraint c
|
|
605
|
+
WHERE c.contypid = t.oid
|
|
606
|
+
LIMIT 1) as check_expression
|
|
607
|
+
FROM pg_type t
|
|
608
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
609
|
+
WHERE t.typtype = 'd'
|
|
610
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
611
|
+
AND n.nspname != 'information_schema'
|
|
612
|
+
AND n.nspname != 'crdb_internal'
|
|
613
|
+
ORDER BY n.nspname, t.typname
|
|
614
|
+
`);
|
|
615
|
+
return result.rows.map((row) => ({
|
|
616
|
+
name: row.name,
|
|
617
|
+
baseType: row.base_type,
|
|
618
|
+
isNotNull: row.is_not_null,
|
|
619
|
+
defaultValue: row.default_value,
|
|
620
|
+
checkExpression: row.check_expression,
|
|
621
|
+
}));
|
|
622
|
+
}
|
|
623
|
+
async function introspectSequences(pool) {
|
|
624
|
+
const result = await pool.query(`
|
|
625
|
+
SELECT
|
|
626
|
+
c.relname as name,
|
|
627
|
+
n.nspname as schema,
|
|
628
|
+
s.seqtypid::regtype::text as data_type,
|
|
629
|
+
s.seqstart::text as start_value,
|
|
630
|
+
s.seqincrement::text as increment,
|
|
631
|
+
s.seqmin::text as min_value,
|
|
632
|
+
s.seqmax::text as max_value,
|
|
633
|
+
s.seqcache::text as cache,
|
|
634
|
+
s.seqcycle as cycle,
|
|
635
|
+
d_table.relname as owned_by_table,
|
|
636
|
+
a.attname as owned_by_column
|
|
637
|
+
FROM pg_sequence s
|
|
638
|
+
JOIN pg_class c ON s.seqrelid = c.oid
|
|
639
|
+
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
640
|
+
LEFT JOIN pg_depend dep ON dep.objid = c.oid
|
|
641
|
+
AND dep.classid = 'pg_class'::regclass
|
|
642
|
+
AND dep.deptype = 'a'
|
|
643
|
+
LEFT JOIN pg_class d_table ON dep.refobjid = d_table.oid
|
|
644
|
+
AND d_table.relkind = 'r'
|
|
645
|
+
LEFT JOIN pg_attribute a ON a.attrelid = dep.refobjid
|
|
646
|
+
AND a.attnum = dep.refobjsubid
|
|
647
|
+
WHERE n.nspname NOT LIKE 'pg_%'
|
|
648
|
+
AND n.nspname != 'information_schema'
|
|
649
|
+
AND n.nspname != 'crdb_internal'
|
|
650
|
+
AND NOT EXISTS (
|
|
651
|
+
SELECT 1 FROM pg_depend di
|
|
652
|
+
WHERE di.objid = c.oid
|
|
653
|
+
AND di.classid = 'pg_class'::regclass
|
|
654
|
+
AND di.deptype = 'i'
|
|
655
|
+
)
|
|
656
|
+
ORDER BY n.nspname, c.relname
|
|
657
|
+
`);
|
|
658
|
+
return result.rows.map((row) => ({
|
|
659
|
+
name: row.name,
|
|
660
|
+
dataType: row.data_type,
|
|
661
|
+
start: row.start_value ? Number(row.start_value) : undefined,
|
|
662
|
+
increment: row.increment ? Number(row.increment) : undefined,
|
|
663
|
+
minValue: row.min_value ? Number(row.min_value) : undefined,
|
|
664
|
+
maxValue: row.max_value ? Number(row.max_value) : undefined,
|
|
665
|
+
cache: row.cache ? Number(row.cache) : undefined,
|
|
666
|
+
cycle: row.cycle,
|
|
667
|
+
ownedBy: row.owned_by_table && row.owned_by_column
|
|
668
|
+
? `${row.owned_by_table}.${row.owned_by_column}`
|
|
669
|
+
: undefined,
|
|
670
|
+
}));
|
|
671
|
+
}
|
|
672
|
+
async function introspectCompositeTypes(pool) {
|
|
673
|
+
const result = await pool.query(`
|
|
674
|
+
SELECT
|
|
675
|
+
t.typname as name,
|
|
676
|
+
n.nspname as schema,
|
|
677
|
+
array_agg(a.attname ORDER BY a.attnum) as attribute_names,
|
|
678
|
+
array_agg(pg_catalog.format_type(a.atttypid, a.atttypmod) ORDER BY a.attnum) as attribute_types
|
|
679
|
+
FROM pg_type t
|
|
680
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
681
|
+
JOIN pg_attribute a ON a.attrelid = t.typrelid
|
|
682
|
+
AND a.attnum > 0
|
|
683
|
+
AND NOT a.attisdropped
|
|
684
|
+
WHERE t.typtype = 'c'
|
|
685
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
686
|
+
AND n.nspname != 'information_schema'
|
|
687
|
+
AND n.nspname != 'crdb_internal'
|
|
688
|
+
AND NOT EXISTS (
|
|
689
|
+
SELECT 1 FROM pg_class c
|
|
690
|
+
WHERE c.reltype = t.oid
|
|
691
|
+
AND c.relkind IN ('r', 'v', 'm', 'f')
|
|
692
|
+
)
|
|
693
|
+
GROUP BY t.oid, t.typname, n.nspname
|
|
694
|
+
ORDER BY n.nspname, t.typname
|
|
695
|
+
`);
|
|
696
|
+
return result.rows.map((row) => ({
|
|
697
|
+
name: row.name,
|
|
698
|
+
attributes: (row.attribute_names || []).map((attrName, i) => ({
|
|
699
|
+
name: attrName,
|
|
700
|
+
type: row.attribute_types[i],
|
|
701
|
+
})),
|
|
702
|
+
}));
|
|
703
|
+
}
|
|
@@ -172,7 +172,7 @@ class DsqlAdapter {
|
|
|
172
172
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
173
173
|
name VARCHAR(255) NOT NULL,
|
|
174
174
|
filename VARCHAR(255) NOT NULL,
|
|
175
|
-
hash VARCHAR(
|
|
175
|
+
hash VARCHAR(255) NOT NULL,
|
|
176
176
|
batch INTEGER NOT NULL,
|
|
177
177
|
applied_at TIMESTAMPTZ DEFAULT NOW(),
|
|
178
178
|
execution_time_ms INTEGER,
|
|
@@ -65,6 +65,12 @@ async function introspectDsql(connection, options) {
|
|
|
65
65
|
const constraints = await introspectConstraints(pool);
|
|
66
66
|
options?.onProgress?.('fetching_enums');
|
|
67
67
|
const enums = await introspectEnums(pool);
|
|
68
|
+
options?.onProgress?.('fetching_domains');
|
|
69
|
+
const domains = await introspectDomains(pool);
|
|
70
|
+
options?.onProgress?.('fetching_sequences');
|
|
71
|
+
const sequences = await introspectSequences(pool);
|
|
72
|
+
options?.onProgress?.('fetching_composite_types');
|
|
73
|
+
const compositeTypes = await introspectCompositeTypes(pool);
|
|
68
74
|
let functions;
|
|
69
75
|
if (options?.includeFunctions) {
|
|
70
76
|
options?.onProgress?.('fetching_functions');
|
|
@@ -89,6 +95,9 @@ async function introspectDsql(connection, options) {
|
|
|
89
95
|
indexes,
|
|
90
96
|
constraints,
|
|
91
97
|
enums,
|
|
98
|
+
domains,
|
|
99
|
+
sequences,
|
|
100
|
+
compositeTypes,
|
|
92
101
|
functions,
|
|
93
102
|
triggers,
|
|
94
103
|
schemas,
|
|
@@ -568,3 +577,119 @@ async function introspectTriggers(pool) {
|
|
|
568
577
|
enabled: row.enabled,
|
|
569
578
|
}));
|
|
570
579
|
}
|
|
580
|
+
async function introspectDomains(pool) {
|
|
581
|
+
const result = await pool.query(`
|
|
582
|
+
SELECT
|
|
583
|
+
t.typname as name,
|
|
584
|
+
n.nspname as schema,
|
|
585
|
+
pg_catalog.format_type(t.typbasetype, t.typtypmod) as base_type,
|
|
586
|
+
t.typnotnull as is_not_null,
|
|
587
|
+
pg_catalog.pg_get_expr(t.typdefaultbin, 0) as default_value,
|
|
588
|
+
(SELECT pg_catalog.pg_get_constraintdef(c.oid)
|
|
589
|
+
FROM pg_constraint c
|
|
590
|
+
WHERE c.contypid = t.oid
|
|
591
|
+
LIMIT 1) as check_expression
|
|
592
|
+
FROM pg_type t
|
|
593
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
594
|
+
WHERE t.typtype = 'd'
|
|
595
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
596
|
+
AND n.nspname != 'information_schema'
|
|
597
|
+
ORDER BY n.nspname, t.typname
|
|
598
|
+
`);
|
|
599
|
+
return result.rows.map((row) => ({
|
|
600
|
+
name: row.name,
|
|
601
|
+
baseType: row.base_type,
|
|
602
|
+
isNotNull: row.is_not_null,
|
|
603
|
+
defaultValue: row.default_value,
|
|
604
|
+
checkExpression: row.check_expression,
|
|
605
|
+
}));
|
|
606
|
+
}
|
|
607
|
+
async function introspectSequences(pool) {
|
|
608
|
+
try {
|
|
609
|
+
const result = await pool.query(`
|
|
610
|
+
SELECT
|
|
611
|
+
c.relname as name,
|
|
612
|
+
n.nspname as schema,
|
|
613
|
+
s.seqtypid::regtype::text as data_type,
|
|
614
|
+
s.seqstart::text as start_value,
|
|
615
|
+
s.seqincrement::text as increment,
|
|
616
|
+
s.seqmin::text as min_value,
|
|
617
|
+
s.seqmax::text as max_value,
|
|
618
|
+
s.seqcache::text as cache,
|
|
619
|
+
s.seqcycle as cycle,
|
|
620
|
+
d_table.relname as owned_by_table,
|
|
621
|
+
a.attname as owned_by_column
|
|
622
|
+
FROM pg_sequence s
|
|
623
|
+
JOIN pg_class c ON s.seqrelid = c.oid
|
|
624
|
+
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
625
|
+
LEFT JOIN pg_depend dep ON dep.objid = c.oid
|
|
626
|
+
AND dep.classid = 'pg_class'::regclass
|
|
627
|
+
AND dep.deptype = 'a'
|
|
628
|
+
LEFT JOIN pg_class d_table ON dep.refobjid = d_table.oid
|
|
629
|
+
AND d_table.relkind = 'r'
|
|
630
|
+
LEFT JOIN pg_attribute a ON a.attrelid = dep.refobjid
|
|
631
|
+
AND a.attnum = dep.refobjsubid
|
|
632
|
+
WHERE n.nspname NOT LIKE 'pg_%'
|
|
633
|
+
AND n.nspname != 'information_schema'
|
|
634
|
+
AND NOT EXISTS (
|
|
635
|
+
SELECT 1 FROM pg_depend di
|
|
636
|
+
WHERE di.objid = c.oid
|
|
637
|
+
AND di.classid = 'pg_class'::regclass
|
|
638
|
+
AND di.deptype = 'i'
|
|
639
|
+
)
|
|
640
|
+
ORDER BY n.nspname, c.relname
|
|
641
|
+
`);
|
|
642
|
+
return result.rows.map((row) => ({
|
|
643
|
+
name: row.name,
|
|
644
|
+
dataType: row.data_type,
|
|
645
|
+
start: row.start_value ? Number(row.start_value) : undefined,
|
|
646
|
+
increment: row.increment ? Number(row.increment) : undefined,
|
|
647
|
+
minValue: row.min_value ? Number(row.min_value) : undefined,
|
|
648
|
+
maxValue: row.max_value ? Number(row.max_value) : undefined,
|
|
649
|
+
cache: row.cache ? Number(row.cache) : undefined,
|
|
650
|
+
cycle: row.cycle,
|
|
651
|
+
ownedBy: row.owned_by_table && row.owned_by_column
|
|
652
|
+
? `${row.owned_by_table}.${row.owned_by_column}`
|
|
653
|
+
: undefined,
|
|
654
|
+
}));
|
|
655
|
+
}
|
|
656
|
+
catch {
|
|
657
|
+
return [];
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async function introspectCompositeTypes(pool) {
|
|
661
|
+
try {
|
|
662
|
+
const result = await pool.query(`
|
|
663
|
+
SELECT
|
|
664
|
+
t.typname as name,
|
|
665
|
+
n.nspname as schema,
|
|
666
|
+
array_agg(a.attname ORDER BY a.attnum) as attribute_names,
|
|
667
|
+
array_agg(pg_catalog.format_type(a.atttypid, a.atttypmod) ORDER BY a.attnum) as attribute_types
|
|
668
|
+
FROM pg_type t
|
|
669
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
670
|
+
JOIN pg_attribute a ON a.attrelid = t.typrelid
|
|
671
|
+
AND a.attnum > 0
|
|
672
|
+
AND NOT a.attisdropped
|
|
673
|
+
WHERE t.typtype = 'c'
|
|
674
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
675
|
+
AND n.nspname != 'information_schema'
|
|
676
|
+
AND NOT EXISTS (
|
|
677
|
+
SELECT 1 FROM pg_class c
|
|
678
|
+
WHERE c.reltype = t.oid
|
|
679
|
+
AND c.relkind IN ('r', 'v', 'm', 'f')
|
|
680
|
+
)
|
|
681
|
+
GROUP BY t.oid, t.typname, n.nspname
|
|
682
|
+
ORDER BY n.nspname, t.typname
|
|
683
|
+
`);
|
|
684
|
+
return result.rows.map((row) => ({
|
|
685
|
+
name: row.name,
|
|
686
|
+
attributes: (row.attribute_names || []).map((attrName, i) => ({
|
|
687
|
+
name: attrName,
|
|
688
|
+
type: row.attribute_types[i],
|
|
689
|
+
})),
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
catch {
|
|
693
|
+
return [];
|
|
694
|
+
}
|
|
695
|
+
}
|
|
@@ -228,7 +228,7 @@ class MySQLAdapter {
|
|
|
228
228
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
229
229
|
name VARCHAR(255) NOT NULL,
|
|
230
230
|
filename VARCHAR(255) NOT NULL,
|
|
231
|
-
hash VARCHAR(
|
|
231
|
+
hash VARCHAR(255) NOT NULL,
|
|
232
232
|
batch INT NOT NULL,
|
|
233
233
|
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
234
234
|
execution_time_ms INT,
|
|
@@ -161,7 +161,7 @@ class NileAdapter {
|
|
|
161
161
|
id SERIAL PRIMARY KEY,
|
|
162
162
|
name VARCHAR(255) NOT NULL,
|
|
163
163
|
filename VARCHAR(255) NOT NULL,
|
|
164
|
-
hash VARCHAR(
|
|
164
|
+
hash VARCHAR(255) NOT NULL,
|
|
165
165
|
batch INTEGER NOT NULL,
|
|
166
166
|
applied_at TIMESTAMPTZ DEFAULT NOW(),
|
|
167
167
|
execution_time_ms INTEGER,
|
|
@@ -64,6 +64,12 @@ async function introspectNile(connection, options) {
|
|
|
64
64
|
const constraints = await introspectConstraints(pool);
|
|
65
65
|
options?.onProgress?.('fetching_enums');
|
|
66
66
|
const enums = await introspectEnums(pool);
|
|
67
|
+
options?.onProgress?.('fetching_domains');
|
|
68
|
+
const domains = await introspectDomains(pool);
|
|
69
|
+
options?.onProgress?.('fetching_sequences');
|
|
70
|
+
const sequences = await introspectSequences(pool);
|
|
71
|
+
options?.onProgress?.('fetching_composite_types');
|
|
72
|
+
const compositeTypes = await introspectCompositeTypes(pool);
|
|
67
73
|
let functions;
|
|
68
74
|
if (options?.includeFunctions) {
|
|
69
75
|
options?.onProgress?.('fetching_functions');
|
|
@@ -88,6 +94,9 @@ async function introspectNile(connection, options) {
|
|
|
88
94
|
indexes,
|
|
89
95
|
constraints,
|
|
90
96
|
enums,
|
|
97
|
+
domains,
|
|
98
|
+
sequences,
|
|
99
|
+
compositeTypes,
|
|
91
100
|
functions,
|
|
92
101
|
triggers,
|
|
93
102
|
schemas,
|
|
@@ -564,3 +573,109 @@ async function introspectTriggers(pool) {
|
|
|
564
573
|
enabled: row.enabled,
|
|
565
574
|
}));
|
|
566
575
|
}
|
|
576
|
+
async function introspectDomains(pool) {
|
|
577
|
+
const result = await pool.query(`
|
|
578
|
+
SELECT
|
|
579
|
+
t.typname as name,
|
|
580
|
+
n.nspname as schema,
|
|
581
|
+
pg_catalog.format_type(t.typbasetype, t.typtypmod) as base_type,
|
|
582
|
+
t.typnotnull as is_not_null,
|
|
583
|
+
pg_catalog.pg_get_expr(t.typdefaultbin, 0) as default_value,
|
|
584
|
+
(SELECT pg_catalog.pg_get_constraintdef(c.oid)
|
|
585
|
+
FROM pg_constraint c
|
|
586
|
+
WHERE c.contypid = t.oid
|
|
587
|
+
LIMIT 1) as check_expression
|
|
588
|
+
FROM pg_type t
|
|
589
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
590
|
+
WHERE t.typtype = 'd'
|
|
591
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
592
|
+
AND n.nspname != 'information_schema'
|
|
593
|
+
ORDER BY n.nspname, t.typname
|
|
594
|
+
`);
|
|
595
|
+
return result.rows.map((row) => ({
|
|
596
|
+
name: row.name,
|
|
597
|
+
baseType: row.base_type,
|
|
598
|
+
isNotNull: row.is_not_null,
|
|
599
|
+
defaultValue: row.default_value,
|
|
600
|
+
checkExpression: row.check_expression,
|
|
601
|
+
}));
|
|
602
|
+
}
|
|
603
|
+
async function introspectSequences(pool) {
|
|
604
|
+
const result = await pool.query(`
|
|
605
|
+
SELECT
|
|
606
|
+
c.relname as name,
|
|
607
|
+
n.nspname as schema,
|
|
608
|
+
s.seqtypid::regtype::text as data_type,
|
|
609
|
+
s.seqstart::text as start_value,
|
|
610
|
+
s.seqincrement::text as increment,
|
|
611
|
+
s.seqmin::text as min_value,
|
|
612
|
+
s.seqmax::text as max_value,
|
|
613
|
+
s.seqcache::text as cache,
|
|
614
|
+
s.seqcycle as cycle,
|
|
615
|
+
d_table.relname as owned_by_table,
|
|
616
|
+
a.attname as owned_by_column
|
|
617
|
+
FROM pg_sequence s
|
|
618
|
+
JOIN pg_class c ON s.seqrelid = c.oid
|
|
619
|
+
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
620
|
+
LEFT JOIN pg_depend dep ON dep.objid = c.oid
|
|
621
|
+
AND dep.classid = 'pg_class'::regclass
|
|
622
|
+
AND dep.deptype = 'a'
|
|
623
|
+
LEFT JOIN pg_class d_table ON dep.refobjid = d_table.oid
|
|
624
|
+
AND d_table.relkind = 'r'
|
|
625
|
+
LEFT JOIN pg_attribute a ON a.attrelid = dep.refobjid
|
|
626
|
+
AND a.attnum = dep.refobjsubid
|
|
627
|
+
WHERE n.nspname NOT LIKE 'pg_%'
|
|
628
|
+
AND n.nspname != 'information_schema'
|
|
629
|
+
AND NOT EXISTS (
|
|
630
|
+
SELECT 1 FROM pg_depend di
|
|
631
|
+
WHERE di.objid = c.oid
|
|
632
|
+
AND di.classid = 'pg_class'::regclass
|
|
633
|
+
AND di.deptype = 'i'
|
|
634
|
+
)
|
|
635
|
+
ORDER BY n.nspname, c.relname
|
|
636
|
+
`);
|
|
637
|
+
return result.rows.map((row) => ({
|
|
638
|
+
name: row.name,
|
|
639
|
+
dataType: row.data_type,
|
|
640
|
+
start: row.start_value ? Number(row.start_value) : undefined,
|
|
641
|
+
increment: row.increment ? Number(row.increment) : undefined,
|
|
642
|
+
minValue: row.min_value ? Number(row.min_value) : undefined,
|
|
643
|
+
maxValue: row.max_value ? Number(row.max_value) : undefined,
|
|
644
|
+
cache: row.cache ? Number(row.cache) : undefined,
|
|
645
|
+
cycle: row.cycle,
|
|
646
|
+
ownedBy: row.owned_by_table && row.owned_by_column
|
|
647
|
+
? `${row.owned_by_table}.${row.owned_by_column}`
|
|
648
|
+
: undefined,
|
|
649
|
+
}));
|
|
650
|
+
}
|
|
651
|
+
async function introspectCompositeTypes(pool) {
|
|
652
|
+
const result = await pool.query(`
|
|
653
|
+
SELECT
|
|
654
|
+
t.typname as name,
|
|
655
|
+
n.nspname as schema,
|
|
656
|
+
array_agg(a.attname ORDER BY a.attnum) as attribute_names,
|
|
657
|
+
array_agg(pg_catalog.format_type(a.atttypid, a.atttypmod) ORDER BY a.attnum) as attribute_types
|
|
658
|
+
FROM pg_type t
|
|
659
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
660
|
+
JOIN pg_attribute a ON a.attrelid = t.typrelid
|
|
661
|
+
AND a.attnum > 0
|
|
662
|
+
AND NOT a.attisdropped
|
|
663
|
+
WHERE t.typtype = 'c'
|
|
664
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
665
|
+
AND n.nspname != 'information_schema'
|
|
666
|
+
AND NOT EXISTS (
|
|
667
|
+
SELECT 1 FROM pg_class c
|
|
668
|
+
WHERE c.reltype = t.oid
|
|
669
|
+
AND c.relkind IN ('r', 'v', 'm', 'f')
|
|
670
|
+
)
|
|
671
|
+
GROUP BY t.oid, t.typname, n.nspname
|
|
672
|
+
ORDER BY n.nspname, t.typname
|
|
673
|
+
`);
|
|
674
|
+
return result.rows.map((row) => ({
|
|
675
|
+
name: row.name,
|
|
676
|
+
attributes: (row.attribute_names || []).map((attrName, i) => ({
|
|
677
|
+
name: attrName,
|
|
678
|
+
type: row.attribute_types[i],
|
|
679
|
+
})),
|
|
680
|
+
}));
|
|
681
|
+
}
|
|
@@ -154,7 +154,7 @@ class PostgresAdapter {
|
|
|
154
154
|
id SERIAL PRIMARY KEY,
|
|
155
155
|
name VARCHAR(255) NOT NULL,
|
|
156
156
|
filename VARCHAR(255) NOT NULL,
|
|
157
|
-
hash VARCHAR(
|
|
157
|
+
hash VARCHAR(255) NOT NULL,
|
|
158
158
|
batch INTEGER NOT NULL,
|
|
159
159
|
applied_at TIMESTAMPTZ DEFAULT NOW(),
|
|
160
160
|
execution_time_ms INTEGER,
|
|
@@ -65,6 +65,12 @@ async function introspectPostgres(connection, options) {
|
|
|
65
65
|
const constraints = await introspectConstraints(pool);
|
|
66
66
|
options?.onProgress?.('fetching_enums');
|
|
67
67
|
const enums = await introspectEnums(pool);
|
|
68
|
+
options?.onProgress?.('fetching_domains');
|
|
69
|
+
const domains = await introspectDomains(pool);
|
|
70
|
+
options?.onProgress?.('fetching_sequences');
|
|
71
|
+
const sequences = await introspectSequences(pool);
|
|
72
|
+
options?.onProgress?.('fetching_composite_types');
|
|
73
|
+
const compositeTypes = await introspectCompositeTypes(pool);
|
|
68
74
|
let functions;
|
|
69
75
|
if (options?.includeFunctions) {
|
|
70
76
|
options?.onProgress?.('fetching_functions');
|
|
@@ -89,6 +95,9 @@ async function introspectPostgres(connection, options) {
|
|
|
89
95
|
indexes,
|
|
90
96
|
constraints,
|
|
91
97
|
enums,
|
|
98
|
+
domains,
|
|
99
|
+
sequences,
|
|
100
|
+
compositeTypes,
|
|
92
101
|
functions,
|
|
93
102
|
triggers,
|
|
94
103
|
schemas,
|
|
@@ -568,3 +577,109 @@ async function introspectTriggers(pool) {
|
|
|
568
577
|
enabled: row.enabled,
|
|
569
578
|
}));
|
|
570
579
|
}
|
|
580
|
+
async function introspectDomains(pool) {
|
|
581
|
+
const result = await pool.query(`
|
|
582
|
+
SELECT
|
|
583
|
+
t.typname as name,
|
|
584
|
+
n.nspname as schema,
|
|
585
|
+
pg_catalog.format_type(t.typbasetype, t.typtypmod) as base_type,
|
|
586
|
+
t.typnotnull as is_not_null,
|
|
587
|
+
pg_catalog.pg_get_expr(t.typdefaultbin, 0) as default_value,
|
|
588
|
+
(SELECT pg_catalog.pg_get_constraintdef(c.oid)
|
|
589
|
+
FROM pg_constraint c
|
|
590
|
+
WHERE c.contypid = t.oid
|
|
591
|
+
LIMIT 1) as check_expression
|
|
592
|
+
FROM pg_type t
|
|
593
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
594
|
+
WHERE t.typtype = 'd'
|
|
595
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
596
|
+
AND n.nspname != 'information_schema'
|
|
597
|
+
ORDER BY n.nspname, t.typname
|
|
598
|
+
`);
|
|
599
|
+
return result.rows.map((row) => ({
|
|
600
|
+
name: row.name,
|
|
601
|
+
baseType: row.base_type,
|
|
602
|
+
isNotNull: row.is_not_null,
|
|
603
|
+
defaultValue: row.default_value,
|
|
604
|
+
checkExpression: row.check_expression,
|
|
605
|
+
}));
|
|
606
|
+
}
|
|
607
|
+
async function introspectSequences(pool) {
|
|
608
|
+
const result = await pool.query(`
|
|
609
|
+
SELECT
|
|
610
|
+
c.relname as name,
|
|
611
|
+
n.nspname as schema,
|
|
612
|
+
s.seqtypid::regtype::text as data_type,
|
|
613
|
+
s.seqstart::text as start_value,
|
|
614
|
+
s.seqincrement::text as increment,
|
|
615
|
+
s.seqmin::text as min_value,
|
|
616
|
+
s.seqmax::text as max_value,
|
|
617
|
+
s.seqcache::text as cache,
|
|
618
|
+
s.seqcycle as cycle,
|
|
619
|
+
d_table.relname as owned_by_table,
|
|
620
|
+
a.attname as owned_by_column
|
|
621
|
+
FROM pg_sequence s
|
|
622
|
+
JOIN pg_class c ON s.seqrelid = c.oid
|
|
623
|
+
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
624
|
+
LEFT JOIN pg_depend dep ON dep.objid = c.oid
|
|
625
|
+
AND dep.classid = 'pg_class'::regclass
|
|
626
|
+
AND dep.deptype = 'a'
|
|
627
|
+
LEFT JOIN pg_class d_table ON dep.refobjid = d_table.oid
|
|
628
|
+
AND d_table.relkind = 'r'
|
|
629
|
+
LEFT JOIN pg_attribute a ON a.attrelid = dep.refobjid
|
|
630
|
+
AND a.attnum = dep.refobjsubid
|
|
631
|
+
WHERE n.nspname NOT LIKE 'pg_%'
|
|
632
|
+
AND n.nspname != 'information_schema'
|
|
633
|
+
AND NOT EXISTS (
|
|
634
|
+
SELECT 1 FROM pg_depend di
|
|
635
|
+
WHERE di.objid = c.oid
|
|
636
|
+
AND di.classid = 'pg_class'::regclass
|
|
637
|
+
AND di.deptype = 'i'
|
|
638
|
+
)
|
|
639
|
+
ORDER BY n.nspname, c.relname
|
|
640
|
+
`);
|
|
641
|
+
return result.rows.map((row) => ({
|
|
642
|
+
name: row.name,
|
|
643
|
+
dataType: row.data_type,
|
|
644
|
+
start: row.start_value ? Number(row.start_value) : undefined,
|
|
645
|
+
increment: row.increment ? Number(row.increment) : undefined,
|
|
646
|
+
minValue: row.min_value ? Number(row.min_value) : undefined,
|
|
647
|
+
maxValue: row.max_value ? Number(row.max_value) : undefined,
|
|
648
|
+
cache: row.cache ? Number(row.cache) : undefined,
|
|
649
|
+
cycle: row.cycle,
|
|
650
|
+
ownedBy: row.owned_by_table && row.owned_by_column
|
|
651
|
+
? `${row.owned_by_table}.${row.owned_by_column}`
|
|
652
|
+
: undefined,
|
|
653
|
+
}));
|
|
654
|
+
}
|
|
655
|
+
async function introspectCompositeTypes(pool) {
|
|
656
|
+
const result = await pool.query(`
|
|
657
|
+
SELECT
|
|
658
|
+
t.typname as name,
|
|
659
|
+
n.nspname as schema,
|
|
660
|
+
array_agg(a.attname ORDER BY a.attnum) as attribute_names,
|
|
661
|
+
array_agg(pg_catalog.format_type(a.atttypid, a.atttypmod) ORDER BY a.attnum) as attribute_types
|
|
662
|
+
FROM pg_type t
|
|
663
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
664
|
+
JOIN pg_attribute a ON a.attrelid = t.typrelid
|
|
665
|
+
AND a.attnum > 0
|
|
666
|
+
AND NOT a.attisdropped
|
|
667
|
+
WHERE t.typtype = 'c'
|
|
668
|
+
AND n.nspname NOT LIKE 'pg_%'
|
|
669
|
+
AND n.nspname != 'information_schema'
|
|
670
|
+
AND NOT EXISTS (
|
|
671
|
+
SELECT 1 FROM pg_class c
|
|
672
|
+
WHERE c.reltype = t.oid
|
|
673
|
+
AND c.relkind IN ('r', 'v', 'm', 'f')
|
|
674
|
+
)
|
|
675
|
+
GROUP BY t.oid, t.typname, n.nspname
|
|
676
|
+
ORDER BY n.nspname, t.typname
|
|
677
|
+
`);
|
|
678
|
+
return result.rows.map((row) => ({
|
|
679
|
+
name: row.name,
|
|
680
|
+
attributes: (row.attribute_names || []).map((attrName, i) => ({
|
|
681
|
+
name: attrName,
|
|
682
|
+
type: row.attribute_types[i],
|
|
683
|
+
})),
|
|
684
|
+
}));
|
|
685
|
+
}
|