Wydania

  • v1.4.2 — Filter operators in client API

    Szontágh Ferenc 3 miesięcy temu | 132 commitów w main od tego wydania

    Highlights

    Exposes the full filter operator set in the client API. The server has supported EQ/NE/GT/GTE/LT/LTE/IN/CONTAINS/EXISTS/REGEX/SEARCH all along — the client library was artificially forcing every filter to EQ. This release lifts that limitation.

    What changed

    • Client::FilterOp enum mirroring the server-side proto FilterOp
    • Client::Filter struct: {field, op, value} with a convenience 2-arg constructor (defaults to EQ)
    • QueryOptions::filters changed type: vector<pair<string, json>>vector<Filter>
    • All three filter serialization sites in client.cpp (find, findWithMetrics, count) now pick up the operator from Filter::op instead of hardcoding EQ

    Example

    using Op = smartbotic::database::Client::FilterOp;
    
    smartbotic::database::Client::QueryOptions opts;
    opts.filters = {
        {"age",    Op::GTE,      18},
        {"status", Op::NE,       "deleted"},
        {"tags",   Op::CONTAINS, "admin"},
        {"role",   Op::IN,       nlohmann::json::array({"admin", "moderator"})},
        {"bio",    Op::REGEX,    "^senior "},
        {"email",  Op::EXISTS,   true}
    };
    auto results = db.find("users", opts);
    

    Backward compatibility

    The 2-arg Filter(field, value) constructor defaults op = EQ, so existing callers using brace-init continue to compile and behave the same:

    opts.filters = {{"status", "active"}, {"role", "admin"}};  // still works, both are EQ
    

    Minor behavior change

    The magic _search field name no longer auto-selects FILTER_OP_SEARCH. Use FilterOp::SEARCH explicitly:

    // Before (v1.4.1)
    opts.filters = {{"_search", "query"}};  // auto-promoted to SEARCH
    
    // After (v1.4.2)
    opts.filters = {{"_search", Op::SEARCH, "query"}};  // explicit
    

    Docs

    • docs/integration-guide.md — Querying section updated with operator table and examples

    Packages

    Four .deb packages published to repository.smartbotics.ai (suite: trixie):

    • smartbotic-database_1.4.2-1_amd64.deb
    • libsmartbotic-db-client_1.4.2-1_amd64.deb
    • libsmartbotic-db-client-dev_1.4.2-1_amd64.deb
    • smartbotic-db-cli_1.4.2-1_amd64.deb
     
  • v1.4.1 — upsert_setting + generate_secret migration ops

    Szontágh Ferenc 3 miesięcy temu | 133 commitów w main od tego wydania

    Highlights

    Adds two new migration operation types — upsert_setting and generate_secret — for declarative settings seeding and secret generation during migrations. Patch release, fully backward compatible.

    New migration operations

    upsert_setting

    Upserts a single document into a collection. Useful for seeding default settings:

    {
      "type": "upsert_setting",
      "collection": "settings",
      "id": "feature_flags",
      "data": {
        "dark_mode_enabled": true,
        "beta_features": false
      }
    }
    

    generate_secret

    Generates a cryptographically-random secret and stores it in a document — only if the document doesn't already exist (so re-running the migration doesn't rotate the secret):

    {
      "type": "generate_secret",
      "collection": "settings",
      "id": "jwt_signing_key",
      "field": "value",
      "bytes": 32,
      "format": "hex"
    }
    

    Supported formats: hex, base64. Default bytes: 32.

    Use case

    Consumers (ShadowMan, CallerAI) can now declare their initial runtime configuration entirely in migrations, including secrets that must be stable across restarts but unique per deployment. No more "run this script after installing the package" step in deployment docs.

    Packages

    Four .deb packages published to repository.smartbotics.ai (suite: trixie):

    • smartbotic-database_1.4.1-1_amd64.deb
    • libsmartbotic-db-client_1.4.1-1_amd64.deb
    • libsmartbotic-db-client-dev_1.4.1-1_amd64.deb
    • smartbotic-db-cli_1.4.1-1_amd64.deb
     
  • v1.3.0 — Optimistic locking in Client::update()

    Szontágh Ferenc 3 miesięcy temu | 137 commitów w main od tego wydania

    Highlights

    Client::update() now uses automatic optimistic locking with retry — transparent to callers. The silent data-loss race where two concurrent update() calls would blindly overwrite each other at the storage layer is gone.

    The problem this solves

    Before v1.3.0:

    client1: read doc (v1), modify, update() → blind write → v2
    client2: read doc (v1), modify, update() → blind write → v3
    # client1's write silently not recorded as a version-ordered change
    

    After v1.3.0:

    client1: update() → get(v1) → updateIfVersion(v1) → SUCCESS → v2
    client2: update() → get(v2) → updateIfVersion(v2) → SUCCESS → v3
    #              ↑ sees v2 now, not stale v1 — writes are properly sequenced
    

    Both writes still land, but now each is a proper version-checked write with history preserved. No writes are silently lost at the storage layer.

    How it works

    Client::update() internally:

    1. Strips metadata fields (_version, _id, _created_at, etc.) from the caller's data
    2. Reads the current document via get() to obtain the current version
    3. Calls updateIfVersion() with that version
    4. On version conflict (another writer wrote between step 2 and step 3), retries up to Config::maxRetries times
    5. Returns true on success, false if retries exhausted

    The caller just calls update() as before — no API change.

    Honest limitation

    This is still "last writer wins" for complete document replacement. If two clients modify different fields via update(), the last winning retry overwrites the other's field change. For true partial-update safety, use patch() shipped in v1.4.0.

    Metadata field stripping

    Callers can now pass the JSON from get() directly after modifying fields — the embedded _version etc. are automatically stripped before the write:

    auto doc = db.get("users", "u1");
    (*doc)["name"] = "Alice Smith";
    (*doc)["role"] = "admin";
    db.update("users", "u1", *doc);  // _version, _id, _created_at etc. stripped internally
    

    Backward compatibility

    • No API change
    • No on-disk format change
    • Callers see the same bool return and the same success/failure semantics
    • Config maxRetries (default 3) controls retry count

    Packages

    Four .deb packages published to repository.smartbotics.ai (suite: trixie):

    • smartbotic-database_1.3.0-1_amd64.deb
    • libsmartbotic-db-client_1.3.0-1_amd64.deb
    • libsmartbotic-db-client-dev_1.3.0-1_amd64.deb
    • smartbotic-db-cli_1.3.0-1_amd64.deb