Skip to content
Open
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//HintName: FFI.cs
//HintName: FFI.cs
// <auto-generated />
#nullable enable
// The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type.
Expand All @@ -17,7 +17,6 @@ namespace SpacetimeDB
{
public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
{
public readonly Identity Sender;
public readonly ConnectionId? ConnectionId;
public readonly Random Rng;
public readonly Timestamp Timestamp;
Expand All @@ -29,6 +28,8 @@ public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
// We need this property to be non-static for parity with client SDK.
public Identity Identity => Internal.IReducerContext.GetIdentity();

private readonly Identity _sender;

internal ReducerContext(
Identity identity,
ConnectionId? connectionId,
Expand All @@ -37,14 +38,19 @@ internal ReducerContext(
AuthCtx? senderAuth = null
)
{
Sender = identity;
_sender = identity;
ConnectionId = connectionId;
Rng = random;
Timestamp = time;
SenderAuth = senderAuth ?? AuthCtx.BuildFromSystemTables(connectionId, identity);
CounterUuid = 0;
}

/// <summary>
/// The identity of the client that invoked the reducer.
/// </summary>
public Identity Sender() => _sender;

/// <summary>
/// Create a new random <see cref="Uuid"/> `v4` using the built-in RNG.
/// </summary>
Expand Down Expand Up @@ -199,13 +205,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase

public sealed record ViewContext : DbContext<Internal.LocalReadOnly>, Internal.IViewContext
{
public Identity Sender { get; }
private readonly Identity _sender;

internal ViewContext(Identity sender, Internal.LocalReadOnly db)
: base(db)
{
Sender = sender;
_sender = sender;
}

/// <summary>
/// The identity of the client that invoked the view.
/// </summary>
public Identity Sender() => _sender;
}

public sealed record AnonymousViewContext
Expand Down
20 changes: 16 additions & 4 deletions crates/bindings-csharp/Codegen/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1737,7 +1737,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

namespace SpacetimeDB {
public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext {
public readonly Identity Sender;
public readonly ConnectionId? ConnectionId;
public readonly Random Rng;
public readonly Timestamp Timestamp;
Expand All @@ -1747,16 +1746,24 @@ public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
// We need this property to be non-static for parity with client SDK.
public Identity Identity => Internal.IReducerContext.GetIdentity();

private readonly Identity _sender;

internal ReducerContext(Identity identity, ConnectionId? connectionId, Random random,
Timestamp time, AuthCtx? senderAuth = null)
{
Sender = identity;
_sender = identity;
ConnectionId = connectionId;
Rng = random;
Timestamp = time;
SenderAuth = senderAuth ?? AuthCtx.BuildFromSystemTables(connectionId, identity);
CounterUuid = 0;
}

/// <summary>
/// The identity of the client that invoked the reducer.
/// </summary>
public Identity Sender() => _sender;

/// <summary>
/// Create a new random <see cref="Uuid"/> `v4` using the built-in RNG.
/// </summary>
Expand Down Expand Up @@ -1891,13 +1898,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase {

public sealed record ViewContext : DbContext<Internal.LocalReadOnly>, Internal.IViewContext
{
public Identity Sender { get; }
private readonly Identity _sender;

internal ViewContext(Identity sender, Internal.LocalReadOnly db)
: base(db)
{
Sender = sender;
_sender = sender;
}

/// <summary>
/// The identity of the client that invoked the view.
/// </summary>
public Identity Sender() => _sender;
}

public sealed record AnonymousViewContext : DbContext<Internal.LocalReadOnly>, Internal.IAnonymousViewContext
Expand Down
7 changes: 5 additions & 2 deletions crates/bindings-csharp/Runtime/Internal/TxContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ public sealed class TxContext(
Random rng
)
{
private readonly Identity _sender = sender;

public Local Db { get; } = db;
public Identity Sender { get; } = sender;
public ConnectionId? ConnectionId { get; } = connectionId;
public Timestamp Timestamp { get; } = timestamp;
public AuthCtx SenderAuth { get; } = senderAuth;
public Random Rng { get; } = rng;

public Identity Sender() => _sender;

public TxContext WithTimestamp(Timestamp ts) =>
new(Db, Sender, ConnectionId, ts, SenderAuth, Rng);
new(Db, _sender, ConnectionId, ts, SenderAuth, Rng);
}
10 changes: 7 additions & 3 deletions crates/bindings-csharp/Runtime/ProcedureContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ public abstract class ProcedureContextBase(
Timestamp time
) : Internal.IInternalProcedureContext
{
private readonly Identity _sender = sender;

public Identity Sender() => _sender;

public static Identity Identity => Internal.IProcedureContext.GetIdentity();
public Identity Sender { get; } = sender;
public ConnectionId? ConnectionId { get; } = connectionId;
public Random Rng { get; } = random;
public Timestamp Timestamp { get; private set; } = time;
Expand Down Expand Up @@ -47,7 +50,7 @@ public Internal.TxContext EnterTxContext(long timestampMicros)
txContext?.WithTimestamp(timestamp)
?? new Internal.TxContext(
CreateLocal(),
Sender,
_sender,
ConnectionId,
timestamp,
SenderAuth,
Expand Down Expand Up @@ -229,8 +232,9 @@ public abstract class ProcedureTxContextBase(Internal.TxContext inner)

internal void Refresh(Internal.TxContext inner) => Inner = inner;

public Identity Sender() => Inner.Sender();

public LocalBase Db => (LocalBase)Inner.Db;
public Identity Sender => Inner.Sender;
public ConnectionId? ConnectionId => Inner.ConnectionId;
public Timestamp Timestamp => Inner.Timestamp;
public AuthCtx SenderAuth => Inner.SenderAuth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ fn init(ctx: &ReducerContext) {

#[reducer(client_connected)]
fn client_connected(ctx: &ReducerContext) {
let existing_user = ctx.db.offline_user().identity().find(ctx.sender);
let existing_user = ctx.db.offline_user().identity().find(ctx.sender());
if let Some(user) = existing_user {
ctx.db.user().insert(user);
ctx.db.offline_user().identity().delete(ctx.sender);
ctx.db.offline_user().identity().delete(ctx.sender());
return;
}
ctx.db.offline_user().insert(User {
identity: ctx.sender,
identity: ctx.sender(),
has_incremented_count: 0,
});
}

#[reducer(client_disconnected)]
fn client_disconnected(ctx: &ReducerContext) -> Result<(), String> {
let existing_user = ctx.db.user().identity().find(ctx.sender).ok_or("User not found")?;
let existing_user = ctx.db.user().identity().find(ctx.sender()).ok_or("User not found")?;
ctx.db.offline_user().insert(existing_user);
ctx.db.user().identity().delete(ctx.sender);
ctx.db.user().identity().delete(ctx.sender());
Ok(())
}

Expand All @@ -48,7 +48,7 @@ fn increment_counter(ctx: &ReducerContext) -> Result<(), String> {
counter.count += 1;
ctx.db.counter().id().update(counter);

let mut user = ctx.db.user().identity().find(ctx.sender).ok_or("User not found")?;
let mut user = ctx.db.user().identity().find(ctx.sender()).ok_or("User not found")?;
user.has_incremented_count += 1;
ctx.db.user().identity().update(user);

Expand Down
2 changes: 1 addition & 1 deletion crates/bindings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ struct PlayerAndLevel {
// At-most-one row: return Option<T>
#[view(name = my_player, public)]
fn my_player(ctx: &ViewContext) -> Option<Player> {
ctx.db.player().identity().find(ctx.sender)
ctx.db.player().identity().find(ctx.sender())
}

// Multiple rows: return Vec<T>
Expand Down
30 changes: 23 additions & 7 deletions crates/bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ pub use spacetimedb_bindings_macro::table;
///
/// #[reducer]
/// fn scheduled(ctx: &ReducerContext, args: ScheduledArgs) -> Result<(), String> {
/// if ctx.sender != ctx.identity() {
/// if ctx.sender() != ctx.identity() {
/// return Err("Reducer `scheduled` may not be invoked by clients, only via scheduling.".into());
/// }
/// // Reducer body...
Expand Down Expand Up @@ -707,7 +707,7 @@ pub use spacetimedb_bindings_macro::reducer;
/// #[procedure]
/// fn return_value(ctx: &mut ProcedureContext, arg: MyArgument) -> MyReturnValue {
/// MyReturnValue {
/// a: format!("Hello, {}", ctx.sender),
/// a: format!("Hello, {}", ctx.sender()),
/// b: ctx.timestamp,
/// }
/// }
Expand Down Expand Up @@ -816,13 +816,13 @@ pub use spacetimedb_bindings_macro::procedure;
/// // A view that selects at most one row from a table
/// #[view(name = my_player, public)]
/// fn my_player(ctx: &ViewContext) -> Option<Player> {
/// ctx.db.player().identity().find(ctx.sender)
/// ctx.db.player().identity().find(ctx.sender())
/// }
///
/// // An example of column projection
/// #[view(name = my_player_id, public)]
/// fn my_player_id(ctx: &ViewContext) -> Option<PlayerId> {
/// ctx.db.player().identity().find(ctx.sender).map(|Player { id, .. }| PlayerId { id })
/// ctx.db.player().identity().find(ctx.sender()).map(|Player { id, .. }| PlayerId { id })
/// }
///
/// // An example that is analogous to a semijoin in sql
Expand Down Expand Up @@ -894,7 +894,7 @@ impl Default for AnonymousViewContext {
/// The other is [`AnonymousViewContext`].
/// Use this type if the view depends on the caller's identity.
pub struct ViewContext {
pub sender: Identity,
sender: Identity,
pub db: LocalReadOnly,
pub from: QueryBuilder,
}
Expand All @@ -907,6 +907,11 @@ impl ViewContext {
from: QueryBuilder {},
}
}

/// The `Identity` of the client that invoked the view.
pub fn sender(&self) -> Identity {
self.sender
}
}

/// The context that any reducer is provided with.
Expand All @@ -924,7 +929,7 @@ impl ViewContext {
#[non_exhaustive]
pub struct ReducerContext {
/// The `Identity` of the client that invoked the reducer.
pub sender: Identity,
sender: Identity,

/// The time at which the reducer was started.
pub timestamp: Timestamp,
Expand Down Expand Up @@ -1014,6 +1019,11 @@ impl ReducerContext {
}
}

/// The `Identity` of the client that invoked the reducer.
pub fn sender(&self) -> Identity {
self.sender
}

/// Returns the authorization information for the caller of this reducer.
pub fn sender_auth(&self) -> &AuthCtx {
&self.sender_auth
Expand Down Expand Up @@ -1124,7 +1134,7 @@ impl Deref for TxContext {
#[cfg(feature = "unstable")]
pub struct ProcedureContext {
/// The `Identity` of the client that invoked the procedure.
pub sender: Identity,
sender: Identity,

/// The time at which the procedure was started.
pub timestamp: Timestamp,
Expand Down Expand Up @@ -1162,6 +1172,12 @@ impl ProcedureContext {
counter_uuid: Cell::new(0),
}
}

/// The `Identity` of the client that invoked the procedure.
pub fn sender(&self) -> Identity {
self.sender
}

/// Read the current module's [`Identity`].
pub fn identity(&self) -> Identity {
// Hypothetically, we *could* read the module identity out of the system tables.
Expand Down
Loading