Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions crates/bindings-csharp/Codegen/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -997,10 +997,7 @@ public string GenerateViewDef(uint Index) =>
IsPublic: {{{IsPublic.ToString().ToLower()}}},
IsAnonymous: {{{IsAnonymous.ToString().ToLower()}}},
Params: [{{{MemberDeclaration.GenerateDefs(Parameters)}}}],
ReturnType: new {{{ReturnType.BSATNName.Replace(
"Module.",
"global::Module."
)}}}().GetAlgebraicType(registrar)
ReturnType: new {{{ReturnType.BSATNName}}}().GetAlgebraicType(registrar)
);
""";

Expand Down
8 changes: 4 additions & 4 deletions crates/codegen/src/csharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use std::ops::Deref;
use super::code_indenter::CodeIndenter;
use super::Lang;
use crate::util::{
collect_case, is_reducer_invokable, iter_indexes, iter_reducers, iter_tables, print_auto_generated_file_comment,
print_auto_generated_version_comment, type_ref_name,
collect_case, is_reducer_invokable, iter_indexes, iter_reducers, iter_table_names_and_types,
print_auto_generated_file_comment, print_auto_generated_version_comment, type_ref_name,
};
use crate::{indent_scope, OutputFile};
use convert_case::{Case, Casing};
Expand Down Expand Up @@ -745,11 +745,11 @@ impl Lang for Csharp<'_> {
indented_block(&mut output, |output| {
writeln!(output, "public RemoteTables(DbConnection conn)");
indented_block(output, |output| {
for table in iter_tables(module) {
for (table_name, _) in iter_table_names_and_types(module) {
writeln!(
output,
"AddTable({} = new(conn));",
table.name.deref().to_case(Case::Pascal)
table_name.deref().to_case(Case::Pascal)
);
}
});
Expand Down
74 changes: 41 additions & 33 deletions crates/codegen/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use super::code_indenter::{CodeIndenter, Indenter};
use super::util::{collect_case, iter_reducers, print_lines, type_ref_name};
use super::Lang;
use crate::util::{
iter_procedures, iter_tables, iter_types, iter_unique_cols, print_auto_generated_file_comment,
print_auto_generated_version_comment,
iter_procedures, iter_table_names_and_types, iter_tables, iter_types, iter_unique_cols, iter_views,
print_auto_generated_file_comment, print_auto_generated_version_comment,
};
use crate::OutputFile;
use convert_case::{Case, Casing};
Expand Down Expand Up @@ -930,12 +930,13 @@ fn reducer_flags_trait_name(reducer: &ReducerDef) -> String {
format!("set_flags_for_{}", reducer_function_name(reducer))
}

/// Iterate over all of the Rust `mod`s for types, reducers and tables in the `module`.
/// Iterate over all of the Rust `mod`s for types, reducers, views, and tables in the `module`.
fn iter_module_names(module: &ModuleDef) -> impl Iterator<Item = String> + '_ {
itertools::chain!(
iter_types(module).map(|ty| type_module_name(&ty.name)),
iter_reducers(module).map(|r| reducer_module_name(&r.name)),
iter_tables(module).map(|tbl| table_module_name(&tbl.name)),
iter_views(module).map(|view| table_module_name(&view.name)),
iter_procedures(module).map(|proc| procedure_module_name(&proc.name)),
)
}
Expand All @@ -954,8 +955,8 @@ fn print_module_reexports(module: &ModuleDef, out: &mut Indenter) {
let type_name = collect_case(Case::Pascal, ty.name.name_segments());
writeln!(out, "pub use {mod_name}::{type_name};")
}
for table in iter_tables(module) {
let mod_name = table_module_name(&table.name);
for (table_name, _) in iter_table_names_and_types(module) {
let mod_name = table_module_name(table_name);
// TODO: More precise reexport: we want:
// - The trait name.
// - The insert, delete and possibly update callback ids.
Expand Down Expand Up @@ -1113,12 +1114,12 @@ fn print_db_update_defn(module: &ModuleDef, out: &mut Indenter) {
out.delimited_block(
"pub struct DbUpdate {",
|out| {
for table in iter_tables(module) {
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
writeln!(
out,
"{}: __sdk::TableUpdate<{}>,",
table_method_name(&table.name),
type_ref_name(module, table.product_type_ref),
table_method_name(table_name),
type_ref_name(module, product_type_ref),
);
}
},
Expand All @@ -1137,13 +1138,13 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate {
match &table_update.table_name[..] {
",
|out| {
for table in iter_tables(module) {
for (table_name, _) in iter_table_names_and_types(module) {
writeln!(
out,
"{:?} => db_update.{}.append({}::parse_table_update(table_update)?),",
table.name.deref(),
table_method_name(&table.name),
table_module_name(&table.name),
table_name.deref(),
table_method_name(table_name),
table_module_name(table_name),
);
}
},
Expand Down Expand Up @@ -1181,21 +1182,28 @@ impl __sdk::InModule for DbUpdate {{
let mut diff = AppliedDiff::default();
",
|out| {
for table in iter_tables(module) {
let with_updates = table
.primary_key
.map(|col| {
let pk_field = table.get_column(col).unwrap().name.deref().to_case(Case::Snake);
format!(".with_updates_by_pk(|row| &row.{pk_field})")
})
.unwrap_or_default();

let field_name = table_method_name(&table.name);
for (table_name, product_type_ref, with_updates) in itertools::chain!(
iter_tables(module).map(|table| {
(
&table.name,
table.product_type_ref,
table
.primary_key
.map(|col| {
let pk_field = table.get_column(col).unwrap().name.deref().to_case(Case::Snake);
format!(".with_updates_by_pk(|row| &row.{pk_field})")
})
.unwrap_or_default(),
)
}),
iter_views(module).map(|view| (&view.name, view.product_type_ref, "".into()))
) {
let field_name = table_method_name(table_name);
writeln!(
out,
"diff.{field_name} = cache.apply_diff_to_table::<{}>({:?}, &self.{field_name}){with_updates};",
type_ref_name(module, table.product_type_ref),
table.name.deref(),
type_ref_name(module, product_type_ref),
table_name.deref(),
);
}
},
Expand All @@ -1215,12 +1223,12 @@ fn print_applied_diff_defn(module: &ModuleDef, out: &mut Indenter) {
out.delimited_block(
"pub struct AppliedDiff<'r> {",
|out| {
for table in iter_tables(module) {
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
writeln!(
out,
"{}: __sdk::TableAppliedDiff<'r, {}>,",
table_method_name(&table.name),
type_ref_name(module, table.product_type_ref),
table_method_name(table_name),
type_ref_name(module, product_type_ref),
);
}
// Also write a `PhantomData` field which uses the lifetime `r`,
Expand Down Expand Up @@ -1248,13 +1256,13 @@ impl __sdk::InModule for AppliedDiff<'_> {{
out.delimited_block(
"fn invoke_row_callbacks(&self, event: &EventContext, callbacks: &mut __sdk::DbCallbacks<RemoteModule>) {",
|out| {
for table in iter_tables(module) {
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
writeln!(
out,
"callbacks.invoke_table_row_callbacks::<{}>({:?}, &self.{}, event);",
type_ref_name(module, table.product_type_ref),
table.name.deref(),
table_method_name(&table.name),
type_ref_name(module, product_type_ref),
table_name.deref(),
table_method_name(table_name),
);
}
},
Expand Down Expand Up @@ -1290,8 +1298,8 @@ type SubscriptionHandle = SubscriptionHandle;
out.delimited_block(
"fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {",
|out| {
for table in iter_tables(module) {
writeln!(out, "{}::register_table(client_cache);", table_module_name(&table.name));
for (table_name, _) in iter_table_names_and_types(module) {
writeln!(out, "{}::register_table(client_cache);", table_module_name(table_name));
}
},
"}\n",
Expand Down
45 changes: 30 additions & 15 deletions crates/codegen/src/typescript.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::util::{
is_reducer_invokable, iter_reducers, iter_tables, iter_types, iter_unique_cols,
print_auto_generated_version_comment,
is_reducer_invokable, iter_reducers, iter_table_names_and_types, iter_tables, iter_types, iter_unique_cols,
iter_views, print_auto_generated_version_comment,
};
use crate::{indent_scope, OutputFile};

Expand Down Expand Up @@ -341,10 +341,9 @@ removeOnUpdate = (cb: (ctx: EventContext, onRow: {row_type}, newRow: {row_type})

writeln!(out);
writeln!(out, "// Import and reexport all table handle types");
for table in iter_tables(module) {
let table_name = &table.name;
for (table_name, _) in iter_table_names_and_types(module) {
let table_module_name = table_module_name(table_name) + ".ts";
let table_name_pascalcase = table.name.deref().to_case(Case::Pascal);
let table_name_pascalcase = table_name.deref().to_case(Case::Pascal);
let table_handle = table_name_pascalcase.clone() + "TableHandle";
writeln!(out, "import {{ {table_handle} }} from \"./{table_module_name}\";");
writeln!(out, "export {{ {table_handle} }};");
Expand All @@ -366,15 +365,31 @@ removeOnUpdate = (cb: (ctx: EventContext, onRow: {row_type}, newRow: {row_type})
out.indent(1);
writeln!(out, "tables: {{");
out.indent(1);
for table in iter_tables(module) {
let type_ref = table.product_type_ref;
for (table_name, product_type_ref, schema) in itertools::chain!(
iter_tables(module).map(|def| {
(
&def.name,
def.product_type_ref,
TableSchema::from_module_def(module, def, (), 0.into()),
)
}),
iter_views(module).map(|def| {
(
&def.name,
def.product_type_ref,
TableSchema::from_view_def_for_codegen(module, def),
)
})
) {
let table_name = table_name.deref();
let type_ref = product_type_ref;
let row_type = type_ref_name(module, type_ref);
let schema = TableSchema::from_module_def(module, table, (), 0.into())
let schema = schema
.validated()
.expect("Failed to generate table due to validation errors");
writeln!(out, "{}: {{", table.name);
writeln!(out, "{}: {{", table_name);
out.indent(1);
writeln!(out, "tableName: \"{}\" as const,", table.name);
writeln!(out, "tableName: \"{}\" as const,", table_name);
writeln!(out, "rowType: {row_type}.getTypeScriptAlgebraicType(),");
if let Some(pk) = schema.pk() {
// This is left here so we can release the codegen change before releasing a new
Expand Down Expand Up @@ -612,13 +627,13 @@ fn print_remote_tables(module: &ModuleDef, out: &mut Indenter) {
out.indent(1);
writeln!(out, "constructor(private connection: __DbConnectionImpl) {{}}");

for table in iter_tables(module) {
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
writeln!(out);
let table_name = table.name.deref();
let table_name_pascalcase = table.name.deref().to_case(Case::Pascal);
let table_name_camelcase = table.name.deref().to_case(Case::Camel);
let table_name = table_name.deref();
let table_name_pascalcase = table_name.to_case(Case::Pascal);
let table_name_camelcase = table_name.to_case(Case::Camel);
let table_handle = table_name_pascalcase.clone() + "TableHandle";
let type_ref = table.product_type_ref;
let type_ref = product_type_ref;
let row_type = type_ref_name(module, type_ref);
writeln!(out, "get {table_name_camelcase}(): {table_handle}<'{table_name}'> {{");
out.with_indent(|out| {
Expand Down
44 changes: 21 additions & 23 deletions crates/codegen/src/unrealcpp.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Autogenerated Unreal‑C++ code‑gen backend for SpacetimeDB CLI
use crate::code_indenter::CodeIndenter;
use crate::util::{
collect_case, fmt_fn, iter_tables, print_auto_generated_file_comment, print_auto_generated_version_comment,
collect_case, fmt_fn, iter_table_names_and_types, print_auto_generated_file_comment,
print_auto_generated_version_comment,
};
use crate::util::{iter_indexes, iter_reducers};
use crate::Lang;
Expand Down Expand Up @@ -683,8 +684,8 @@ impl Lang for UnrealCpp<'_> {
writeln!(client_h);

writeln!(client_h, "/** Forward declaration for tables */");
for table in iter_tables(module) {
let table_pascal = type_ref_name(module, table.product_type_ref);
for (_, product_type_ref) in iter_table_names_and_types(module) {
let table_pascal = type_ref_name(module, product_type_ref);
writeln!(client_h, "class U{table_pascal}Table;");
}
writeln!(client_h, "/***/");
Expand Down Expand Up @@ -774,12 +775,11 @@ impl Lang for UnrealCpp<'_> {
});

// Build table includes
let table_includes: Vec<String> = module
.tables()
.map(|table| {
let table_includes: Vec<String> = iter_table_names_and_types(module)
.map(|(_, product_type_ref)| {
format!(
"ModuleBindings/Tables/{}Table.g.h",
type_ref_name(module, table.product_type_ref)
type_ref_name(module, product_type_ref)
)
})
.collect();
Expand Down Expand Up @@ -1856,14 +1856,14 @@ fn generate_remote_tables_class(output: &mut UnrealCppAutogen, module: &ModuleDe
writeln!(output);

// Generate table handle properties
for table in module.tables() {
let table_pascal = type_ref_name(module, table.product_type_ref);
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
let table_pascal = type_ref_name(module, product_type_ref);

writeln!(output, " UPROPERTY(BlueprintReadOnly, Category=\"SpacetimeDB\")");
writeln!(
output,
" U{table_pascal}Table* {};",
table.name.deref().to_case(Case::Pascal)
table_name.deref().to_case(Case::Pascal)
);
writeln!(output);
}
Expand Down Expand Up @@ -2357,16 +2357,16 @@ fn generate_client_implementation(output: &mut UnrealCppAutogen, module: &Module
writeln!(output, "\tReducers->SetCallReducerFlags = SetReducerFlags;");
writeln!(output, "\tReducers->Conn = this;");
writeln!(output);
for table in module.tables() {
let table_pascal = type_ref_name(module, table.product_type_ref);
let table_name = table.name.deref();
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
let table_pascal = type_ref_name(module, product_type_ref);
let table_name = table_name.deref();
writeln!(
output,
"\tRegisterTable<F{}Type, U{}Table, FEventContext>(TEXT(\"{}\"), Db->{});",
table_pascal,
table_pascal,
table_name,
table.name.deref().to_case(Case::Pascal)
table_name.to_case(Case::Pascal)
);
}
writeln!(output, "}}");
Expand Down Expand Up @@ -2412,23 +2412,23 @@ fn generate_client_implementation(output: &mut UnrealCppAutogen, module: &Module
writeln!(output, "{{");
writeln!(output);
writeln!(output, "\t/** Creating tables */");
for table in module.tables() {
let table_pascal = type_ref_name(module, table.product_type_ref);
for (table_name, product_type_ref) in iter_table_names_and_types(module) {
let table_pascal = type_ref_name(module, product_type_ref);
writeln!(
output,
"\t{} = NewObject<U{}Table>(this);",
table.name.deref().to_case(Case::Pascal),
table_name.deref().to_case(Case::Pascal),
table_pascal
);
}
writeln!(output, "\t/**/");
writeln!(output);
writeln!(output, "\t/** Initialization */");
for table in module.tables() {
for (table_name, _) in iter_table_names_and_types(module) {
writeln!(
output,
"\t{}->PostInitialize();",
table.name.deref().to_case(Case::Pascal)
table_name.deref().to_case(Case::Pascal)
);
}
writeln!(output, "\t/**/");
Expand Down Expand Up @@ -3095,10 +3095,8 @@ fn collect_optional_types(module: &ModuleDef) -> HashSet<String> {
}

// Collect from all tables
for table in module.tables() {
let product_type = module.typespace_for_generate()[table.product_type_ref]
.as_product()
.unwrap();
for (_, product_type_ref) in iter_table_names_and_types(module) {
let product_type = module.typespace_for_generate()[product_type_ref].as_product().unwrap();
for (_, field_ty) in &product_type.elements {
collect_from_type(module, field_ty, &mut optional_types);
}
Expand Down
Loading
Loading