insert method

Future<void> insert(
  1. Map<String, Object?> row
)

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);
  }
}