Osy#betaRun it on Osyrin: osyrin.com

Reference / Storage

File.WriteAllBytes(..., about: row)

File.WriteAllBytes(path, bytes, about: row) · File.WriteAllText(path, text, about: row) · File.About(row) · File.DeleteAbout(row)

Write a file by path ABOUT a row — a receipt for an order, a label for a shipment — and the row finds it again: File.About(row) lists its files, File.DeleteAbout(row) deletes them, and deleting or restricting the row takes its files with it. A path-written file with no `about:` is tied to nothing, and no erasure can ever find it.

preview2 examples compiled by CIstoragefilesprivacyerasure

Summary#

A file written by path — receipts/{order.Id}.pdf — is just bytes at an address. Written with about: order, it is also recorded against the order, so everything that later has to reach "every copy of this person's data" can:

Signature#

bool         File.WriteAllBytes(string path, byte[] bytes, about: row)
bool         File.WriteAllText(string path, string text, about: row)
List<string> File.About(row)
int          File.DeleteAbout(row)

Description#

Needs use Osysharp.Storage; (the register lives there). about: takes a stored row of any entity; writing the same path about the same row twice records it once. A restricted row's renderings are deleted rather than kept: a purpose read renders them again when the purpose needs them.

If a file cannot be deleted when its row goes, its register entry stays — so File.About and Assert.NoTraceOf (Assert.NoTraceOf(token)) still find it, rather than the copy silently surviving.

Examples#

app Shop { use Osysharp.Storage; }

entity Order {
  [Required, MaxLength(20)] string Number;
  [MaxLength(200)] string? Buyer;
  security { allow read, create, update, delete when IsAuthenticated || IsAnonymous; }
}

string WriteReceipt(Order o) {
  var path = $"receipts/{o.Number}.txt";
  File.WriteAllText(path, "Receipt for " + o.Buyer, about: o);
  return path;
}
[Test]
void A_receipt_goes_with_its_order() {
  var o = new Order { Number = "O-1", Buyer = "Ann" };
  UnitOfWork.Commit();
  var path = WriteReceipt(o);
  Assert.Equal(1, File.About(o).Count);
  o.Delete();
  UnitOfWork.Commit();
  Assert.False(File.Exists(path));
}

See also#

Related

Files (addressing something the app stores)

The platform stores a file two ways, and which one you hold decides how you address it. A PATH-keyed file lives at an…

restricted rows and purpose reads (Restriction, [PurposeRead])

Keep a row only for a stated purpose: Restriction.Restrict stamps it with a privacy category and the end of its period…

Assert.NoTraceOf(token)

The erasure oracle: the token is found nowhere the app keeps data — any column of any table (the audit trail, memory…