Relatude Help

17 Uploading files

Insert the node first: an upload writes to a stored node. It stores the bytes and sets the FileValue on the node, so no Update is needed afterwards.

// from a local path
await db.FileUploadAsync<IVenue>(venue, v => v.Photo, @"/tmp/sentrum.jpg");

// from a stream or a byte array
await db.FileUploadAsync<IVenue>(venue, v => v.Photo, stream, "sentrum.jpg");
await db.FileUploadAsync<IVenue>(venue, v => v.Photo, bytes, "sentrum.jpg");

// into a FileValue you already hold
await db.FileUploadAsync(venue.Photo, @"/tmp/sentrum.jpg");

// take the file out of the property
await db.FileDeleteAsync<IVenue>(venue, v => v.Photo);

Only uploads and copies put a file into a property. A FileValue written with Update or a transaction can remove the file (FileValue.Empty) or change its name and meta data, but cannot point at another stored file. So b.Photo = a.Photo copies nothing: use FileCopyAsync. And a node object read before an upload, then written back, keeps the uploaded file.

FileDeleteAsync takes the file out of the property. The bytes stay in the store until the job delete-unreferenced-files finds nothing pointing at them, as revisions of a node can share a file.

  • Copying files — A copy gets the source's file with its name and meta data. When the file store keeps one copy per content (SameHashSameFile, §12.1), the two share the stored file and no bytes move. The result lists the new values in…
  • Very large files — Where the file store supports it, files too large for one request go up in chunks: start the upload, append the chunks, finalize.
  • Serving and converting — GetUrl with an adjustment gives the URL of a variant of a file: resized, cropped or in another format. The middleware that answers these URLs is in chapter 18.
  • Light and dark mode — A diagram drawn on white becomes a bright slab in a dark theme. InvertLuminance turns light into dark and dark into light, but keeps the hues: the blue bars below are still blue.