put method
Stores bytes and returns the descriptor.
If sha256 is null the cache computes it from bytes; otherwise the
supplied value is used as-is and is not verified.
Putting the same key twice overwrites the previous bytes and refreshes the descriptor's BlobDescriptor.uploadedAt. Existing pins are kept.
When pinBy is set, the blob is pinned on behalf of that holder, as if
pin had been called with it.
Implementation
@override
Future<BlobDescriptor> put(
Uint8List bytes, {
String? sha256,
String? type,
String? pinBy,
}) async {
final key = sha256 ?? sha256Hex(bytes);
if (!_keyPattern.hasMatch(key)) {
throw ArgumentError.value(key, 'sha256', 'must be 64 lowercase hex');
}
final db = _required;
// Written aside then renamed, so a reader never sees a partial file.
final temp = File(p.join(_blobs.path, '$key.${_tempCount++}.tmp'));
try {
await temp.writeAsBytes(bytes, flush: true);
return await _serialized(() async {
await temp.rename(_blobFile(key).path);
return db.transaction((txn) async {
final record = _meta.record(key);
final previous = await record.get(txn);
final now = DateTime.now().toUtc();
final descriptor = BlobDescriptor(
sha256: key,
size: bytes.length,
type: type,
uploadedAt: now,
lastAccessedAt: now,
pinnedBy: {if (previous != null) ...holdersOf(previous), ?pinBy},
);
await record.put(txn, descriptorToRecord(descriptor));
return descriptor;
});
});
} finally {
await _deleteIfExists(temp);
}
}