insert method
Insert a row. The map's keys must be a subset of the column names; missing columns are stored as NULL. Throws if a row with the same PK already exists.
Implementation
Future<void> insert(Map<String, Object?> row) async {
final pkVal = row[primaryKey.name];
if (pkVal == null) {
throw ArgumentError('PagedTable.insert: primary-key value is null');
}
final pkBytes = _encodePrimaryKey(pkVal);
if ((await _index.get(pkBytes)) != null) {
throw StateError(
'PagedTable.insert: duplicate primary key ${jsonEncode(pkVal)}');
}
// Uniqueness pre-check on every UNIQUE secondary index.
for (final si in _secondary.values) {
if (!si.unique) continue;
final prefix = _encodeSecondaryPrefix(si, row);
if (prefix == null) continue; // NULL components don't constrain
if (await _uniqueConflict(si, prefix, null)) {
throw StateError('PagedTable.insert: UNIQUE constraint violated on '
'index ${si.name} (${si.columns.join(", ")})');
}
}
final rowBytes = _encodeRow(row);
final rowId = await _heap.insert(rowBytes);
await _index.put(pkBytes, rowId);
// Maintain every secondary index. Composite indexes are skipped
// entirely when ANY component is NULL (SQL-ish: NULLs don't index).
for (final si in _secondary.values) {
final key = _encodeSecondaryKey(si, row, pkBytes);
if (key == null) continue;
await si.btree.put(key, rowId);
}
}