logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class EnsureSchemaOnFirstUseStructuredStore

    IStructuredStore decorator that lazily calls the inner store's EnsureSchemaAsync(StructuredTableSchema, CancellationToken) for a fixed StructuredTableSchema exactly once before the first real operation, then forwards everything verbatim. Built for embedded backends whose storage lives on the player's device (e.g. the SQLite leaderboard backend): no administrator exists there to provision the schema manually, so the store must create its own table on first use. Server backends keep their manual-provisioning contract and are never wrapped.

    Inheritance
    object
    EnsureSchemaOnFirstUseStructuredStore
    Implements
    IStructuredStore
    IPositionalStructuredStore
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.StructuredPersistence.Infrastructure.Decorators
    Assembly: Serenity.StructuredPersistence.Decorators.dll
    Syntax
    public class EnsureSchemaOnFirstUseStructuredStore : IStructuredStore, IPositionalStructuredStore
    Remarks

    Concurrency: the first-use schema call is single-flighted through a SemaphoreSlim (the same serialization idiom KeyValueStructuredStore uses for its partition writes), so concurrent first operations produce exactly one EnsureSchemaAsync call.

    The ensured flag latches ONLY on success. A failed EnsureSchemaAsync propagates to the caller and the next operation retries it — caching the failure would permanently kill the store over a transient error (the same latch-on-failure defect once fixed in SignalEmitterComponent).

    The inner store must implement BOTH IStructuredStore and IPositionalStructuredStore (enforced at construction): this decorator implements IPositionalStructuredStore unconditionally, so accepting a positional-blind inner would lie to StructuredStoreLeaderboardAdapter's store is IPositionalStructuredStore capability check and break its full-scan fallback.

    HealthCheckAsync(CancellationToken) forwards WITHOUT ensuring the schema: its contract across every backend is "is the store reachable" and it never throws — forcing DDL inside it would turn a reachability probe into a mutation and report unreachable on a schema failure.

    Constructors

    EnsureSchemaOnFirstUseStructuredStore(IStructuredStore, StructuredTableSchema)

    Initializes a new instance of the EnsureSchemaOnFirstUseStructuredStore class.

    Declaration
    public EnsureSchemaOnFirstUseStructuredStore(IStructuredStore inner, StructuredTableSchema schema)
    Parameters
    Type Name Description
    IStructuredStore inner

    The store to decorate. Must also implement IPositionalStructuredStore (see the class remarks).

    StructuredTableSchema schema

    The schema ensured once before the first operation.

    Exceptions
    Type Condition
    ArgumentNullException

    Thrown when inner or schema is null.

    ArgumentException

    Thrown when inner does not implement IPositionalStructuredStore.

    Properties

    Namespace

    Declaration
    public string Namespace { get; }
    Property Value
    Type Description
    string

    Methods

    CountAsync(StoreTable, IReadOnlyList<FieldFilter>, IReadOnlyList<string>, CancellationToken)

    Declaration
    public Task<long> CountAsync(StoreTable table, IReadOnlyList<FieldFilter> filters, IReadOnlyList<string> distinctBy, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    IReadOnlyList<FieldFilter> filters
    IReadOnlyList<string> distinctBy
    CancellationToken cancellationToken
    Returns
    Type Description
    Task<long>

    DeleteByQueryAsync(StoreTable, IReadOnlyList<FieldFilter>, CancellationToken)

    Declaration
    public Task DeleteByQueryAsync(StoreTable table, IReadOnlyList<FieldFilter> filters, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    IReadOnlyList<FieldFilter> filters
    CancellationToken cancellationToken
    Returns
    Type Description
    Task

    EnsureSchemaAsync(StructuredTableSchema, CancellationToken)

    Declaration
    public Task EnsureSchemaAsync(StructuredTableSchema schema, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StructuredTableSchema schema
    CancellationToken cancellationToken
    Returns
    Type Description
    Task
    Remarks

    Forwards to the inner store; a successful call for this decorator's own table also satisfies the first-use guarantee, so later operations skip the lazy call.

    HealthCheckAsync(CancellationToken)

    Declaration
    public Task<bool> HealthCheckAsync(CancellationToken cancellationToken)
    Parameters
    Type Name Description
    CancellationToken cancellationToken
    Returns
    Type Description
    Task<bool>
    Remarks

    Forwards without ensuring the schema — see the class remarks.

    InsertAsync(StoreTable, StructuredRecord, StructuredTrim, CancellationToken)

    Declaration
    public Task InsertAsync(StoreTable table, StructuredRecord record, StructuredTrim trim, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    StructuredRecord record
    StructuredTrim trim
    CancellationToken cancellationToken
    Returns
    Type Description
    Task

    QueryAsync(StoreTable, StructuredQuery, CancellationToken)

    Declaration
    public Task<IReadOnlyList<StructuredRecord>> QueryAsync(StoreTable table, StructuredQuery query, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    StructuredQuery query
    CancellationToken cancellationToken
    Returns
    Type Description
    Task<IReadOnlyList<StructuredRecord>>

    QueryWindowAroundAsync(StoreTable, IReadOnlyList<FieldFilter>, IReadOnlyList<string>, IReadOnlyList<OrderField>, FieldFilter, int, CancellationToken)

    Declaration
    public Task<IReadOnlyList<StructuredRecord>> QueryWindowAroundAsync(StoreTable table, IReadOnlyList<FieldFilter> scope, IReadOnlyList<string> distinctBy, IReadOnlyList<OrderField> ordering, FieldFilter targetKey, int radius, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    IReadOnlyList<FieldFilter> scope
    IReadOnlyList<string> distinctBy
    IReadOnlyList<OrderField> ordering
    FieldFilter targetKey
    int radius
    CancellationToken cancellationToken
    Returns
    Type Description
    Task<IReadOnlyList<StructuredRecord>>

    TrimBeyondAsync(StoreTable, IReadOnlyList<FieldFilter>, IReadOnlyList<OrderField>, int, CancellationToken)

    Declaration
    public Task TrimBeyondAsync(StoreTable table, IReadOnlyList<FieldFilter> scopeFilters, IReadOnlyList<OrderField> ordering, int keepCount, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    IReadOnlyList<FieldFilter> scopeFilters
    IReadOnlyList<OrderField> ordering
    int keepCount
    CancellationToken cancellationToken
    Returns
    Type Description
    Task

    UpsertIfBetterAsync(StoreTable, StructuredRecord, IReadOnlyList<string>, string, StructuredSortDirection, StructuredTrim, CancellationToken)

    Declaration
    public Task UpsertIfBetterAsync(StoreTable table, StructuredRecord record, IReadOnlyList<string> keyFields, string comparisonField, StructuredSortDirection betterDirection, StructuredTrim trim, CancellationToken cancellationToken)
    Parameters
    Type Name Description
    StoreTable table
    StructuredRecord record
    IReadOnlyList<string> keyFields
    string comparisonField
    StructuredSortDirection betterDirection
    StructuredTrim trim
    CancellationToken cancellationToken
    Returns
    Type Description
    Task

    Implements

    IStructuredStore
    IPositionalStructuredStore
    In this article
    © 2026 Serenity. All Rights Reserved