setArrayValue method

void setArrayValue(
  1. int index,
  2. dynamic value
)

Set a value at a specific position in the array

The data buffer was allocated by ODPI-C during variable creation and is accessed directly using pointer arithmetic. For string/bytes data, dpiVar_setFromBytes is used to properly copy data for batch operations.

Implementation

void setArrayValue(int index, dynamic value) {
  _ensureNotDisposed();

  if (index < 0 || index >= _arraySize) {
    throw OracleException(
      'Index $index out of bounds (array size: $_arraySize)',
    );
  }

  // For string/bytes types, use dpiVar_setFromBytes for proper batch support
  if (_nativeType == DPI_NATIVE_TYPE_BYTES) {
    if (value == null) {
      // For null values, use dpiVar_setFromBytes with null/0
      _dpiOracle.dpiVar_setFromBytes(_varPtr.value, index, nullptr, 0);
    } else if (value is String) {
      final (bytes, byteLength) = StringUtils.toNativeUtf8WithLength(value, _memoryManager);
      final result = _dpiOracle.dpiVar_setFromBytes(_varPtr.value, index, bytes, byteLength);
      if (result == DPI_FAILURE) {
        throw OracleException('Failed to set bytes value at index $index');
      }
    } else {
      throw OracleException('Expected String for BYTES type, got ${value.runtimeType}');
    }
  } else {
    // Access the data element at the specified index
    // The data buffer is an array of dpiData structures allocated by ODPI-C
    final data = Pointer<dpiData>.fromAddress(
      _dataPtr.address + index * sizeOf<dpiData>(),
    );

    // Set the value based on native type
    _setDataValue(data, value);
  }

  // Update the number of elements in the array
  // This tells ODPI-C how many values are valid
  final currentMax = index + 1;
  _dpiOracle.dpiVar_setNumElementsInArray(_varPtr.value, currentMax);
}