build method

Uint8List build()

Builds the binary data buffer for bulk insert.

Validates that table name, columns, and at least one row are present. Returns a Uint8List containing the serialized bulk insert data.

Throws StateError if table name is empty, no columns are defined, no rows have been added, or a non-nullable column contains null.

Implementation

Uint8List build() {
  if (_table.isEmpty) {
    throw StateError('Table name required');
  }
  if (_columns.isEmpty) {
    throw StateError('At least one column required');
  }
  if (_rows.isEmpty) {
    throw StateError('At least one row required');
  }

  // Keep a final nullability check because addRow stores row references.
  // Caller code can still mutate rows after insertion.
  for (var c = 0; c < _columns.length; c++) {
    final spec = _columns[c];
    if (!spec.nullable) {
      for (var r = 0; r < _rows.length; r++) {
        final value = _rows[r][c];
        if (value == null) {
          _throwNullabilityError(spec.name, r + 1);
        }
      }
    }
  }

  final out = <int>[];
  final tableBytes = utf8.encode(_table);
  out
    ..addAll(_u32Le(tableBytes.length))
    ..addAll(tableBytes)
    ..addAll(_u32Le(_columns.length));

  for (final spec in _columns) {
    final nameBytes = utf8.encode(spec.name);
    out
      ..addAll(_u32Le(nameBytes.length))
      ..addAll(nameBytes)
      ..add(spec.tag)
      ..add(spec.nullable ? 1 : 0)
      ..addAll(_u32Le(spec.maxLen));
  }

  final rowCount = _rows.length;
  out.addAll(_u32Le(rowCount));

  for (var c = 0; c < _columns.length; c++) {
    final spec = _columns[c];
    _serializeColumn(out, spec, c, rowCount);
  }

  return Uint8List.fromList(out);
}