Skip to content

Releases: veeso/wasm-dbms

wasm-dbms 0.9.0

28 Apr 08:37
bbdc3d4

Choose a tag to compare

0.9.0

Released on 2026-04-28

⚠ Breaking Changes

  • acl: granular per-identity permissions (closes #87)

    granular per-identity permissions (closes #87)

Added

  • query: add DISTINCT support to query API

    Adds distinct_by field on Query and .distinct(&[..]) builder method.
    The select pipeline deduplicates rows by the listed columns before applying
    ORDER BY / OFFSET / LIMIT, matching standard SQL semantics. Closes #85.

  • query: add aggregates, GROUP BY, and HAVING (#86)

    Introduce Database::aggregate with COUNT/SUM/AVG/MIN/MAX, GROUP BY,
    HAVING, and aggregate-aware ORDER BY/LIMIT/OFFSET. Expose the new flow
    through the IC canister macro (aggregate_<table>) and the
    ic-dbms-client Client trait + all three client impls.

    • AggregateFunction / AggregatedRow / AggregatedValue types in
      wasm-dbms-api; HAVING / ORDER BY reference aggregate outputs by
      synthetic agg{N} names.
    • Plan-time validation: SUM/AVG numeric, unknown col/agg, LIKE/JSON
      rejected in HAVING, joins/eager relations rejected in aggregate.
    • Reject group_by/having on non-aggregate select paths via new
      QueryError::AggregateClauseInSelect (mirrors JoinInsideTypedSelect).
    • Fix Query candid serialization order after group_by/having insertion
      (idl_hash-sorted: eager_relations, distinct_by, joins, offset, limit,
      filter, group_by, having, order_by, columns).
    • Tests: 29 unit tests, 3 select-guard tests, 6 pocket-ic integration
      tests including round-trip via wrapper canister.
    • Docs: guides/querying.md aggregations section, reference/query.md
      Aggregate Types + Errors, ic/reference/schema.md endpoint listing,
      ic/guides/client-api.md client.aggregate example, errors.md updates.
    • Database trait method docs rewritten with proper Errors sections.
  • migrations: add schema snapshot, Migrate trait, and macro support (#34)

    Lay the groundwork for schema migrations:

    • Snapshot types (TableSchemaSnapshot, ColumnSnapshot, IndexSnapshot,
      ForeignKeySnapshot, OnDeleteSnapshot, DataTypeSnapshot) with
      versioned binary Encode/Decode, Serialize/Deserialize, and
      feature-gated CandidType derives.
    • TableSchema::schema_snapshot() with default impl assembling from
      table_name / primary_key / columns / indexes and
      Encode::ALIGNMENT.
    • dbms::migration module: Migrate trait, MigrationOp, ColumnChanges,
      MigrationPolicy, MigrationError, plus DbmsError::Migration and
      prelude re-exports.
    • ColumnDef gains default: Option<fn() -> Value> (kept fn-pointer to
      preserve Copy) and renamed_from: &'static [&'static str].
    • #[derive(Table)] parses #[default = ...], #[renamed_from(...)], and
      #[migrate]; emits impl Migrate for T {} unless #[migrate] is set.
    • DatabaseSchema trait and #[derive(DatabaseSchema)] gain
      migrate_default, migrate_transform, compiled_snapshots dispatch
      methods (object-safe via Self: Sized).
    • WIT: new migration-error(string) variant; guest maps
      DbmsError::Migration.
    • Docs: schema reference covers the three new attributes; new
      docs/reference/migrations.md and docs/guides/migrations.md; errors
      reference lists every MigrationError variant.
    • Tests: 13 new macro tests cover #[default], #[renamed_from],
      #[migrate], dispatch fall-through, unknown-table behaviour, and
      multi-table snapshot ordering.

    Memory layer integration, the migration engine, Database wiring, IC
    endpoints, client surface, integration tests, and full WIT migrate APIs
    are tracked in the issue checklist.

  • migrations: name-hash fingerprint + schema snapshot ledger

    Switch TableSchema::fingerprint to hash table_name() instead of
    TypeId so table identity stays stable across rebuilds and schema
    evolution. SchemaRegistry::register_table now detects name-hash
    collisions eagerly: when the fingerprint slot is occupied, it loads the
    persisted snapshot and compares names, returning the new
    MemoryError::NameCollision variant on mismatch.

    Wire SchemaSnapshotLedger into the registry: register_table
    initializes the snapshot on the dedicated page, and the encode/decode of
    SchemaRegistry now persists schema_snapshot_page. Add full module-,
    struct-, and method-level docs to SchemaSnapshotLedger plus coverage
    tests for init/load/write/get and page isolation.

    Update docs/technical/memory.md with the new per-table snapshot page,
    the name-hash fingerprint semantics, the collision-detection flow, the
    ledger API, and the TableSchemaSnapshot serialization layout.

  • migrations: engine + Database wiring for schema migrations

    Wire the migration engine into the generic wasm-dbms crate so callers
    can detect drift, plan migrations, and apply structural ops through the
    existing Database trait surface.

    Engine layer (crates/wasm-dbms/wasm-dbms/src/database/migration/):

    • snapshots: drift hash via xxh3 (xxhash-rust), seeded with
      TableSchemaSnapshot::latest_version(). compute_drift compares
      persisted snapshots (loaded through SchemaRegistry::stored_snapshots)
      with S::compiled_snapshots() reachable through the boxed schema.
    • diff: pure stored-vs-compiled diff producing Vec<MigrationOp>.
      Renames resolved via the new DatabaseSchema::renamed_from_dyn
      dispatch, type changes routed through the widening whitelist or
      MigrationOp::TransformColumn.
    • plan: deterministic op ordering plus policy-driven validation
      (destructive-op gate, defense-in-depth missing-default check).
    • apply: journaled execution of structural ops (CreateTable,
      DropTable, AlterColumn, AddIndex, DropIndex); tightening
      validation (nullable: false, unique: true) scans existing rows
      through schema dispatch. Column-mutating ops (AddColumn,
      DropColumn, RenameColumn, WidenColumn, TransformColumn) return
      the new MigrationError::DataRewriteUnsupported until the
      snapshot-driven (de)serializer (issue #91) lands. DropTable leaks
      pages (issue #90).

    Database wiring:

    • DbmsContext gains Cell<Option<bool>> drift (lazy cache) and
      Cell<bool> migrating (apply-in-progress guard so internal reads
      bypass the gate).
    • WasmDbmsDatabase::ensure_no_drift is called as the first line of
      every Database method except rollback. ACL methods on
      DbmsContext continue to bypass.
    • Database trait gains has_drift, pending_migrations (renamed
      from the previous plan_migration), and migrate(policy). The IC
      adapter and any other Database implementor must now implement them;
      the test mock in wasm-dbms-api is updated.

    API additions (wasm-dbms-api):

    • fingerprint_for_name(&str) -> u64 (xxh3_64), so the engine can
      derive a registry key for tables it knows only by name.
    • MigrationError::DataRewriteUnsupported { op }.
    • xxhash-rust workspace dependency.

    Memory layer (wasm-dbms-memory):

    • SchemaRegistry::{stored_snapshots, register_table_from_snapshot, unregister_table, table_registry_page_by_name}.
    • IndexLedger::init_from_keys for snapshot-keyed init paths.
    • test_utils::write_dummy_schema_snapshot so the table-registry unit
      tests (which allocate raw pages and call TableRegistry::load) can
      satisfy the snapshot-ledger decode that landed in #34's prior commit.

    Macro additions (wasm-dbms-macros):

    • Emit compiled_snapshots_dyn, migrate_default_dyn,
      migrate_transform_dyn, and renamed_from_dyn as object-safe
      siblings of the existing Sized dispatch methods.

    Benches (ic-dbms-canister):

    • Replace hand-written DatabaseSchema impls in eager_relation and
      read_table with #[derive(DatabaseSchema)]. ~330 LOC of boilerplate
      removed; the derive macro covers the same dispatch.
  • migrations: IC layer endpoints for schema migrations

    Wires the migration surface through the IC layer: has_drift and
    pending_migrations as queries, migrate as an update, all admin-gated
    via the existing ACL check. Adds matching Client trait methods with
    implementations for IcDbmsCanisterClient, IcDbmsAgentClient, and
    IcDbmsPocketIcClient, plus wrapper-canister bindings and PocketIC
    coverage exercising both the direct client and wrapper paths on a
    fresh canister (no drift, empty plan, migrate is a no-op).

  • migrations: WIT surface and IC migration docs

    Add has-drift / pending-migrations / migrate to wit/dbms.wit plus the
    supporting snapshot, op, and policy records. Wire them through the
    example guest and host so the round-trip is exercised end-to-end.

    Document the IC migration flow: new docs/ic/guides/migrations.md, full
    Candid signatures in docs/ic/reference/schema.md, and a Schema
    Migrations section in docs/ic/guides/client-api.md.

  • migrations: snapshot-driven record codec for column-mutating ops
  • memory: page reclamation via unclaimed-pages ledger (closes #90)

    Reserve page 2 for an LIFO ledger of pages released by destructive ops.
    Rename MemoryAccess::allocate_page to claim_page and add unclaim_page,
    both built on new grow_one_page / zero_page primitives. claim_page
    pops the ledger before bumping the high-water mark; unclaim_page zeros
    the page and pushes it. JournaledWriter records the full pre-zero page so
    rollback restores ledger state and c...

Read more

wasm-dbms 0.8.2

21 Apr 20:16

Choose a tag to compare

0.8.2

Released on 2026-04-21

Changed

  • derive Default on generated *UpdateRequest structs

    All fields on update requests are Option<T>, so Default is always
    derivable. This enables the ..Default::default() struct-update pattern
    when constructing partial updates, removing the need to write None
    for every untouched field.

wasm-dbms 0.8.1

05 Apr 19:29

Choose a tag to compare

0.8.1

Released on 2026-04-05

Added

  • add select_join to Database trait and rename CandidColumnDef to JoinColumnDef

    Move select_join from a #[doc(hidden)] method on WasmDbmsDatabase to a
    proper public method on the Database trait, making it the official API
    for join queries. Rename CandidColumnDef to JoinColumnDef to better
    reflect its purpose as the column definition type that carries table
    provenance for join results. Update all docs to reference select_join
    instead of select_raw for join queries.

Fixed

  • apply LIMIT and OFFSET after ORDER BY to match SQL semantics

    LIMIT and OFFSET were applied during the table scan (before sorting),
    so ORDER BY + LIMIT didn't produce correct "top N sorted" results.
    Now, when ORDER BY is present, LIMIT and OFFSET are deferred to after
    sorting, matching standard SQL evaluation order. The early-exit
    optimization is preserved when no ORDER BY is specified.

  • align insert offset to RawRecord alignment for fixed-size records

    The second insert into a table with all fixed-size columns (e.g. Uint64 +
    Uint64 + 1-byte CustomDataType) failed with OffsetNotAligned because:

    1. table_registry::insert aligned the write offset using E::ALIGNMENT
      instead of RawRecord::ALIGNMENT (which includes the 2-byte header).
    2. page_ledger::commit double-wrapped the type in RawRecord, computing
      RawRecord<RawRecord>::ALIGNMENT instead of RawRecord::ALIGNMENT,
      causing incorrect free-space tracking.

wasm-dbms 0.8.0

05 Apr 18:21
f5e379b

Choose a tag to compare

0.8.0

Released on 2026-04-05

Added

  • add select_join to Database trait and rename CandidColumnDef to JoinColumnDef

    Move select_join from a #[doc(hidden)] method on WasmDbmsDatabase to a
    proper public method on the Database trait, making it the official API
    for join queries. Rename CandidColumnDef to JoinColumnDef to better
    reflect its purpose as the column definition type that carries table
    provenance for join results. Update all docs to reference select_join
    instead of select_raw for join queries.

Fixed

  • apply LIMIT and OFFSET after ORDER BY to match SQL semantics

    LIMIT and OFFSET were applied during the table scan (before sorting),
    so ORDER BY + LIMIT didn't produce correct "top N sorted" results.
    Now, when ORDER BY is present, LIMIT and OFFSET are deferred to after
    sorting, matching standard SQL evaluation order. The early-exit
    optimization is preserved when no ORDER BY is specified.

wasm-dbms 0.7.2

02 Apr 08:21

Choose a tag to compare

0.7.2

Released on 2026-04-02

Fixed

  • export macros in wasm-dbms-api

    wasm-dbms-macros were not actually exported as the documentation example were showing

wasm-dbms 0.7.1

01 Apr 14:02

Choose a tag to compare

0.7.1

Released on 2026-04-01

Documentation

  • build docs from mdbook

Fixed

  • rename generated loop variables in Table macro to avoid shadowing user field names

    Fields named value caused compile errors because the generated code
    used value as both the loop binding and destructure binding, shadowing
    the field accumulator variable.

Miscellaneous

  • derive CustomDataType on principal

wasm-dbms 0.7.0

31 Mar 07:29
3251dbe

Choose a tag to compare

0.7.0

Released on 2026-03-30

⚠ Breaking Changes

  • change MemoryProvider::read and MemoryAccess::read_at to take &mut self

    MemoryProvider::read signature changed from &self to &mut self.

Added

  • bench: add benchmark comparison crate against other in-memory DBMS

    Add wasm-dbms-bench crate with Criterion benchmarks comparing wasm-dbms
    against SQLite (in-memory) and DuckDB (in-memory) across CRUD operations,
    bulk inserts, queries (filter, order, join), and transactions.

    Includes CI workflow for running benchmarks and uploading artifacts.

  • B+ tree indexes for accelerated queries

    Add a complete B+ tree index system to wasm-dbms. Every table
    automatically gets an index on its primary key, and users can declare
    additional single-column or composite indexes with the #[index]
    attribute.

    Key changes:

    Memory layer (wasm-dbms-memory):

    • IndexLedger: per-table registry mapping column sets to B-tree roots
    • IndexTree: page-per-node B+ tree with variable-size keys, doubly-linked
      leaves for range scans, and automatic node splitting/merging
    • RecordAddress: lightweight (page, offset) pointer stored in leaf entries
    • SchemaRegistry/TableRegistryPage extended with index_registry_page
    • TableRegistry now owns and exposes an IndexLedger
    • INSERT/UPDATE/DELETE maintain all indexes eagerly

    DBMS layer (wasm-dbms):

    • FilterAnalyzer: extracts index plans (Eq, Range, In) from query filters
    • IndexReader: unified view merging base B-tree results with transaction
      overlay additions/removals
    • IndexOverlay: in-memory BTreeMap tracking uncommitted index changes per
      transaction, flushed on commit, discarded on rollback
    • SELECT, UPDATE, DELETE, and JOIN queries use indexes when a suitable
      plan is found; remaining filter conditions applied as residual checks

    Macro layer (wasm-dbms-macros):

    • #[index] attribute on fields for single-column indexes
    • #[index(group = "name")] for composite indexes
    • Automatic primary key index generation in TableSchema
    • Deduplicated shared macro logic from ic-dbms-macros into wasm-dbms-macros

    Also includes CI improvements, dependency updates, and documentation
    updates covering the index memory layout, query optimization, and
    architecture changes.

  • add wasi-dbms-memory crate with file-backed MemoryProvider

    Implements WasiMemoryProvider backed by a single flat file,
    enabling wasm-dbms to persist data on any WASI-compliant runtime
    (Wasmer, Wasmtime, WasmEdge). The file layout is byte-for-byte
    equivalent to IC stable memory.

  • add #[unique] attribute for table fields

    Add support for the #[unique] field attribute that enforces uniqueness
    constraints on non-primary-key columns. A unique field automatically
    gets a B+ tree index for efficient O(log n) duplicate detection.

    • Parse #[unique] in Table derive macro, set ColumnDef::unique and
      auto-generate an index for the field
    • Add UniqueConstraintViolation error variant to QueryError
    • Enforce uniqueness in InsertIntegrityValidator and
      UpdateIntegrityValidator (update allows keeping own value)
    • Add comprehensive tests for insert, update, and transaction scenarios
    • Update schema, errors, and IC reference documentation
  • add #[autoincrement] attribute for table fields

    Add support for autoincrement columns in table schemas. Fields annotated
    with #[autoincrement] automatically generate sequential values on
    insert, starting from zero and incrementing by one.

    Implementation across all layers:

    Memory layer (wasm-dbms-memory):

    • AutoincrementLedger: per-table ledger storing current counter values
      for each autoincrement column, persisted to a dedicated memory page
    • AutoincrementRegistry: HashMap-based registry mapping column names to
      their current Value, with custom Encode implementation
    • SchemaRegistry: conditionally allocates an autoincrement page when a
      table has autoincrement columns (Option in TableRegistryPage)
    • TableRegistry: integrates AutoincrementLedger as an optional field,
      exposes autoincrement_next() to get the next value for a column

    API layer (wasm-dbms-api):

    • ColumnDef: add auto_increment field to column definitions
    • MemoryError::AutoincrementOverflow: new error variant returned when
      a column reaches its type's maximum value (uses checked_add)
    • Filter: support autoincrement columns in query filters

    Macro layer (wasm-dbms-macros):

    • Table derive macro: parse #[autoincrement] attribute on fields,
      propagate auto_increment flag to generated TableSchema impl

    DBMS layer (wasm-dbms):

    • Database: wire autoincrement through insert operations
    • Transaction overlay: support autoincrement in transactional context

    Supported types: Int8, Int16, Int32, Int64, Uint8, Uint16, Uint32,
    Uint64. Overflow returns AutoincrementOverflow error to prevent
    duplicate key generation.

CI

  • run workflow only once in pr (branches main)
  • run ci workflow against x.y.z branches
  • install nightly and check format before installing stable toolchain
  • install ic-wasm with curl

Changed

  • remove duplicated macros from ic-dbms-macros

    Remove Encode, Table, CustomDataType, and DatabaseSchema derive macros
    from ic-dbms-macros, keeping only DbmsCanister. These macros were
    duplicated from wasm-dbms-macros with the only differences being crate
    path prefixes and Candid/Serde derives on generated types.

    IC crates now re-export the wasm-dbms-macros versions through their
    preludes. To support the IC requirement of Candid-serializable generated
    types, a #[candid] attribute is added to wasm-dbms-macros' Table derive:
    when present, generated Record, InsertRequest, and UpdateRequest types
    derive CandidType, Serialize, and Deserialize.

  • 💥 change MemoryProvider::read and MemoryAccess::read_at to take &mut self

    File-backed providers need mutable access to seek before reading.
    Previously this was worked around with try_clone() on every read.
    Making the trait honest about mutation removes that overhead and
    simplifies implementations.

Documentation

  • add WASI documentation
  • update project description to better match the project identity

Fixed

  • prevent PK from being indexed twice

    using #[index] on the primary key lead to duplicated index for the primary key

  • track PK changes in overlay patch_row to chain subsequent operations
  • add missing Int8, Int16, Uint8, Uint16 variants to DataTypeKind and CandidDataTypeKind

    Value enum already had these variants but DataTypeKind did not,
    causing compile errors when using 8-bit or 16-bit integer types
    in table field definitions via the derive macro.

  • autoincrement macro codegen and DBMS integration

    Fix InsertRequest codegen for autoincrement fields:

    • from_values: wraps found values in Autoincrement::Value, absent ones
      in Autoincrement::Auto
    • into_values: skips Autoincrement::Auto fields, includes Value fields
    • into_record: unwraps Autoincrement::Value to inner type for schema

    Fix insert_contract test helper using wrong column index (order vs
    user_id). Add full coverage tests for autoincrement at the DBMS layer:
    sequential generation, explicit override, no recycle after delete,
    transaction commit/rollback counter behavior, from_values/into_values
    variants, and filter on autoincrement column.

    Wire autoincrement_next into TableRegistry as a public method.

Miscellaneous

  • remove repeated compare benchmarks
  • add Rust logo to crates.io badges in all READMEs
  • removed kofi badge
  • ignore .DS_Store

Build

  • update dependencies

wasm-dbms 0.6.0

02 Mar 11:05

Choose a tag to compare

0.6.0

Released on 2026-03-02

⚠ Breaking Changes

  • migrate Principal from built-in to CustomDataType

    Value::Principal and DataTypeKind::Principal removed.
    Principal fields in tables must now use #[custom_type] annotation.
    Existing stable memory schemas are incompatible (fingerprint change).

  • restructure workspace into wasm-dbms and ic-dbms layers

    restructure workspace into wasm-dbms and ic-dbms layers

Added

  • ic-dbms-api: add CustomValue struct with comparison and hashing
  • ic-dbms-api: add CustomDataType trait
  • ic-dbms-api: add Value::Custom variant and accessors
  • ic-dbms-api: add DataTypeKind::Custom variant and CandidDataTypeKind

    Add Custom(&'static str) variant to DataTypeKind for user-defined types.
    Remove CandidType/Serialize/Deserialize derives from DataTypeKind since
    it no longer needs to cross API boundaries directly. Introduce
    CandidDataTypeKind as the Candid-serializable mirror with Custom(String)
    for the canister API layer. Update CandidColumnDef to use the new type.

  • ic-dbms-macros: add #[derive(CustomDataType)] macro

    Add a proc-macro derive that generates impl CustomDataType (with
    TYPE_TAG constant) and impl From<T> for Value for user-defined types.
    The attribute #[type_tag = "..."] is required and uses the same
    NameValue parsing pattern as the existing #[table = "..."] attribute.

  • ic-dbms-macros: add #[custom_type] support to Table derive macro

    When a field is annotated with #[custom_type], the generated code uses
    Value::Custom(CustomValue { ... }) instead of Value::FieldType(field)
    for to_values/from_values in TableSchema, Record, InsertRequest, and
    UpdateRequest. This allows user-defined types implementing CustomDataType
    to be used as table columns.

  • 💥 migrate Principal from built-in to CustomDataType
  • add WIT interface definition for wasm-dbms Component Model API
  • add WIT guest crate with FileMemoryProvider and example schemas

    Create the wasm-dbms-example-guest crate scaffolding with:

    • FileMemoryProvider: file-backed MemoryProvider implementation with
      > persistence across process restarts and full test coverage
    • Example table schemas (User, Post) with ExampleDatabaseSchema
      > implementing the generic DatabaseSchema trait
    • register_tables helper for DBMS context initialization

    Fix wasm-dbms-macros to use DbmsError/DbmsResult instead of
    IcDbmsError/IcDbmsResult and remove IC-specific candid/serde derives
    from generated insert, update, and record structs, making the
    generic macro layer truly runtime-agnostic.

  • implement WIT guest bridge layer for Component Model exports
  • add Wasmtime host binary for WIT Component Model example

    Create the host-side binary that loads the guest WASM component via
    Wasmtime, provides WASI filesystem access, and exercises every exported
    database operation: insert, select, transactional commit, and rollback.

  • add wasm-dbms dependency to ic-dbms-canister
  • add #[derive(DatabaseSchema)] macro for automatic schema dispatch

    Add a DatabaseSchema derive macro that auto-generates the
    DatabaseSchema trait implementation from a #[tables(...)] attribute,
    eliminating ~130+ lines of boilerplate per schema. Two variants exist:
    a generic one in wasm-dbms-macros and an IC-specific one in
    ic-dbms-macros with IC crate paths. Update examples, tests, and docs.

  • add AccessControl trait with associated Id type for runtime-agnostic ACL

    Introduce the AccessControl trait in wasm-dbms-memory to abstract access
    control behind a generic interface. Different runtimes can use different
    identity types: Vec (AccessControlList), Principal (IcAccessControlList),
    or () (NoAccessControl). The A: AccessControl generic parameter is propagated
    through DbmsContext, WasmDbmsDatabase, DatabaseSchema, integrity validators,
    join engine, and both derive macros. Default type parameters preserve backward
    compatibility.

  • add journaling-based atomicity to MemoryManager

    Replace panic-based rollback in atomic() with a write-ahead journal in
    MemoryManager. All writes via write_at and zero are recorded when a
    journal is active, enabling byte-level rollback on error. This makes
    atomicity runtime-agnostic, removing the dependency on IC's
    trap-reverts-stable-memory semantics.

    Key changes:

    • Add JournalEntry, begin/commit/rollback_journal to MemoryManager
    • Refactor atomic() to use journal with nested-call awareness
    • Refactor commit() to use a single journal spanning all operations
    • Fix self vs db inconsistency in delete closure
    • Fix pre-existing clippy is_multiple_of lint
    • Add 14 journal unit tests and 1 commit-rollback integration test
    • Add docs/technical/atomicity.md

Changed

  • 💥 restructure workspace into wasm-dbms and ic-dbms layers

    Split the monolithic ic-dbms crates into a two-layer architecture:

    • wasm-dbms (generic layer): runtime-agnostic DBMS engine (wasm-dbms-api,
      > wasm-dbms-memory, wasm-dbms, wasm-dbms-macros)
    • ic-dbms (IC layer): thin adapter for Internet Computer canister
      > integration (ic-dbms-api, ic-dbms-canister, ic-dbms-macros,
      > ic-dbms-client, example, integration-tests)

    Also fixes integration test wasm paths to account for the new directory
    depth and updates CI, docs, and build scripts accordingly.

  • consolidate IC thread-locals into DbmsContext
  • remove duplicated IC database engine module
  • update ic-dbms-canister prelude to re-export from wasm-dbms
  • update IC API layer to use wasm-dbms database engine
  • slim down DbmsCanister macro to IC API only
  • update IC canister tests to use wasm-dbms engine
  • update CHANGELOG, docs, and API for custom data types and AccessControl trait

    Update CHANGELOG with custom data types, AccessControl, and DatabaseSchema entries.
    Remove CallerContext in favor of AccessControl trait. Update IC macros to use
    generic-layer AccessControl. Update example guest, Cargo.toml dependencies, and
    documentation across wasm-dbms and ic-dbms crates.

  • remove IC-specific documentation from wasm-dbms crates

    The generic wasm-dbms layer should not reference IC-specific concepts.
    Remove all doc comments mentioning IC, canister, Principal, Candid,
    IcDbmsError, and IcDbmsResult from the wasm-dbms crates.

  • make error types runtime-agnostic and replace ACL panic with error

    Rename IC-specific error variants to runtime-agnostic names
    (StableMemoryError → ProviderError, PrincipalError → IdentityDecodeError),
    add ConstraintViolation variant, replace panic in ACL last-identity removal
    with a proper error, simplify get_referenced_tables by removing thread-local
    cache, and add DbmsContext threading documentation.

  • move journal from MemoryManager to transaction module

    Extract the write-ahead journal from the memory layer into the DBMS
    layer where it belongs as a transaction concern. Introduce MemoryAccess
    trait so memory-crate functions are generic over the writer, allowing
    JournaledWriter to intercept writes for rollback support.

Documentation

  • add custom data types design document

    Design for issue #35: type-erased CustomValue approach with
    CustomDataType trait, no generic propagation through core API.
    Principal becomes a CustomDataType impl in 0.6, prerequisite
    for wasm-dbms extraction (#48) in 0.7.

  • update CHANGELOG for 0.6.0 custom data types
  • add custom data types guide and update references
  • New website for wasm-dbms
  • add Wasmtime WIT Component Model example documentation
  • update architecture docs after IC deduplication

Fixed

  • move design doc to .claude/plans, add convention to CLAUDE.md

    Design docs and plans belong in .claude/plans/ (gitignored),
    not in docs/plans/. Added this convention to CLAUDE.md.

  • ic-dbms-macros: fix nullable custom type codegen using inner type

    When a custom type field is declared as Nullable, the macro now
    correctly uses the inner type T (not Nullable) for trait lookups
    like CustomDataType::TYPE_TAG and Encode::decode in all codegen paths.

  • address code review findings
    • Replace String::leak() with OnceLock-based static cache in
      > Value::type_name() for Custom variants to prevent unbounded leaks
    • Add compile-time error when #[custom_type] and #[foreign_key] are
      > combined on the same field
  • harden custom data types and add CustomValue constructor
    • Add cache size guard (max 64 entries) to Value::type_name() to
      > prevent unbounded memory leaks on IC
    • Replace panicking .expect() with non-panicking if-let-Ok decode
      > in macro codegen for custom types (record, insert, update)
    • Add CustomValue::new() constructor enforcing consistency between
      > type_tag, encoded bytes, and display string
    • Add Project table with #[custom_type] owner field to example canister
    • Add PocketIC integration tests for custom type CRUD and filtering
  • exclude guest crate from native tests and fix clippy warning

    The guest crate targets wasm32-wasip2 and cannot link on native targets.
    Exclude it from just test using --workspace --exclude. Also fix a
    redundant_closure clippy warning in the host binary.

  • update MSRV to 1.91.1, fix ACL persist-before-panic, fix clippy warnings
    • Set rust-version to 1.91.1 (actual MSRV per cargo msrv) across
      > workspace Cargo.toml, CLAUDE.md, and all docs
    • Replace is_multiple_of (Rust 1.87+) with modulo check for MSRV compat
    • Fix ACL remove_identity to check emptiness before persisting, preventing
      > corrupted state on non-IC runtimes
    • Add #[allow(clippy::approx_constant)] to JSON test modu...
Read more

ic-dbms 0.5.0

27 Feb 11:11

Choose a tag to compare

0.5.0

Released on 2026-02-27

⚠ Breaking Changes

  • Remove generic T from Query, since it's unnecessary

    Remove T from Query and QueryBuilder

Added

  • 💥 Remove generic T from Query, since it's unnecessary

    The T: TableSchema argument from Query and QueryBuilder was actually unnecessary, because it didn't provide
    any meaningful information. The T argument has just been moved to the dbms select method, in order to bring
    information to the selected entity.

  • add generic select endpoint for untyped table queries (#10)

    Add a select_raw method to the Database trait and a select canister
    endpoint that returns Vec<Vec<(CandidColumnDef, Value)>>, enabling
    table queries by name without compile-time type information. This lays
    the groundwork for future SQL and JOIN support.

  • ic-dbms-client: add select_raw method to allow selecting untyped columns
  • implement JOIN support (INNER, LEFT, RIGHT, FULL) (#47)

    Add user-facing join guide content to the querying and relationships
    docs, create a technical deep-dive for the join engine, and update the
    architecture overview and index with join-related entries.
    Add cross-table join queries with nested-loop join engine, qualified
    column resolution, NULL padding for outer joins, and filter support
    on joined rows. Joins are available through the untyped select_raw
    path and the generated select canister endpoint.

Performance

  • batch fetch foreign keys in eager relation loading (#41)

    Replace per-record N+1 foreign key fetching with a batched approach
    using Filter::In queries. Adds ForeignFetcher::fetch_batch trait method,
    HashSet-based FK deduplication, benchmarks, and uses the existing
    TableColumns type alias throughout.

ic-dbms 0.4.0

06 Feb 12:24

Choose a tag to compare

0.4.0

Released on 2026-02-06

  • New features:
    • Issue 13: Added JSON filtering capabilities for querying JSON columns.
      • JsonFilter::Contains for PostgreSQL @> style structural containment checks
      • JsonFilter::Extract for extracting values at JSON paths with comparison operations
      • JsonFilter::HasKey for checking path existence in JSON structures
      • Path syntax supports dot notation with bracket array indices (e.g., user.items[0].name)
    • Issue 22: Added AgentClient for the ic-dbms-canister to interact with
      the IC from an IC Agent.
  • Performance improvements:
    • Issue 11: Implemented in-place update instead of delete+insert strategy
      (#37).
      • Records whose size is unchanged are now overwritten directly in stable memory, avoiding unnecessary reallocation.
      • Records whose size changes still fall back to delete+reinsert.
      • Added UpdateIntegrityValidator that allows keeping the same primary key during updates.
      • Cascade primary key changes to referencing tables via update_pk_referencing_updated_table.
      • Extracted shared validation logic into integrity::common module.
    • Replaced the external like crate with a custom SQL LIKE pattern engine (#42).
      • The new iterative two-pointer algorithm runs in O(n*m) worst-case with O(1) space and zero heap allocation, replacing the previous recursive approach that had exponential worst-case complexity.
  • Bug fixes:
    • Fixed an issue with the IcCanisterClient which called update with the wrong amount of arguments.
    • Fixed multi-column order_by applying sorts in the wrong order, causing only the last column's sort to survive
      (#39).
  • Refactoring:
    • Moved workspace crates into crates/ directory for better project organization
      (#38).
    • Cleaned up dbms.rs with extracted helpers, immutable borrow fixes, and moved tests to a separate file
      (#40).
    • Reorganized and expanded project documentation (#31).
    • Increased test coverage for ic-dbms-api, ic-dbms-canister, and ic-dbms-client.
  • Dependencies: