Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 2 additions & 5 deletions crates/codegen/src/csharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use convert_case::{Case, Casing};
use spacetimedb_lib::sats::layout::PrimitiveType;
use spacetimedb_primitives::ColId;
use spacetimedb_schema::def::{BTreeAlgorithm, IndexAlgorithm, ModuleDef, TableDef, TypeDef};
use spacetimedb_schema::schema::{Schema, TableSchema};
use spacetimedb_schema::schema::TableSchema;
use spacetimedb_schema::type_for_generate::{
AlgebraicTypeDef, AlgebraicTypeUse, PlainEnumTypeDef, ProductTypeDef, SumTypeDef, TypespaceForGenerate,
};
Expand Down Expand Up @@ -433,7 +433,7 @@ pub struct Csharp<'opts> {
}

impl Lang for Csharp<'_> {
fn generate_table_file(&self, module: &ModuleDef, table: &TableDef) -> OutputFile {
fn generate_table_file_from_schema(&self, module: &ModuleDef, table: &TableDef, schema: TableSchema) -> OutputFile {
let mut output = CsharpAutogen::new(
self.namespace,
&[
Expand All @@ -447,9 +447,6 @@ impl Lang for Csharp<'_> {

writeln!(output, "public sealed partial class RemoteTables");
indented_block(&mut output, |output| {
let schema = TableSchema::from_module_def(module, table, (), 0.into())
.validated()
.expect("Failed to generate table due to validation errors");
let csharp_table_name = table.name.deref().to_case(Case::Pascal);
let csharp_table_class_name = csharp_table_name.clone() + "Handle";
let table_type = type_ref_name(module, table.product_type_ref);
Expand Down
21 changes: 19 additions & 2 deletions crates/codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use spacetimedb_schema::def::{ModuleDef, ReducerDef, TableDef, TypeDef};
use spacetimedb_schema::def::{ModuleDef, ReducerDef, TableDef, TypeDef, ViewDef};
use spacetimedb_schema::schema::{Schema, TableSchema};

mod code_indenter;
pub mod csharp;
Expand All @@ -16,6 +17,7 @@ pub use util::AUTO_GENERATED_PREFIX;
pub fn generate(module: &ModuleDef, lang: &dyn Lang) -> Vec<OutputFile> {
itertools::chain!(
module.tables().map(|tbl| lang.generate_table_file(module, tbl)),
module.views().map(|view| lang.generate_view_file(module, view)),
module.types().flat_map(|typ| lang.generate_type_files(module, typ)),
util::iter_reducers(module).map(|reducer| lang.generate_reducer_file(module, reducer)),
lang.generate_global_files(module),
Expand All @@ -29,8 +31,23 @@ pub struct OutputFile {
}

pub trait Lang {
fn generate_table_file(&self, module: &ModuleDef, tbl: &TableDef) -> OutputFile;
fn generate_table_file_from_schema(&self, module: &ModuleDef, tbl: &TableDef, schema: TableSchema) -> OutputFile;
fn generate_type_files(&self, module: &ModuleDef, typ: &TypeDef) -> Vec<OutputFile>;
fn generate_reducer_file(&self, module: &ModuleDef, reducer: &ReducerDef) -> OutputFile;
fn generate_global_files(&self, module: &ModuleDef) -> Vec<OutputFile>;

fn generate_table_file(&self, module: &ModuleDef, tbl: &TableDef) -> OutputFile {
let schema = TableSchema::from_module_def(module, tbl, (), 0.into())
.validated()
.expect("Failed to generate table due to validation errors");
self.generate_table_file_from_schema(module, tbl, schema)
}

fn generate_view_file(&self, module: &ModuleDef, view: &ViewDef) -> OutputFile {
let tbl = TableDef::from(view.clone());
let schema = TableSchema::from_view_def_for_codegen(module, view)
.validated()
.expect("Failed to generate table due to validation errors");
self.generate_table_file_from_schema(module, &tbl, schema)
}
}
10 changes: 3 additions & 7 deletions crates/codegen/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use spacetimedb_lib::sats::layout::PrimitiveType;
use spacetimedb_lib::sats::AlgebraicTypeRef;
use spacetimedb_schema::def::{ModuleDef, ReducerDef, ScopedTypeName, TableDef, TypeDef};
use spacetimedb_schema::identifier::Identifier;
use spacetimedb_schema::schema::{Schema, TableSchema};
use spacetimedb_schema::schema::TableSchema;
use spacetimedb_schema::type_for_generate::{AlgebraicTypeDef, AlgebraicTypeUse};
use std::collections::BTreeSet;
use std::fmt::{self, Write};
Expand Down Expand Up @@ -70,11 +70,7 @@ impl __sdk::InModule for {type_name} {{
code: output.into_inner(),
}]
}
fn generate_table_file(&self, module: &ModuleDef, table: &TableDef) -> OutputFile {
let schema = TableSchema::from_module_def(module, table, (), 0.into())
.validated()
.expect("Failed to generate table due to validation errors");

fn generate_table_file_from_schema(&self, module: &ModuleDef, table: &TableDef, schema: TableSchema) -> OutputFile {
let type_ref = table.product_type_ref;

let mut output = CodeIndenter::new(String::new(), INDENT);
Expand Down Expand Up @@ -200,7 +196,7 @@ pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::Remote
"}",
);

if schema.pk().is_some() {
if table.primary_key.is_some() {
let update_callback_id = table_name_pascalcase.clone() + "UpdateCallbackId";
write!(
out,
Expand Down
6 changes: 1 addition & 5 deletions crates/codegen/src/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,7 @@ impl Lang for TypeScript {
}
}

fn generate_table_file(&self, module: &ModuleDef, table: &TableDef) -> OutputFile {
let schema = TableSchema::from_module_def(module, table, (), 0.into())
.validated()
.expect("Failed to generate table due to validation errors");

fn generate_table_file_from_schema(&self, module: &ModuleDef, table: &TableDef, schema: TableSchema) -> OutputFile {
let mut output = CodeIndenter::new(String::new(), INDENT);
let out = &mut output;

Expand Down
6 changes: 1 addition & 5 deletions crates/codegen/src/unrealcpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl UnrealCpp<'_> {
}

impl Lang for UnrealCpp<'_> {
fn generate_table_file(&self, module: &ModuleDef, table: &TableDef) -> OutputFile {
fn generate_table_file_from_schema(&self, module: &ModuleDef, table: &TableDef, schema: TableSchema) -> OutputFile {
let struct_name = type_ref_name(module, table.product_type_ref);
let self_header = struct_name.clone() + "Table";

Expand All @@ -58,10 +58,6 @@ impl Lang for UnrealCpp<'_> {
let table_name = table.name.deref().to_string();
let table_pascal = struct_name.clone();

let schema = TableSchema::from_module_def(module, table, (), 0.into())
.validated()
.expect("table schema should validate");

// Generate unique index classes first
let product_type = module.typespace_for_generate()[table.product_type_ref].as_product();

Expand Down
30 changes: 29 additions & 1 deletion crates/codegen/tests/snapshots/codegen__codegen_csharp.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: crates/codegen/tests/codegen.rs
assertion_line: 37
expression: outfiles
---
"Reducers/Add.g.cs" = '''
Expand Down Expand Up @@ -1602,6 +1601,35 @@ namespace SpacetimeDB
}
}
'''
"Tables/MyPlayer.g.cs" = '''
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.

#nullable enable

using System;
using SpacetimeDB.BSATN;
using SpacetimeDB.ClientApi;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace SpacetimeDB
{
public sealed partial class RemoteTables
{
public sealed class MyPlayerHandle : RemoteTableHandle<EventContext, Player>
{
protected override string RemoteTableName => "my_player";

internal MyPlayerHandle(DbConnection conn) : base(conn)
{
}
}

public readonly MyPlayerHandle MyPlayer;
}
}
'''
"Tables/Person.g.cs" = '''
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
Expand Down
100 changes: 100 additions & 0 deletions crates/codegen/tests/snapshots/codegen__codegen_rust.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2273,6 +2273,106 @@ fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
}
}
'''
"my_player_table.rs" = '''
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.

#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{
self as __sdk,
__lib,
__sats,
__ws,
};
use super::player_type::Player;

/// Table handle for the table `my_player`.
///
/// Obtain a handle from the [`MyPlayerTableAccess::my_player`] method on [`super::RemoteTables`],
/// like `ctx.db.my_player()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.my_player().on_insert(...)`.
pub struct MyPlayerTableHandle<'ctx> {
imp: __sdk::TableHandle<Player>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `my_player`.
///
/// Implemented for [`super::RemoteTables`].
pub trait MyPlayerTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`MyPlayerTableHandle`], which mediates access to the table `my_player`.
fn my_player(&self) -> MyPlayerTableHandle<'_>;
}

impl MyPlayerTableAccess for super::RemoteTables {
fn my_player(&self) -> MyPlayerTableHandle<'_> {
MyPlayerTableHandle {
imp: self.imp.get_table::<Player>("my_player"),
ctx: std::marker::PhantomData,
}
}
}

pub struct MyPlayerInsertCallbackId(__sdk::CallbackId);
pub struct MyPlayerDeleteCallbackId(__sdk::CallbackId);

impl<'ctx> __sdk::Table for MyPlayerTableHandle<'ctx> {
type Row = Player;
type EventContext = super::EventContext;

fn count(&self) -> u64 { self.imp.count() }
fn iter(&self) -> impl Iterator<Item = Player> + '_ { self.imp.iter() }

type InsertCallbackId = MyPlayerInsertCallbackId;

fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> MyPlayerInsertCallbackId {
MyPlayerInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}

fn remove_on_insert(&self, callback: MyPlayerInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}

type DeleteCallbackId = MyPlayerDeleteCallbackId;

fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> MyPlayerDeleteCallbackId {
MyPlayerDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}

fn remove_on_delete(&self, callback: MyPlayerDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}

#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {

let _table = client_cache.get_or_make_table::<Player>("my_player");
}

#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
) -> __sdk::Result<__sdk::TableUpdate<Player>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse(
"TableUpdate<Player>",
"TableUpdate",
).with_cause(e).into()
})
}
'''
"namespace_test_c_type.rs" = '''
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
Expand Down
78 changes: 78 additions & 0 deletions crates/codegen/tests/snapshots/codegen__codegen_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,84 @@ export class LoggedOutPlayerTableHandle<TableName extends string> implements __T
return this.tableCache.removeOnUpdate(cb);
}}
'''
"my_player_table.ts" = '''
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.

/* eslint-disable */
/* tslint:disable */
import {
AlgebraicType as __AlgebraicTypeValue,
BinaryReader as __BinaryReader,
BinaryWriter as __BinaryWriter,
ClientCache as __ClientCache,
ConnectionId as __ConnectionId,
DbConnectionBuilder as __DbConnectionBuilder,
DbConnectionImpl as __DbConnectionImpl,
Identity as __Identity,
SubscriptionBuilderImpl as __SubscriptionBuilderImpl,
TableCache as __TableCache,
TimeDuration as __TimeDuration,
Timestamp as __Timestamp,
deepEqual as __deepEqual,
type AlgebraicType as __AlgebraicTypeType,
type AlgebraicTypeVariants as __AlgebraicTypeVariants,
type CallReducerFlags as __CallReducerFlags,
type ErrorContextInterface as __ErrorContextInterface,
type Event as __Event,
type EventContextInterface as __EventContextInterface,
type ReducerEventContextInterface as __ReducerEventContextInterface,
type SubscriptionEventContextInterface as __SubscriptionEventContextInterface,
type TableHandle as __TableHandle,
} from "spacetimedb";
import { Player } from "./player_type";
import { type EventContext, type Reducer, RemoteReducers, RemoteTables } from ".";
declare type __keep = [EventContext, Reducer, RemoteReducers, RemoteTables];

/**
* Table handle for the table `my_player`.
*
* Obtain a handle from the [`myPlayer`] property on [`RemoteTables`],
* like `ctx.db.myPlayer`.
*
* Users are encouraged not to explicitly reference this type,
* but to directly chain method calls,
* like `ctx.db.myPlayer.on_insert(...)`.
*/
export class MyPlayerTableHandle<TableName extends string> implements __TableHandle<TableName> {
// phantom type to track the table name
readonly tableName!: TableName;
tableCache: __TableCache<Player>;

constructor(tableCache: __TableCache<Player>) {
this.tableCache = tableCache;
}

count(): number {
return this.tableCache.count();
}

iter(): Iterable<Player> {
return this.tableCache.iter();
}

onInsert = (cb: (ctx: EventContext, row: Player) => void) => {
return this.tableCache.onInsert(cb);
}

removeOnInsert = (cb: (ctx: EventContext, row: Player) => void) => {
return this.tableCache.removeOnInsert(cb);
}

onDelete = (cb: (ctx: EventContext, row: Player) => void) => {
return this.tableCache.onDelete(cb);
}

removeOnDelete = (cb: (ctx: EventContext, row: Player) => void) => {
return this.tableCache.removeOnDelete(cb);
}
}
'''
"namespace_test_c_type.ts" = '''
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
Expand Down
2 changes: 1 addition & 1 deletion crates/datastore/src/locking_tx_datastore/mut_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl MutTxId {
/// - The returned [`ViewId`] is unique and not [`ViewId::SENTINEL`].
/// - All view metadata maintained by the datastore is created atomically
pub fn create_view(&mut self, module_def: &ModuleDef, view_def: &ViewDef) -> Result<(ViewId, TableId)> {
let table_schema = TableSchema::from_view_def(module_def, view_def);
let table_schema = TableSchema::from_view_def_for_datastore(module_def, view_def);
let table_id = self.create_table(table_schema)?;

let ViewDef {
Expand Down
Loading
Loading