diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 68d7371b..bd7d6c49 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -92,6 +92,10 @@ jobs: cache-base: main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup sqlx-cli + run: cargo install sqlx-cli + - name: Setup Biome uses: biomejs/setup-biome@v2 with: @@ -101,6 +105,7 @@ jobs: cargo clippy cargo run -p rules_check biome lint + cargo sqlx prepare --check --workspace test: name: Test diff --git a/.sqlx/query-1c29eca62591ae2597581be806dd572b3d79c7b8b9b7ffa8915806c947095a96.json b/.sqlx/query-1c29eca62591ae2597581be806dd572b3d79c7b8b9b7ffa8915806c947095a96.json new file mode 100644 index 00000000..fcd4901e --- /dev/null +++ b/.sqlx/query-1c29eca62591ae2597581be806dd572b3d79c7b8b9b7ffa8915806c947095a96.json @@ -0,0 +1,56 @@ +{ + "db_name": "PostgreSQL", + "query": "select\n t.oid :: int8 as \"id!\",\n t.typname as name,\n n.nspname as \"schema!\",\n format_type (t.oid, null) as \"format!\",\n coalesce(t_enums.enums, '[]') as enums,\n coalesce(t_attributes.attributes, '[]') as attributes,\n obj_description (t.oid, 'pg_type') as comment\nfrom\n pg_type t\n left join pg_namespace n on n.oid = t.typnamespace\n left join (\n select\n enumtypid,\n jsonb_agg(\n enumlabel\n order by\n enumsortorder\n ) as enums\n from\n pg_enum\n group by\n enumtypid\n ) as t_enums on t_enums.enumtypid = t.oid\n left join (\n select\n oid,\n jsonb_agg(\n jsonb_build_object('name', a.attname, 'type_id', a.atttypid :: int8)\n order by\n a.attnum asc\n ) as attributes\n from\n pg_class c\n join pg_attribute a on a.attrelid = c.oid\n where\n c.relkind = 'c'\n and not a.attisdropped\n group by\n c.oid\n ) as t_attributes on t_attributes.oid = t.typrelid\nwhere\n (\n t.typrelid = 0\n or (\n select\n c.relkind = 'c'\n from\n pg_class c\n where\n c.oid = t.typrelid\n )\n );", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id!", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Name" + }, + { + "ordinal": 2, + "name": "schema!", + "type_info": "Name" + }, + { + "ordinal": 3, + "name": "format!", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "enums", + "type_info": "Jsonb" + }, + { + "ordinal": 5, + "name": "attributes", + "type_info": "Jsonb" + }, + { + "ordinal": 6, + "name": "comment", + "type_info": "Text" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + false, + true, + null, + null, + null, + null + ] + }, + "hash": "1c29eca62591ae2597581be806dd572b3d79c7b8b9b7ffa8915806c947095a96" +} diff --git a/.sqlx/query-2a964a12383b977bbbbd6fe7298dfce00358ecbe878952e8d4915c06cc5c9e0f.json b/.sqlx/query-2a964a12383b977bbbbd6fe7298dfce00358ecbe878952e8d4915c06cc5c9e0f.json new file mode 100644 index 00000000..96439422 --- /dev/null +++ b/.sqlx/query-2a964a12383b977bbbbd6fe7298dfce00358ecbe878952e8d4915c06cc5c9e0f.json @@ -0,0 +1,80 @@ +{ + "db_name": "PostgreSQL", + "query": "select\n c.oid :: int8 as \"id!\",\n nc.nspname as schema,\n c.relname as name,\n c.relrowsecurity as rls_enabled,\n c.relforcerowsecurity as rls_forced,\n case\n when c.relreplident = 'd' then 'DEFAULT'\n when c.relreplident = 'i' then 'INDEX'\n when c.relreplident = 'f' then 'FULL'\n else 'NOTHING'\n end as \"replica_identity!\",\n pg_total_relation_size(format('%I.%I', nc.nspname, c.relname)) :: int8 as \"bytes!\",\n pg_size_pretty(\n pg_total_relation_size(format('%I.%I', nc.nspname, c.relname))\n ) as \"size!\",\n pg_stat_get_live_tuples(c.oid) as \"live_rows_estimate!\",\n pg_stat_get_dead_tuples(c.oid) as \"dead_rows_estimate!\",\n obj_description(c.oid) as comment\nfrom\n pg_namespace nc\n join pg_class c on nc.oid = c.relnamespace\nwhere\n c.relkind in ('r', 'p')\n and not pg_is_other_temp_schema(nc.oid)\n and (\n pg_has_role(c.relowner, 'USAGE')\n or has_table_privilege(\n c.oid,\n 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'\n )\n or has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')\n )\ngroup by\n c.oid,\n c.relname,\n c.relrowsecurity,\n c.relforcerowsecurity,\n c.relreplident,\n nc.nspname;", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id!", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "schema", + "type_info": "Name" + }, + { + "ordinal": 2, + "name": "name", + "type_info": "Name" + }, + { + "ordinal": 3, + "name": "rls_enabled", + "type_info": "Bool" + }, + { + "ordinal": 4, + "name": "rls_forced", + "type_info": "Bool" + }, + { + "ordinal": 5, + "name": "replica_identity!", + "type_info": "Text" + }, + { + "ordinal": 6, + "name": "bytes!", + "type_info": "Int8" + }, + { + "ordinal": 7, + "name": "size!", + "type_info": "Text" + }, + { + "ordinal": 8, + "name": "live_rows_estimate!", + "type_info": "Int8" + }, + { + "ordinal": 9, + "name": "dead_rows_estimate!", + "type_info": "Int8" + }, + { + "ordinal": 10, + "name": "comment", + "type_info": "Text" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + false, + false, + false, + false, + null, + null, + null, + null, + null, + null + ] + }, + "hash": "2a964a12383b977bbbbd6fe7298dfce00358ecbe878952e8d4915c06cc5c9e0f" +} diff --git a/.sqlx/query-36862f7f9d2d1c50ba253b28a7648e76ff7e255960a4ce5466674ff35a97b151.json b/.sqlx/query-36862f7f9d2d1c50ba253b28a7648e76ff7e255960a4ce5466674ff35a97b151.json new file mode 100644 index 00000000..6255c9b9 --- /dev/null +++ b/.sqlx/query-36862f7f9d2d1c50ba253b28a7648e76ff7e255960a4ce5466674ff35a97b151.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "select\n n.oid :: int8 as \"id!\",\n n.nspname as name,\n u.rolname as \"owner!\"\nfrom\n pg_namespace n,\n pg_roles u\nwhere\n n.nspowner = u.oid\n and (\n pg_has_role(n.nspowner, 'USAGE')\n or has_schema_privilege(n.oid, 'CREATE, USAGE')\n )\n and not pg_catalog.starts_with(n.nspname, 'pg_temp_')\n and not pg_catalog.starts_with(n.nspname, 'pg_toast_temp_');", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id!", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Name" + }, + { + "ordinal": 2, + "name": "owner!", + "type_info": "Name" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + false, + true + ] + }, + "hash": "36862f7f9d2d1c50ba253b28a7648e76ff7e255960a4ce5466674ff35a97b151" +} diff --git a/.sqlx/query-64d9718b07516f3d2720cb7aa79e496f5337cadbad7a3fb03ccd3e3c21b71389.json b/.sqlx/query-64d9718b07516f3d2720cb7aa79e496f5337cadbad7a3fb03ccd3e3c21b71389.json new file mode 100644 index 00000000..43d63459 --- /dev/null +++ b/.sqlx/query-64d9718b07516f3d2720cb7aa79e496f5337cadbad7a3fb03ccd3e3c21b71389.json @@ -0,0 +1,104 @@ +{ + "db_name": "PostgreSQL", + "query": "with functions as (\n select\n oid,\n proname,\n prosrc,\n prorettype,\n proretset,\n provolatile,\n prosecdef,\n prolang,\n pronamespace,\n proconfig,\n -- proargmodes is null when all arg modes are IN\n coalesce(\n p.proargmodes,\n array_fill(\n 'i' :: text,\n array [cardinality(coalesce(p.proallargtypes, p.proargtypes))]\n )\n ) as arg_modes,\n -- proargnames is null when all args are unnamed\n coalesce(\n p.proargnames,\n array_fill(\n '' :: text,\n array [cardinality(coalesce(p.proallargtypes, p.proargtypes))]\n )\n ) as arg_names,\n -- proallargtypes is null when all arg modes are IN\n coalesce(p.proallargtypes, p.proargtypes) as arg_types,\n array_cat(\n array_fill(false, array [pronargs - pronargdefaults]),\n array_fill(true, array [pronargdefaults])\n ) as arg_has_defaults\n from\n pg_proc as p\n where\n p.prokind = 'f'\n)\nselect\n f.oid :: int8 as \"id!\",\n n.nspname as \"schema!\",\n f.proname as \"name!\",\n l.lanname as \"language!\",\n case\n when l.lanname = 'internal' then null\n else f.prosrc\n end as body,\n case\n when l.lanname = 'internal' then null\n else pg_get_functiondef(f.oid)\n end as definition,\n coalesce(f_args.args, '[]') as args,\n nullif(pg_get_function_arguments(f.oid), '') as argument_types,\n nullif(pg_get_function_identity_arguments(f.oid), '') as identity_argument_types,\n f.prorettype :: int8 as \"return_type_id!\",\n pg_get_function_result(f.oid) as \"return_type!\",\n nullif(rt.typrelid :: int8, 0) as return_type_relation_id,\n f.proretset as is_set_returning_function,\n case\n when f.provolatile = 'i' then 'IMMUTABLE'\n when f.provolatile = 's' then 'STABLE'\n when f.provolatile = 'v' then 'VOLATILE'\n end as behavior,\n f.prosecdef as security_definer\nfrom\n functions f\n left join pg_namespace n on f.pronamespace = n.oid\n left join pg_language l on f.prolang = l.oid\n left join pg_type rt on rt.oid = f.prorettype\n left join (\n select\n oid,\n jsonb_object_agg(param, value) filter (\n where\n param is not null\n ) as config_params\n from\n (\n select\n oid,\n (string_to_array(unnest(proconfig), '=')) [1] as param,\n (string_to_array(unnest(proconfig), '=')) [2] as value\n from\n functions\n ) as t\n group by\n oid\n ) f_config on f_config.oid = f.oid\n left join (\n select\n oid,\n jsonb_agg(\n jsonb_build_object(\n 'mode',\n t2.mode,\n 'name',\n name,\n 'type_id',\n type_id,\n 'has_default',\n has_default\n )\n ) as args\n from\n (\n select\n oid,\n unnest(arg_modes) as mode,\n unnest(arg_names) as name,\n unnest(arg_types) :: int8 as type_id,\n unnest(arg_has_defaults) as has_default\n from\n functions\n ) as t1,\n lateral (\n select\n case\n when t1.mode = 'i' then 'in'\n when t1.mode = 'o' then 'out'\n when t1.mode = 'b' then 'inout'\n when t1.mode = 'v' then 'variadic'\n else 'table'\n end as mode\n ) as t2\n group by\n t1.oid\n ) f_args on f_args.oid = f.oid;", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id!", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "schema!", + "type_info": "Name" + }, + { + "ordinal": 2, + "name": "name!", + "type_info": "Name" + }, + { + "ordinal": 3, + "name": "language!", + "type_info": "Name" + }, + { + "ordinal": 4, + "name": "body", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "definition", + "type_info": "Text" + }, + { + "ordinal": 6, + "name": "args", + "type_info": "Jsonb" + }, + { + "ordinal": 7, + "name": "argument_types", + "type_info": "Text" + }, + { + "ordinal": 8, + "name": "identity_argument_types", + "type_info": "Text" + }, + { + "ordinal": 9, + "name": "return_type_id!", + "type_info": "Int8" + }, + { + "ordinal": 10, + "name": "return_type!", + "type_info": "Text" + }, + { + "ordinal": 11, + "name": "return_type_relation_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "is_set_returning_function", + "type_info": "Bool" + }, + { + "ordinal": 13, + "name": "behavior", + "type_info": "Text" + }, + { + "ordinal": 14, + "name": "security_definer", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + true, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + false, + null, + false + ] + }, + "hash": "64d9718b07516f3d2720cb7aa79e496f5337cadbad7a3fb03ccd3e3c21b71389" +} diff --git a/.sqlx/query-d61f2f56ce777c99593df240b3a126cacb3c9ed5f915b7e98052d58df98d480b.json b/.sqlx/query-d61f2f56ce777c99593df240b3a126cacb3c9ed5f915b7e98052d58df98d480b.json new file mode 100644 index 00000000..d1766e30 --- /dev/null +++ b/.sqlx/query-d61f2f56ce777c99593df240b3a126cacb3c9ed5f915b7e98052d58df98d480b.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "select\n version(),\n current_setting('server_version_num') :: int8 AS version_num,\n (\n select\n count(*) :: int8 AS active_connections\n FROM\n pg_stat_activity\n ) AS active_connections,\n current_setting('max_connections') :: int8 AS max_connections;", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "version", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "version_num", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "active_connections", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "max_connections", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + null, + null, + null + ] + }, + "hash": "d61f2f56ce777c99593df240b3a126cacb3c9ed5f915b7e98052d58df98d480b" +} diff --git a/.sqlx/query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json b/.sqlx/query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json new file mode 100644 index 00000000..01043a69 --- /dev/null +++ b/.sqlx/query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json @@ -0,0 +1,86 @@ +{ + "db_name": "PostgreSQL", + "query": "with\n available_tables as (\n select\n c.relname as table_name,\n c.oid as table_oid,\n c.relkind as class_kind,\n n.nspname as schema_name\n from\n pg_catalog.pg_class c\n join pg_catalog.pg_namespace n on n.oid = c.relnamespace\n where\n -- r: normal tables\n -- v: views\n -- m: materialized views\n -- f: foreign tables\n -- p: partitioned tables\n c.relkind in ('r', 'v', 'm', 'f', 'p')\n ),\n available_indexes as (\n select\n unnest (ix.indkey) as attnum,\n ix.indisprimary as is_primary,\n ix.indisunique as is_unique,\n ix.indrelid as table_oid\n from\n pg_catalog.pg_class c\n join pg_catalog.pg_index ix on c.oid = ix.indexrelid\n where\n c.relkind = 'i'\n )\nselect\n atts.attname as name,\n ts.table_name,\n ts.table_oid :: int8 as \"table_oid!\",\n ts.class_kind :: char as \"class_kind!\",\n ts.schema_name,\n atts.atttypid :: int8 as \"type_id!\",\n not atts.attnotnull as \"is_nullable!\",\n nullif(\n information_schema._pg_char_max_length (atts.atttypid, atts.atttypmod),\n -1\n ) as varchar_length,\n pg_get_expr (def.adbin, def.adrelid) as default_expr,\n coalesce(ix.is_primary, false) as \"is_primary_key!\",\n coalesce(ix.is_unique, false) as \"is_unique!\",\n pg_catalog.col_description (ts.table_oid, atts.attnum) as comment\nfrom\n pg_catalog.pg_attribute atts\n join available_tables ts on atts.attrelid = ts.table_oid\n left join available_indexes ix on atts.attrelid = ix.table_oid\n and atts.attnum = ix.attnum\n left join pg_catalog.pg_attrdef def on atts.attrelid = def.adrelid\n and atts.attnum = def.adnum\nwhere\n -- system columns, such as `cmax` or `tableoid`, have negative `attnum`s\n atts.attnum >= 0\norder by\n schema_name desc,\n table_name,\n atts.attnum;", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "name", + "type_info": "Name" + }, + { + "ordinal": 1, + "name": "table_name", + "type_info": "Name" + }, + { + "ordinal": 2, + "name": "table_oid!", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "class_kind!", + "type_info": "Bpchar" + }, + { + "ordinal": 4, + "name": "schema_name", + "type_info": "Name" + }, + { + "ordinal": 5, + "name": "type_id!", + "type_info": "Int8" + }, + { + "ordinal": 6, + "name": "is_nullable!", + "type_info": "Bool" + }, + { + "ordinal": 7, + "name": "varchar_length", + "type_info": "Int4" + }, + { + "ordinal": 8, + "name": "default_expr", + "type_info": "Text" + }, + { + "ordinal": 9, + "name": "is_primary_key!", + "type_info": "Bool" + }, + { + "ordinal": 10, + "name": "is_unique!", + "type_info": "Bool" + }, + { + "ordinal": 11, + "name": "comment", + "type_info": "Text" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + null, + null, + false, + null, + null, + null, + null, + null, + null, + null + ] + }, + "hash": "fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45" +}