Skip to content

Commit bd3748b

Browse files
authored
RLS section in RawModuleDefV10. (#4149)
# Description of Changes Keep RLS in `RawModuleDefV10` for now, revisit replacing it with Views before 2.0 release. <!-- Please describe your change, mention any related tickets, and so on here. --> # API and ABI breaking changes NA # Expected complexity level and risk1 1
1 parent 65718da commit bd3748b

3 files changed

Lines changed: 52 additions & 4 deletions

File tree

crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV10Section.g.cs

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/lib/src/db/raw_def/v10.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,12 @@ pub enum RawModuleDefV10Section {
8383
/// Unlike V9 where lifecycle was a field on reducers,
8484
/// V10 stores lifecycle-to-reducer mappings separately.
8585
LifeCycleReducers(Vec<RawLifeCycleReducerDefV10>),
86-
//TODO: Add section for Event tables, and Case conversion before exposing this from module
86+
87+
RowLevelSecurity(Vec<RawRowLevelSecurityDefV10>), //TODO: Add section for Event tables, and Case conversion before exposing this from module
8788
}
8889

90+
pub type RawRowLevelSecurityDefV10 = crate::db::raw_def::v9::RawRowLevelSecurityDefV9;
91+
8992
/// The definition of a database table.
9093
///
9194
/// This struct holds information about the table, including its name, columns, indexes,
@@ -476,6 +479,14 @@ impl RawModuleDefV10 {
476479
})
477480
.expect("Tables section must exist for tests")
478481
}
482+
483+
// Get the row-level security section, if present.
484+
pub fn row_level_security(&self) -> Option<&Vec<RawRowLevelSecurityDefV10>> {
485+
self.sections.iter().find_map(|s| match s {
486+
RawModuleDefV10Section::RowLevelSecurity(rls) => Some(rls),
487+
_ => None,
488+
})
489+
}
479490
}
480491

481492
/// A builder for a [`RawModuleDefV10`].
@@ -633,6 +644,26 @@ impl RawModuleDefV10Builder {
633644
TypespaceBuilder::add_type::<T>(self)
634645
}
635646

647+
/// Get mutable access to the row-level security section, creating it if missing.
648+
fn row_level_security_mut(&mut self) -> &mut Vec<RawRowLevelSecurityDefV10> {
649+
let idx = self
650+
.module
651+
.sections
652+
.iter()
653+
.position(|s| matches!(s, RawModuleDefV10Section::RowLevelSecurity(_)))
654+
.unwrap_or_else(|| {
655+
self.module
656+
.sections
657+
.push(RawModuleDefV10Section::RowLevelSecurity(Vec::new()));
658+
self.module.sections.len() - 1
659+
});
660+
661+
match &mut self.module.sections[idx] {
662+
RawModuleDefV10Section::RowLevelSecurity(rls) => rls,
663+
_ => unreachable!("Just ensured RowLevelSecurity section exists"),
664+
}
665+
}
666+
636667
/// Create a table builder.
637668
///
638669
/// Does not validate that the product_type_ref is valid; this is left to the module validation code.
@@ -867,6 +898,16 @@ impl RawModuleDefV10Builder {
867898
});
868899
}
869900

901+
/// Add a row-level security policy to the module.
902+
///
903+
/// The `sql` expression should be a valid SQL expression that will be used to filter rows.
904+
///
905+
/// **NOTE**: The `sql` expression must be unique within the module.
906+
pub fn add_row_level_security(&mut self, sql: &str) {
907+
self.row_level_security_mut()
908+
.push(RawRowLevelSecurityDefV10 { sql: sql.into() });
909+
}
910+
870911
/// Finish building, consuming the builder and returning the module.
871912
/// The module should be validated before use.
872913
///

crates/schema/src/def/validate/v10.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::borrow::Cow;
22

3-
use spacetimedb_data_structures::map::HashCollectionExt;
43
use spacetimedb_lib::bsatn::Deserializer;
54
use spacetimedb_lib::db::raw_def::v10::*;
65
use spacetimedb_lib::de::DeserializeSeed as _;
@@ -180,6 +179,13 @@ pub fn validate(def: RawModuleDefV10) -> Result<ModuleDef> {
180179
..
181180
} = validator.core;
182181

182+
let row_level_security_raw = def
183+
.row_level_security()
184+
.into_iter()
185+
.flatten()
186+
.map(|rls| (rls.sql.clone(), rls.to_owned()))
187+
.collect();
188+
183189
let (tables, types, reducers, procedures, views) =
184190
(tables_types_reducers_procedures_views).map_err(|errors| errors.sort_deduplicate())?;
185191

@@ -194,7 +200,7 @@ pub fn validate(def: RawModuleDefV10) -> Result<ModuleDef> {
194200
typespace_for_generate,
195201
stored_in_table_def,
196202
refmap,
197-
row_level_security_raw: HashMap::new(),
203+
row_level_security_raw,
198204
lifecycle_reducers,
199205
procedures,
200206
raw_module_def_version: RawModuleDefVersion::V10,

0 commit comments

Comments
 (0)