putMany method

List<int> putMany (
  1. List<T> objects,
  2. {_PutMode mode: _PutMode.Put}
)

Puts the given objects into this Box in a single transaction. Returns a list of all IDs of the inserted Objects.

Implementation

List<int> putMany(List<T> objects, {_PutMode mode = _PutMode.Put}) {
  if (objects.isEmpty) return [];

  // read all property values and find number of instances where ID is missing
  var allPropVals = objects.map(_entityReader).toList();
  var missingIdsCount = 0;
  for (var instPropVals in allPropVals) {
    if (instPropVals[_modelEntity.idProperty.name] == null ||
        instPropVals[_modelEntity.idProperty.name] == 0) {
      ++missingIdsCount;
    }
  }

  // generate new IDs for these instances and set them
  if (missingIdsCount != 0) {
    var nextId = 0;
    final nextIdPtr = allocate<Uint64>(count: 1);
    try {
      checkObx(
          bindings.obx_box_ids_for_put(_cBox, missingIdsCount, nextIdPtr));
      nextId = nextIdPtr.value;
    } finally {
      free(nextIdPtr);
    }
    for (var instPropVals in allPropVals) {
      if (instPropVals[_modelEntity.idProperty.name] == null ||
          instPropVals[_modelEntity.idProperty.name] == 0) {
        instPropVals[_modelEntity.idProperty.name] = nextId++;
      }
    }
  }

  // because obx_box_put_many also needs a list of all IDs of the elements to be put into the box,
  // generate this list now (only needed if not all IDs have been generated)
  final allIdsMemory = allocate<Uint64>(count: objects.length);
  try {
    for (var i = 0; i < allPropVals.length; ++i) {
      allIdsMemory[i] = (allPropVals[i][_modelEntity.idProperty.name] as int);
    }

    // marshal all objects to be put into the box
    final bytesArrayPtr = checkObxPtr(
        bindings.obx_bytes_array(allPropVals.length),
        'could not create OBX_bytes_array');
    final listToFree = <Pointer<OBX_bytes>>[];
    try {
      for (var i = 0; i < allPropVals.length; i++) {
        final bytesPtr = _fbManager.marshal(allPropVals[i]);
        listToFree.add(bytesPtr);
        final bytes = bytesPtr.ref;
        bindings.obx_bytes_array_set(
            bytesArrayPtr, i, bytes.ptr, bytes.length);
      }

      checkObx(bindings.obx_box_put_many(
          _cBox, bytesArrayPtr, allIdsMemory, _getOBXPutMode(mode)));
    } finally {
      bindings.obx_bytes_array_free(bytesArrayPtr);
      listToFree.forEach(OBX_bytes.freeManaged);
    }
  } finally {
    free(allIdsMemory);
  }

  return allPropVals
      .map((p) => p[_modelEntity.idProperty.name] as int)
      .toList();
}