Skip to content

wasm-dbms 0.6.0

Choose a tag to compare

@veeso veeso released this 02 Mar 11:05

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 module
    • Remove unused _name binding in DatabaseSchema metadata parsing
  • remove redundant drop and unnecessary pub visibility in journal refactor

    Remove the explicit drop(self) in Journal::commit since the method
    already takes ownership, and revert test-only struct fields in
    memory_manager back to private visibility since they are unused
    outside their module.

  • add wasm32-wasip2 target to CI and rust-toolchain

Miscellaneous

  • funding
  • add justfile recipes for WIT example build and test

    Adds build_wasm_dbms_example (guest + host) and test_wasm_dbms_example
    recipes, integrated into build_all and test_all for CI coverage.

  • update benchmarks and remove unused dependencies after IC deduplication
  • sort deps