Skip to content

v2.4.2

Choose a tag to compare

@github-actions github-actions released this 07 Nov 19:43
· 77 commits to main since this release

HexDB 2.4.2 makes deletes safe: every delete can be undone, a delete or update without a filter no longer runs by accident, and documents can belong to other documents so deleting the owner takes (or refuses to leave) what belongs to it.

Breaking change

  • POST /{tessellation}/_update with no filter, or {}, is refused with 400 filter_required. Add "all": true to the body if you mean every document. The same goes for GraphQL updateDocuments (all: true) and the drivers' updateWhere (an all option). Requests with a filter are unchanged.

Added

  • A trash and a delete history for every delete. A deleted document goes to the trash for storage.trash_days (30), and each request's delete (the documents it named or matched and everything that went with them) is one delete batch. GET /deletes lists the history, POST /deletes/{batch}/restore puts a whole batch back in one commit, and DELETE /deletes/{batch} purges it for good. GET /{tessellation}/_trash and its restore and purge endpoints work for document tessellations as they do for files. Masked fields stay sealed and tokens stay tokens in the trash, and both the trash and the history replicate, so a hex that takes over can restore them. DELETE /{tessellation}/{id} names its batch in X-HexDB-Delete-Batch.
  • Delete by filter, with guardrails. POST /{tessellation}/_delete deletes the documents matching a filter in one atomic batch. It needs a filter or "all": true. dry_run shows what would go, and expect refuses (409 count_changed) unless exactly that many documents would go, checked again inside the commit. GraphQL deleteDocuments, a delete_where transaction operation, and deleteWhere in the Node, Python and .NET drivers.
  • Parent links and cascading deletes. A schema field can name the document that owns this one: "order_id": {"type": "string", "parent": {"tessellation": "orders", "on_delete": "cascade"}}. When the parent is deleted, cascade deletes the child too, restrict refuses the delete (409 has_children), and detach sets the link to null. Files can belong to documents the same way. A link marks ownership only: no joins, and writes don't check that the parent exists. Link fields are indexed, a cascade that reaches a document the caller can't change is refused as a whole, and a delete removes at most 100,000 documents and files (413 too_many).
  • Folder deletes. DELETE /{tessellation}/_folders/{folder}?recursive=true deletes a folder of files and everything below it as one restorable batch.
  • CLI. hexdb rm deletes by ID, filter or folder: it always shows what would go and asks (you type the tessellation's name for everything or more than 100 documents), needs --yes without a terminal, and prints how to undo it. hexdb deletes list|show|restore|purge and hexdb trash.
  • Admin UI. Delete matching on the Documents page, with a preview and Undo; a Deletes page with the history, Restore and Purge; Delete folder on the Files page; parent links in the schema editor.
  • Audit. Deletes of more than one document (by filter, folders, cascades, transactions), restores and purges are in the audit trail (data.delete.*, data.restore, data.purge).
  • deletes is now a reserved tessellation name.

Upgrading

Restart the hexes one at a time, as usual: replicas first, the Overseer last. Before upgrading, check that nothing sends _update (or updateDocuments, or updateWhere) without a filter; give those calls all: true. Deleted documents take disk space while they're in the trash; set storage.trash_days lower (or 0 to keep none) if that matters.

Full Changelog: v2.4.1...v2.4.2