update method
Replace an existing row. Throws if the PK doesn't exist. The
primary-key value in row must equal pkVal (we don't allow
PK rewrites here — do delete + insert if you need that).
Implementation
Future<void> update(Object pkVal, Map<String, Object?> row) async {
final pkBytes = _encodePrimaryKey(pkVal);
final rowId = await _index.get(pkBytes);
if (rowId == null) {
throw StateError(
'PagedTable.update: no row with primary key ${jsonEncode(pkVal)}');
}
final newPk = row[primaryKey.name];
if (newPk == null) {
throw ArgumentError('PagedTable.update: primary-key value is null');
}
if (_compareBytes(_encodePrimaryKey(newPk), pkBytes) != 0) {
throw ArgumentError(
'PagedTable.update: cannot rewrite primary key (delete + insert instead)');
}
// Refresh secondary-index entries: compare the old vs new tuple
// of indexed-column values; only rewrite indexes whose tuple
// changed. NULL-containing tuples have no index entry.
if (_secondary.isNotEmpty) {
final oldBytes = await _heap.get(rowId);
if (oldBytes != null) {
final oldRow = _decodeRow(oldBytes);
// Uniqueness pre-check before any mutation.
for (final si in _secondary.values) {
if (!si.unique) continue;
final newPrefix = _encodeSecondaryPrefix(si, row);
if (newPrefix == null) continue;
final oldPrefix = _encodeSecondaryPrefix(si, oldRow);
if (oldPrefix != null && _compareBytes(oldPrefix, newPrefix) == 0) {
continue; // unchanged prefix, no conflict possible
}
if (await _uniqueConflict(si, newPrefix, pkBytes)) {
throw StateError('PagedTable.update: UNIQUE constraint violated on '
'index ${si.name} (${si.columns.join(", ")})');
}
}
for (final si in _secondary.values) {
final oldKey = _encodeSecondaryKey(si, oldRow, pkBytes);
final newKey = _encodeSecondaryKey(si, row, pkBytes);
if (oldKey == null && newKey == null) continue;
if (oldKey != null &&
newKey != null &&
_compareBytes(oldKey, newKey) == 0) {
continue;
}
if (oldKey != null) await si.btree.remove(oldKey);
if (newKey != null) await si.btree.put(newKey, rowId);
}
}
}
final rowBytes = _encodeRow(row);
await _heap.update(rowId, rowBytes);
}