feat: drop_named_graph + fluree graph CLI (list, drop)#1247
Open
bplatz wants to merge 4 commits into
Open
Conversation
`Fluree::drop_named_graph(ledger_id, graph_iri)` retracts every triple currently asserted under a named graph in one new commit. History at older `t` is preserved, the graph IRI keeps its `g_id`, drops are per-branch. System graphs (default, txn-meta, config) are rejected; unknown IRIs return 404 before staging so the registry isn't silently extended. Idempotent on an already-empty graph (no commit produced). Wire endpoint: POST /v1/fluree/drop-graph (admin-protected). CLI: `fluree graph drop <iri> [--ledger] [--remote]` plus a companion `fluree graph list [--include-system] [--json]` that parses the existing `/info` payload's `named-graphs` section. Both subcommands support `--remote`, tracked-remote auto-routing, and `--direct`. `graph_iri` is validated as an absolute IRI: `<scheme>:<rest>` head, no whitespace, no C0/DEL controls, no RFC 3987-excluded characters. Leading/trailing whitespace is rejected, not silently trimmed. Docs: new docs/cli/graph.md; Drop Named Graph Contract and Graph List Contract in docs/cli/server-integration.md; POST /drop-graph spec in docs/api/endpoints.md; cross-links from docs/cli/drop.md and docs/concepts/datasets-and-named-graphs.md; SUMMARY and cli/README updated. /info contract now notes `ledger.named-graphs` as required for `fluree graph list`. 11 integration tests in it_drop_named_graph.rs cover the happy path, idempotency, history preservation via DatasetSpec + TimeSpec, per- branch isolation, and every validation/rejection branch; 7 unit tests cover `validate_absolute_iri`.
`build_ledger_block` was enumerating named graphs by iterating `BinaryIndexStore::graph_entries()`. That meant ledgers with no index reported only `urn:default`, and any graph registered in a commit after the last index build was silently missing from `info.ledger.named-graphs` until the next index. Since `fluree graph list` parses that same payload, the bug surfaced there as well — newly registered user graphs wouldn't appear between drops or after a fresh insert until the indexer caught up. Iterate `ledger.snapshot.graph_registry.iter_entries()` instead. The registry is mutated at commit-apply time, so it is always current. Per-graph `flakes` / `size` totals still come from `IndexStats.graphs` when populated and fall back to `0` otherwise. `store: Option<&BinaryIndexStore>` is no longer needed in `build_ledger_block` and was dropped from the signature. Regression tests in `it_ledger_info_named_graphs.rs`: - `named_graphs_visible_without_an_index` — two user graphs seeded with no index built; all four (default + two users + txn-meta + config) must appear. - `named_graphs_include_post_index_registrations` — alpha seeded and indexed, beta seeded post-index without rebuilding; both user graphs must appear.
Both the local and remote branch-drop paths in
`fluree-db-cli/src/commands/branch.rs` only inspected the `deferred`
field when deciding what to print, so a second drop of an
already-retracted branch was reported as a successful "Dropped
branch" instead of a no-op. The bug applied to the local report and
to the JSON response (`print_branch_dropped`).
Both paths now branch on the authoritative `status` /
`DropStatus` field:
- `AlreadyRetracted` -> "Branch '...' was already retracted (no-op)."
- `NotFound` -> "Branch '...' not found."
- `Dropped` -> existing dropped / deferred-retract messages,
keyed on `deferred`.
Extracted `format_drop_branch_headline` from `print_branch_dropped`
so the status / deferred branching is exercised by six unit tests
in `commands::branch::tests`, including a regression test that
asserts `status: "already_retracted"` wins over a stale
`deferred: true` field.
Locked the underlying API contract in `it_branch.rs` with
`drop_branch_is_idempotent_already_retracted`: a deferred drop on
a branch with children leaves the nameservice record retracted,
and a second `Fluree::drop_branch` call on the same branch must
return `DropStatus::AlreadyRetracted`.
fluree graph CLI (list, drop)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fluree::drop_named_graph(ledger_id, graph_iri)retracts every triple currently asserted under a named graph in a single new commit. History at oldertis preserved, the graph IRI keeps itsg_id, and the operation is idempotent on an empty graph (no commit produced).POST /v1/fluree/drop-graph(admin-protected) and a matching CLI:fluree graph drop <iri>plus a companionfluree graph list. Both subcommands support--remote, tracked-remote auto-routing, and--direct.ledger.named-graphsblock in the/infopayload so newly registered graphs show up immediately (not after the next index build).fluree branch dropso a second drop of an already-retracted branch prints "no-op" instead of "Dropped branch".Details
drop_named_graph(new)Fluree::drop_named_graph(ledger_id, graph_iri) -> Result<DropNamedGraphReport>walks the live triples undergraph_iriand stages a single retract-only commit. Concrete behavior:tsee the old graph contents. The graph IRI keeps its assignedg_id; later inserts re-populate it normally.mydb:devleavesmydb:mainuntouched.DropStatus::AlreadyRetractedoutcome.urn:fluree:default,urn:fluree:txn-meta,urn:fluree:config(the three system graphs) returnApiError::Http(400). Unknown IRIs return404before staging so the graph registry isn't silently extended.graph_iriis validated as an absolute IRI: requires a<scheme>:<rest>head, no whitespace, no C0/DEL control characters, and rejects RFC 3987-excluded characters. Leading/trailing whitespace is rejected outright, not silently trimmed (7 unit tests invalidate_absolute_iri).Wire endpoint:
POST /v1/fluree/drop-graphAdmin-protected — same bracket as
/drop,/create,/reindex. Body and response specified indocs/api/endpoints.md; full server-side contract documented indocs/cli/server-integration.md("Drop Named Graph Contract").CLI
fluree graph drop <iri>Three-mode dispatch matching the rest of the
--remotefamily: explicit--remote <name>→ named remote; otherwise auto-route through a locally runningfluree server startifserver.meta.jsonis present; otherwise direct local execution.--directskips auto-routing.fluree graph listParses the existing
/infopayload'sledger.named-graphssection. By default hides the three system graphs;--include-systemshows them.Companion fixes
ledger.named-graphsnow built from the live registrybuild_ledger_blockused to enumerate named graphs viaBinaryIndexStore::graph_entries(). Two failure modes:urn:default.info.ledger.named-graphsuntil the next index ran.Since
fluree graph listparses that same payload, the bug surfaced there as well — newly registered user graphs wouldn't show up between drops or right after an insert.Fixed by iterating
ledger.snapshot.graph_registry.iter_entries()instead, which is mutated at commit-apply time and so is always current. Per-graphflakes/sizetotals still come fromIndexStats.graphswhen populated and fall back to0otherwise.fluree branch drophonorsDropStatus::AlreadyRetractedBoth the local and remote branch-drop paths in
fluree-db-cli/src/commands/branch.rswere only inspecting thedeferredfield when deciding what to print, so a second drop of an already-retracted branch was reported as a successful "Dropped branch" instead of a no-op. The bug applied to the local report and to the JSON response handler (print_branch_dropped).Both paths now branch on the authoritative
status/DropStatusfield:AlreadyRetractedNotFoundDroppeddeferred.Docs
docs/cli/graph.md— full reference for thefluree graphsubcommand family.docs/cli/server-integration.md.POST /drop-graphspec indocs/api/endpoints.md.docs/cli/drop.mdanddocs/concepts/datasets-and-named-graphs.mdpoint at the new graph reference.docs/SUMMARY.md,docs/cli/README.mdtable of contents./infocontract entry inserver-integration.mdnow notesledger.named-graphsas required forfluree graph list.Tests
fluree-db-api/tests/it_drop_named_graph.rscovering:DatasetSpec+TimeSpeclookups at oldert.validate_absolute_iri.it_ledger_info_named_graphs.rs(179 lines) covers the/inforegistry fix — pre-index, post-insert, post-drop snapshots all agree with the live registry.it_branchextended with assertions for theAlreadyRetractedCLI output fix.