Skip to content

Commit 74f913e

Browse files
chore(schema_cache): add query for roles (#404)
1 parent 2f08a67 commit 74f913e

File tree

5 files changed

+143
-2
lines changed

5 files changed

+143
-2
lines changed

.sqlx/query-5e12c1d242ea9fcc68c20807b72300a7e131d2fb17fc74bd7f40a60b68df56c0.json

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/pgt_schema_cache/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
mod columns;
66
mod functions;
77
mod policies;
8+
mod roles;
89
mod schema_cache;
910
mod schemas;
1011
mod tables;
@@ -15,6 +16,7 @@ mod versions;
1516
pub use columns::*;
1617
pub use functions::{Behavior, Function, FunctionArg, FunctionArgs};
1718
pub use policies::{Policy, PolicyCommand};
19+
pub use roles::*;
1820
pub use schema_cache::SchemaCache;
1921
pub use schemas::Schema;
2022
pub use tables::{ReplicaIdentity, Table};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
select
2+
rolname as "name!",
3+
rolsuper as "is_super_user!",
4+
rolcreatedb as "can_create_db!",
5+
rolcanlogin as "can_login!",
6+
rolbypassrls as "can_bypass_rls!"
7+
from pg_catalog.pg_roles;

crates/pgt_schema_cache/src/roles.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use crate::schema_cache::SchemaCacheItem;
2+
3+
#[derive(Debug, PartialEq, Eq)]
4+
pub struct Role {
5+
pub name: String,
6+
pub is_super_user: bool,
7+
pub can_create_db: bool,
8+
pub can_login: bool,
9+
pub can_bypass_rls: bool,
10+
}
11+
12+
impl SchemaCacheItem for Role {
13+
type Item = Role;
14+
15+
async fn load(pool: &sqlx::PgPool) -> Result<Vec<Self::Item>, sqlx::Error> {
16+
sqlx::query_file_as!(Role, "src/queries/roles.sql")
17+
.fetch_all(pool)
18+
.await
19+
}
20+
}
21+
22+
#[cfg(test)]
23+
mod tests {
24+
use crate::SchemaCache;
25+
use pgt_test_utils::test_database::get_new_test_db;
26+
use sqlx::Executor;
27+
28+
#[tokio::test]
29+
async fn loads_roles() {
30+
let test_db = get_new_test_db().await;
31+
32+
let setup = r#"
33+
do $$
34+
begin
35+
if not exists (
36+
select from pg_catalog.pg_roles
37+
where rolname = 'test_super'
38+
) then
39+
create role test_super superuser createdb login bypassrls;
40+
end if;
41+
if not exists (
42+
select from pg_catalog.pg_roles
43+
where rolname = 'test_nologin'
44+
) then
45+
create role test_nologin;
46+
end if;
47+
if not exists (
48+
select from pg_catalog.pg_roles
49+
where rolname = 'test_login'
50+
) then
51+
create role test_login login;
52+
end if;
53+
end $$;
54+
"#;
55+
56+
test_db
57+
.execute(setup)
58+
.await
59+
.expect("Failed to setup test database");
60+
61+
let cache = SchemaCache::load(&test_db)
62+
.await
63+
.expect("Failed to load Schema Cache");
64+
65+
let roles = &cache.roles;
66+
67+
let super_role = roles.iter().find(|r| r.name == "test_super").unwrap();
68+
assert!(super_role.is_super_user);
69+
assert!(super_role.can_create_db);
70+
assert!(super_role.can_login);
71+
assert!(super_role.can_bypass_rls);
72+
73+
let nologin_role = roles.iter().find(|r| r.name == "test_nologin").unwrap();
74+
assert!(!nologin_role.is_super_user);
75+
assert!(!nologin_role.can_create_db);
76+
assert!(!nologin_role.can_login);
77+
assert!(!nologin_role.can_bypass_rls);
78+
79+
let login_role = roles.iter().find(|r| r.name == "test_login").unwrap();
80+
assert!(!login_role.is_super_user);
81+
assert!(!login_role.can_create_db);
82+
assert!(login_role.can_login);
83+
assert!(!login_role.can_bypass_rls);
84+
}
85+
}

crates/pgt_schema_cache/src/schema_cache.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use sqlx::postgres::PgPool;
22

3-
use crate::Trigger;
43
use crate::columns::Column;
54
use crate::functions::Function;
65
use crate::policies::Policy;
76
use crate::schemas::Schema;
87
use crate::tables::Table;
98
use crate::types::PostgresType;
109
use crate::versions::Version;
10+
use crate::{Role, Trigger};
1111

1212
#[derive(Debug, Default)]
1313
pub struct SchemaCache {
@@ -19,11 +19,12 @@ pub struct SchemaCache {
1919
pub columns: Vec<Column>,
2020
pub policies: Vec<Policy>,
2121
pub triggers: Vec<Trigger>,
22+
pub roles: Vec<Role>,
2223
}
2324

2425
impl SchemaCache {
2526
pub async fn load(pool: &PgPool) -> Result<SchemaCache, sqlx::Error> {
26-
let (schemas, tables, functions, types, versions, columns, policies, triggers) = futures_util::try_join!(
27+
let (schemas, tables, functions, types, versions, columns, policies, triggers, roles) = futures_util::try_join!(
2728
Schema::load(pool),
2829
Table::load(pool),
2930
Function::load(pool),
@@ -32,6 +33,7 @@ impl SchemaCache {
3233
Column::load(pool),
3334
Policy::load(pool),
3435
Trigger::load(pool),
36+
Role::load(pool)
3537
)?;
3638

3739
Ok(SchemaCache {
@@ -43,6 +45,7 @@ impl SchemaCache {
4345
columns,
4446
policies,
4547
triggers,
48+
roles,
4649
})
4750
}
4851

0 commit comments

Comments
 (0)