add things

This commit is contained in:
johnnyfish
2024-08-29 09:52:35 +03:00
committed by Guy Ben-Aharon
parent 60804278df
commit 26aaebe5b8
3 changed files with 194 additions and 123 deletions

BIN
src/assets/supabase.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/timescale.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,5 +1,45 @@
export const postgresQuery = `WITH fk_info AS ( // Define the database options type
select array_to_string(array_agg(CONCAT('{"schema":"', schema_name, '"', type DatabaseOption = 'regular' | 'supabase' | 'timescale';
export const getPostgresQuery = (databaseOption?: DatabaseOption): string => {
// Define additional filters based on the database option
const supabaseFilters = `
AND connamespace::regnamespace::text NOT IN ('auth', 'extensions', 'pgsodium', 'realtime', 'storage', 'vault')
`;
const supabaseTableFilter = `
AND cols.table_schema NOT IN ('auth', 'extensions', 'pgsodium', 'realtime', 'storage', 'vault')
`;
const supabaseIndexesFilter = `
WHERE schema_name NOT IN ('auth', 'extensions', 'pgsodium', 'realtime', 'storage', 'vault')
`;
const supabaseViewsFilter = `
AND views.schemaname NOT IN ('auth', 'extensions', 'pgsodium', 'realtime', 'storage', 'vault')
`;
const timescaleFilters = `
AND connamespace::regnamespace::text !~ '^(timescaledb_|_timescaledb_)'
`;
const timescaleTableFilter = `
AND cols.table_schema !~ '^(timescaledb_|_timescaledb_)'
AND cols.table_name !~ '^(pg_stat_)'
`;
const timescaleIndexesFilter = `
WHERE schema_name !~ '^(timescaledb_|_timescaledb_)'
`;
const timescaleViewsFilter = `
AND views.schemaname !~ '^(timescaledb_|_timescaledb_)'
`;
// Define the base query
const query = `
WITH fk_info AS (
SELECT array_to_string(array_agg(CONCAT('{"schema":"', schema_name, '"',
',"table":"', replace(table_name::text, '"', ''), '"', ',"table":"', replace(table_name::text, '"', ''), '"',
',"column":"', replace(fk_column::text, '"', ''), '"', ',"column":"', replace(fk_column::text, '"', ''), '"',
',"foreign_key_name":"', foreign_key_name, '"', ',"foreign_key_name":"', foreign_key_name, '"',
@@ -7,8 +47,8 @@ export const postgresQuery = `WITH fk_info AS (
',"reference_column":"', reference_column, '"', ',"reference_column":"', reference_column, '"',
',"fk_def":"', fk_def, ',"fk_def":"', fk_def,
'"}')), ',') as fk_metadata '"}')), ',') as fk_metadata
from ( FROM (
SELECT connamespace::regnamespace::text as schema_name, SELECT connamespace::regnamespace::text AS schema_name,
conname AS foreign_key_name, conname AS foreign_key_name,
conrelid::regclass AS table_name, conrelid::regclass AS table_name,
(regexp_matches(pg_get_constraintdef(oid), 'FOREIGN KEY \\((\\w+)\\) REFERENCES (\\w+)\\((\\w+)\\)', 'g'))[1] AS fk_column, (regexp_matches(pg_get_constraintdef(oid), 'FOREIGN KEY \\((\\w+)\\) REFERENCES (\\w+)\\((\\w+)\\)', 'g'))[1] AS fk_column,
@@ -19,17 +59,22 @@ export const postgresQuery = `WITH fk_info AS (
pg_constraint pg_constraint
WHERE WHERE
contype = 'f' contype = 'f'
AND connamespace::regnamespace::text not in ('information_schema', 'pg_catalog') AND connamespace::regnamespace::text NOT IN ('information_schema', 'pg_catalog')${
AND connamespace::regnamespace::text !~ '^(timescaledb_|_timescaledb_)' databaseOption === 'timescale'
) as x ? timescaleFilters
), pk_info AS ( : databaseOption === 'supabase'
? supabaseFilters
: ''
}
) AS x
), pk_info AS (
SELECT array_to_string(array_agg(CONCAT('{"schema":"', schema_name, '"', SELECT array_to_string(array_agg(CONCAT('{"schema":"', schema_name, '"',
',"table":"', replace(pk_table, '"', ''), '"', ',"table":"', replace(pk_table, '"', ''), '"',
',"column":"', replace(pk_column, '"', ''), '"', ',"column":"', replace(pk_column, '"', ''), '"',
',"pk_def":"', replace(pk_def, '"', ''), ',"pk_def":"', replace(pk_def, '"', ''),
'"}')), ',') as pk_metadata '"}')), ',') AS pk_metadata
FROM ( FROM (
SELECT connamespace::regnamespace::text as schema_name, SELECT connamespace::regnamespace::text AS schema_name,
CASE CASE
WHEN strpos(conrelid::regclass::text, '.') > 0 WHEN strpos(conrelid::regclass::text, '.') > 0
THEN split_part(conrelid::regclass::text, '.', 2) THEN split_part(conrelid::regclass::text, '.', 2)
@@ -41,35 +86,41 @@ export const postgresQuery = `WITH fk_info AS (
pg_constraint pg_constraint
WHERE WHERE
contype = 'p' contype = 'p'
AND connamespace::regnamespace::text not in ('information_schema', 'pg_catalog') AND connamespace::regnamespace::text NOT IN ('information_schema', 'pg_catalog')${
AND connamespace::regnamespace::text !~ '^(timescaledb_|_timescaledb_)' databaseOption === 'timescale'
) as y ? timescaleFilters
), : databaseOption === 'supabase'
indexes_cols as ( select tnsp.nspname as schema_name, ? supabaseFilters
trel.relname as table_name, : ''
pg_relation_size(tnsp.nspname || '.' || '"' || irel.relname || '"') as index_size, }
irel.relname as index_name, ) AS y
am.amname as index_type, ),
a.attname as col_name, indexes_cols AS (
(case when i.indisunique = true then 'true' else 'false' end) as is_unique, SELECT tnsp.nspname AS schema_name,
irel.reltuples as cardinality, trel.relname AS table_name,
1 + Array_position(i.indkey, a.attnum) as column_position, pg_relation_size(tnsp.nspname || '.' || '"' || irel.relname || '"') AS index_size,
case o.OPTION & 1 when 1 then 'DESC' else 'ASC' end as direction, irel.relname AS index_name,
CASE WHEN indpred IS NOT NULL THEN 'true' ELSE 'false' END as is_partial_index am.amname AS index_type,
from pg_index as i a.attname AS col_name,
join pg_class as trel on trel.oid = i.indrelid (CASE WHEN i.indisunique = TRUE THEN 'true' ELSE 'false' END) AS is_unique,
join pg_namespace as tnsp on trel.relnamespace = tnsp.oid irel.reltuples AS cardinality,
join pg_class as irel on irel.oid = i.indexrelid 1 + Array_position(i.indkey, a.attnum) AS column_position,
join pg_am as am on irel.relam = am.oid CASE o.OPTION & 1 WHEN 1 THEN 'DESC' ELSE 'ASC' END AS direction,
cross join lateral unnest (i.indkey) CASE WHEN indpred IS NOT NULL THEN 'true' ELSE 'false' END AS is_partial_index
with ordinality as c (colnum, ordinality) left join lateral unnest (i.indoption) FROM pg_index AS i
with ordinality as o (option, ordinality) JOIN pg_class AS trel ON trel.oid = i.indrelid
on c.ordinality = o.ordinality join pg_attribute as a on trel.oid = a.attrelid and a.attnum = c.colnum JOIN pg_namespace AS tnsp ON trel.relnamespace = tnsp.oid
where tnsp.nspname not like 'pg_%' JOIN pg_class AS irel ON irel.oid = i.indexrelid
group by tnsp.nspname, trel.relname, irel.relname, am.amname, i.indisunique, i.indexrelid, irel.reltuples, a.attname, array_position(i.indkey, a.attnum), o.OPTION, i.indpred JOIN pg_am AS am ON irel.relam = am.oid
), CROSS JOIN LATERAL unnest (i.indkey)
cols as ( WITH ORDINALITY AS c (colnum, ordinality) LEFT JOIN LATERAL unnest (i.indoption)
select array_to_string(array_agg(CONCAT('{"schema":"', cols.table_schema, WITH ORDINALITY AS o (option, ordinality)
ON c.ordinality = o.ordinality JOIN pg_attribute AS a ON trel.oid = a.attrelid AND a.attnum = c.colnum
WHERE tnsp.nspname NOT LIKE 'pg_%'
GROUP BY tnsp.nspname, trel.relname, irel.relname, am.amname, i.indisunique, i.indexrelid, irel.reltuples, a.attname, Array_position(i.indkey, a.attnum), o.OPTION, i.indpred
),
cols AS (
SELECT array_to_string(array_agg(CONCAT('{"schema":"', cols.table_schema,
'","table":"', cols.table_name, '","table":"', cols.table_name,
'","name":"', cols.column_name, '","name":"', cols.column_name,
'","ordinal_position":"', cols.ordinal_position, '","ordinal_position":"', cols.ordinal_position,
@@ -82,58 +133,78 @@ cols as (
',"scale":', COALESCE(cols.numeric_scale::text, 'null'), '}') ',"scale":', COALESCE(cols.numeric_scale::text, 'null'), '}')
ELSE 'null' ELSE 'null'
END, END,
',"nullable":', case when (cols.IS_NULLABLE = 'YES') then 'true' else 'false' end, ',"nullable":', CASE WHEN (cols.IS_NULLABLE = 'YES') THEN 'true' ELSE 'false' END,
',"default":"', COALESCE(replace(replace(cols.column_default, '"', '\\"'), '\\x', '\\\\x'), ''), ',"default":"', COALESCE(replace(replace(cols.column_default, '"', '\\"'), '\\x', '\\\\x'), ''),
'","collation":"', coalesce(cols.COLLATION_NAME, ''), '"}')), ',') as cols_metadata ',"collation":"', COALESCE(cols.COLLATION_NAME, ''), '"}')), ',') AS cols_metadata
from information_schema.columns cols FROM information_schema.columns cols
where cols.table_schema not in ('information_schema', 'pg_catalog') WHERE cols.table_schema NOT IN ('information_schema', 'pg_catalog')${
and cols.table_schema !~ '^(timescaledb_|_timescaledb_)' databaseOption === 'timescale'
and cols.table_name !~ '^(pg_stat_)' ? timescaleTableFilter
), indexes_metadata as ( : databaseOption === 'supabase'
select array_to_string(array_agg(CONCAT('{"schema":"', schema_name, ? supabaseTableFilter
: ''
}
), indexes_metadata AS (
SELECT array_to_string(array_agg(CONCAT('{"schema":"', schema_name,
'","table":"', table_name, '","table":"', table_name,
'","name":"', index_name, '","name":"', index_name,
'","column":"', replace(col_name :: text, '"', E'"'), '","column":"', replace(col_name :: TEXT, '"', E'"'),
'","index_type":"', index_type, '","index_type":"', index_type,
'","cardinality":', cardinality, '","cardinality":', cardinality,
',"size":', index_size, ',"size":', index_size,
',"unique":', is_unique, ',"unique":', is_unique,
',"is_partial_index":', is_partial_index, ',"is_partial_index":', is_partial_index,
',"direction":"', lower(direction), ',"direction":"', LOWER(direction),
'"}')), ',') as indexes_metadata '"}')), ',') AS indexes_metadata
from indexes_cols x FROM indexes_cols x ${
where schema_name !~ '^(timescaledb_|_timescaledb_)' databaseOption === 'timescale'
), tbls as ( ? timescaleIndexesFilter
select array_to_string(array_agg(CONCAT('{', '"schema":"', TABLE_SCHEMA, '",', '"table":"', TABLE_NAME, '",', '"rows":', : databaseOption === 'supabase'
coalesce((select s.n_live_tup ? supabaseIndexesFilter
from pg_stat_user_tables s : ''
where tbls.TABLE_SCHEMA = s.schemaname and tbls.TABLE_NAME = s.relname), }
), tbls AS (
SELECT array_to_string(array_agg(CONCAT('{', '"schema":"', TABLE_SCHEMA, '",', '"table":"', TABLE_NAME, '",', '"rows":',
COALESCE((SELECT s.n_live_tup
FROM pg_stat_user_tables s
WHERE tbls.TABLE_SCHEMA = s.schemaname AND tbls.TABLE_NAME = s.relname),
0), ', "type":"', TABLE_TYPE, '",', '"engine":"",', '"collation":""}')), 0), ', "type":"', TABLE_TYPE, '",', '"engine":"",', '"collation":""}')),
',') as tbls_metadata ',') AS tbls_metadata
from information_schema.tables tbls FROM information_schema.tables tbls
where tbls.TABLE_SCHEMA not in ('information_schema', 'pg_catalog') WHERE tbls.TABLE_SCHEMA NOT IN ('information_schema', 'pg_catalog') ${
and tbls.TABLE_SCHEMA !~ '^(timescaledb_|_timescaledb_)' databaseOption === 'timescale'
and tbls.TABLE_NAME !~ '^(pg_stat_)' ? timescaleTableFilter
), config as ( : databaseOption === 'supabase'
select array_to_string( ? supabaseTableFilter
: ''
}
), config AS (
SELECT array_to_string(
array_agg(CONCAT('{"name":"', conf.name, '","value":"', replace(conf.setting, '"', E'"'), '"}')), array_agg(CONCAT('{"name":"', conf.name, '","value":"', replace(conf.setting, '"', E'"'), '"}')),
',') as config_metadata ',') AS config_metadata
from pg_settings conf FROM pg_settings conf
), views as ), views AS (
( SELECT array_to_string(array_agg(CONCAT('{"schema":"', views.schemaname, '","view_name":"', viewname, '"}')),
select array_to_string(array_agg(CONCAT('{"schema":"', views.schemaname, '","view_name":"', viewname, '"}')), ',') AS views_metadata
',') as views_metadata FROM pg_views views
from pg_views views WHERE views.schemaname NOT IN ('information_schema', 'pg_catalog') ${
where views.schemaname not in ('information_schema', 'pg_catalog') databaseOption === 'timescale'
and views.schemaname !~ '^(timescaledb_|_timescaledb_)' ? timescaleViewsFilter
) : databaseOption === 'supabase'
select CONCAT('{ "fk_info": [', coalesce(fk_metadata, ''), ? supabaseViewsFilter
: ''
}
)
SELECT CONCAT('{ "fk_info": [', COALESCE(fk_metadata, ''),
'], "pk_info": [', COALESCE(pk_metadata, ''), '], "pk_info": [', COALESCE(pk_metadata, ''),
'], "columns": [', coalesce(cols_metadata, ''), '], "columns": [', COALESCE(cols_metadata, ''),
'], "indexes": [', coalesce(indexes_metadata, ''), '], "indexes": [', COALESCE(indexes_metadata, ''),
'], "tables":[', coalesce(tbls_metadata, ''), '], "tables":[', COALESCE(tbls_metadata, ''),
'], "views":[', coalesce(views_metadata, ''), '], "views":[', COALESCE(views_metadata, ''),
'], "database_name": "', current_database(), '', '", "version": "', '', '], "database_name": "', CURRENT_DATABASE(), '', '", "version": "', '',
'"}') as " " '"}') AS " "
from fk_info, pk_info, cols, indexes_metadata, tbls, config, views; FROM fk_info, pk_info, cols, indexes_metadata, tbls, config, views;
`; `;
return query;
};