Skip to content

Commit 15ede7f

Browse files
committed
explicit names
1 parent c461c11 commit 15ede7f

4 files changed

Lines changed: 202 additions & 79 deletions

File tree

crates/bindings-csharp/Codegen/Module.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ public static bool CanParse(AttributeData data) =>
390390
public string GenerateIndexDef() =>
391391
$$"""
392392
new(
393-
SourceName: null,
393+
SourceName: "{{Table + StandardNameSuffix}}",
394394
AccessorName: "{{AccessorName}}",
395395
Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.{{Type}}([{{string.Join(
396396
", ",

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ impl ExplicitNames {
179179
pub fn merge(&mut self, other: ExplicitNames) {
180180
self.entries.extend(other.entries);
181181
}
182+
183+
pub fn into_entries(self) -> Vec<ExplicitNameEntry> {
184+
self.entries
185+
}
182186
}
183187

184188
pub type RawRowLevelSecurityDefV10 = crate::db::raw_def::v9::RawRowLevelSecurityDefV9;
@@ -594,6 +598,13 @@ impl RawModuleDefV10 {
594598
})
595599
.unwrap_or_default()
596600
}
601+
602+
pub fn explicit_names(&self) -> Option<&ExplicitNames> {
603+
self.sections.iter().find_map(|s| match s {
604+
RawModuleDefV10Section::ExplicitNames(names) => Some(names),
605+
_ => None,
606+
})
607+
}
597608
}
598609

599610
/// A builder for a [`RawModuleDefV10`].

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

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use spacetimedb_data_structures::map::HashMap;
12
use spacetimedb_lib::bsatn::Deserializer;
23
use spacetimedb_lib::db::raw_def::v10::*;
34
use spacetimedb_lib::de::DeserializeSeed as _;
@@ -12,12 +13,54 @@ use crate::error::ValidationError;
1213
use crate::type_for_generate::ProductTypeDef;
1314
use crate::{def::validate::Result, error::TypeLocation};
1415

16+
#[derive(Default)]
17+
pub struct ExplicitNamesLookup {
18+
pub tables: HashMap<RawIdentifier, RawIdentifier>,
19+
pub functions: HashMap<RawIdentifier, RawIdentifier>,
20+
pub indexes: HashMap<RawIdentifier, RawIdentifier>,
21+
}
22+
23+
impl ExplicitNamesLookup {
24+
fn new(ex: ExplicitNames) -> Self {
25+
let mut tables = HashMap::default();
26+
let mut functions = HashMap::default();
27+
let mut indexes = HashMap::default();
28+
29+
for entry in ex.into_entries() {
30+
match entry {
31+
ExplicitNameEntry::Table(m) => {
32+
tables.insert(m.source_name, m.canonical_name);
33+
}
34+
ExplicitNameEntry::Function(m) => {
35+
functions.insert(m.source_name, m.canonical_name);
36+
}
37+
ExplicitNameEntry::Index(m) => {
38+
indexes.insert(m.source_name, m.canonical_name);
39+
}
40+
_ => {}
41+
}
42+
}
43+
44+
ExplicitNamesLookup {
45+
tables,
46+
functions,
47+
indexes,
48+
}
49+
}
50+
}
51+
1552
/// Validate a `RawModuleDefV9` and convert it into a `ModuleDef`,
1653
/// or return a stream of errors if the definition is invalid.
1754
pub fn validate(def: RawModuleDefV10) -> Result<ModuleDef> {
1855
let mut typespace = def.typespace().cloned().unwrap_or_else(|| Typespace::EMPTY.clone());
1956
let known_type_definitions = def.types().into_iter().flatten().map(|def| def.ty);
2057
let case_policy = def.case_conversion_policy();
58+
let explicit_names = def
59+
.explicit_names()
60+
.cloned()
61+
.map(ExplicitNamesLookup::new)
62+
.unwrap_or_default();
63+
2164
CoreValidator::typespace_case_conversion(case_policy, &mut typespace);
2265

2366
let mut validator = ModuleValidatorV10 {
@@ -28,6 +71,7 @@ pub fn validate(def: RawModuleDefV10) -> Result<ModuleDef> {
2871
lifecycle_reducers: Default::default(),
2972
typespace_for_generate: TypespaceForGenerate::builder(&typespace, known_type_definitions),
3073
case_policy,
74+
explicit_names,
3175
},
3276
};
3377

@@ -130,7 +174,7 @@ pub fn validate(def: RawModuleDefV10) -> Result<ModuleDef> {
130174
let function_name = ReducerName::new(
131175
validator
132176
.core
133-
.identifier_with_case(lifecycle_def.function_name.clone())?,
177+
.resolve_function_ident(lifecycle_def.function_name.clone())?,
134178
);
135179

136180
let (pos, _) = reducers_vec
@@ -349,16 +393,20 @@ impl<'a> ModuleValidatorV10<'a> {
349393
})
350394
.collect_all_errors();
351395

352-
let name = table_validator
353-
.add_to_global_namespace(raw_table_name.clone())
354-
.and_then(|name| {
355-
let name = self.core.identifier_with_case(name)?;
356-
if table_type != TableType::System && name.starts_with("st_") {
357-
Err(ValidationError::TableNameReserved { table: name }.into())
358-
} else {
359-
Ok(name)
360-
}
361-
});
396+
// `raw_table_name` should also go in global namespace as it will be used as alias
397+
let raw_table_name = table_validator.add_to_global_namespace(raw_table_name.clone())?;
398+
399+
let name = {
400+
let name = table_validator
401+
.module_validator
402+
.resolve_table_ident(raw_table_name.clone())?;
403+
if table_type != TableType::System && name.starts_with("st_") {
404+
Err(ValidationError::TableNameReserved { table: name }.into())
405+
} else {
406+
let name = table_validator.add_to_global_namespace(name.as_raw().clone())?;
407+
Ok(name)
408+
}
409+
};
362410

363411
// Validate default values inline and attach them to columns
364412
let validated_defaults: Result<HashMap<ColId, AlgebraicValue>> = default_values
@@ -406,7 +454,7 @@ impl<'a> ModuleValidatorV10<'a> {
406454
.combine_errors()?;
407455

408456
Ok(TableDef {
409-
name,
457+
name: identifier(name)?,
410458
product_type_ref,
411459
primary_key,
412460
columns,
@@ -438,7 +486,7 @@ impl<'a> ModuleValidatorV10<'a> {
438486
arg_name,
439487
});
440488

441-
let name_result = self.core.identifier_with_case(source_name.clone());
489+
let name_result = self.core.resolve_function_ident(source_name.clone());
442490

443491
let return_res: Result<_> = (ok_return_type.is_unit() && err_return_type.is_string())
444492
.then_some((ok_return_type.clone(), err_return_type.clone()))
@@ -482,7 +530,7 @@ impl<'a> ModuleValidatorV10<'a> {
482530
function_name,
483531
} = schedule;
484532

485-
let table_ident = self.core.identifier_with_case(table_name.clone())?;
533+
let table_ident = self.core.resolve_table_ident(table_name.clone())?;
486534

487535
// Look up the table to validate the schedule
488536
let table = tables.get(&table_ident).ok_or_else(|| ValidationError::TableNotFound {
@@ -499,11 +547,11 @@ impl<'a> ModuleValidatorV10<'a> {
499547
ref_: table.product_type_ref,
500548
})?;
501549

502-
let source_name = source_name.unwrap_or_else(|| generate_schedule_name(&table_name));
550+
let source_name = generate_schedule_name(&table_ident);
503551
self.core
504552
.validate_schedule_def(
505553
table_name.clone(),
506-
self.core.identifier_with_case(source_name)?,
554+
source_name,
507555
function_name,
508556
product_type,
509557
schedule_at_col,
@@ -549,7 +597,7 @@ impl<'a> ModuleValidatorV10<'a> {
549597
&return_type,
550598
);
551599

552-
let name_result = self.core.identifier_with_case(source_name);
600+
let name_result = self.core.resolve_function_ident(source_name);
553601

554602
let (name_result, params_for_generate, return_type_for_generate) =
555603
(name_result, params_for_generate, return_type_for_generate).combine_errors()?;
@@ -623,6 +671,8 @@ impl<'a> ModuleValidatorV10<'a> {
623671
&return_type,
624672
);
625673

674+
let name_result = self.core.resolve_function_ident(accessor_name.clone());
675+
626676
let mut view_validator = ViewValidator::new(
627677
accessor_name.clone(),
628678
product_type_ref,
@@ -632,7 +682,7 @@ impl<'a> ModuleValidatorV10<'a> {
632682
&mut self.core,
633683
)?;
634684

635-
let name_result = view_validator.add_to_global_namespace(accessor_name);
685+
let name_result = view_validator.add_to_global_namespace(name_result?.as_raw().clone());
636686

637687
let n = product_type.elements.len();
638688
let return_columns = (0..n)
@@ -648,8 +698,8 @@ impl<'a> ModuleValidatorV10<'a> {
648698
(name_result, return_type_for_generate, return_columns, param_columns).combine_errors()?;
649699

650700
Ok(ViewDef {
651-
name: self.core.identifier_with_case(name_result.clone())?,
652-
accessor_name: identifier(name_result)?,
701+
name: self.core.resolve_function_ident(name_result.clone())?,
702+
accessor_name: identifier(accessor_name)?,
653703
is_anonymous,
654704
is_public,
655705
params,

0 commit comments

Comments
 (0)