build method

Uint8List build({
  1. BulkPayloadVersion version = BulkPayloadVersion.v2,
})

Builds the binary data buffer for bulk insert.

Version BulkPayloadVersion.v2 is the default and preserves variable-width binary values, including embedded NUL bytes. Use BulkPayloadVersion.legacy only when talking to native engines that do not understand the versioned BLK2 payload.

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({BulkPayloadVersion version = BulkPayloadVersion.v2}) {
  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>[];
  if (version == BulkPayloadVersion.v2) {
    out
      ..addAll(_bulkPayloadV2Magic)
      ..addAll(_u16Le(_bulkPayloadV2Version))
      ..addAll(_u16Le(_bulkPayloadV2Flags));
  }

  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];
    if (version == BulkPayloadVersion.v2) {
      _serializeColumnV2(out, spec, c, rowCount);
    } else {
      _serializeColumnLegacy(out, spec, c, rowCount);
    }
  }

  return Uint8List.fromList(out);
}