bulkUpdate method

  1. @override
Future<bool> bulkUpdate(
  1. List<Map<String, dynamic>> updates, {
  2. required String matchColumn,
  3. List<String>? updateColumns,
  4. int batchSize = 500,
  5. Map<String, dynamic>? additionalValues,
})
inherited

Implementation

@override
Future<bool> bulkUpdate(
  List<Map<String, dynamic>> updates, {
  required String matchColumn,
  List<String>? updateColumns,
  int batchSize = 500,
  Map<String, dynamic>? additionalValues,
}) async {
  if (updates.isEmpty) {
    throw InvalidArgumentException(
        'Updates cannot be empty for bulk update operation');
  }

  try {
    final conn = await getConnection();

    for (int i = 0; i < updates.length; i += batchSize) {
      final batch = updates.skip(i).take(batchSize).toList();

      final columns = updateColumns ??
          batch.first.keys.where((key) => key != matchColumn).toList();
      final paramBindings = <String, dynamic>{};

      final matchValues = <String>[];
      final caseClauses = <String, List<String>>{};

      for (var column in columns) {
        caseClauses[column] = [];
      }

      for (var row in batch) {
        final matchParamName = _nextParamName();
        paramBindings[matchParamName] = row[matchColumn];
        matchValues.add(":$matchParamName");

        for (var column in columns) {
          final valueParamName = _nextParamName();
          paramBindings[valueParamName] = row[column];
          caseClauses[column]!
              .add("WHEN :$matchParamName THEN :$valueParamName");
        }
      }

      final setClauses = caseClauses.entries.map((entry) {
        final caseStatement =
            "CASE $matchColumn ${entry.value.join(' ')} END";
        return "${entry.key} = $caseStatement";
      }).toList();

      if (additionalValues != null) {
        for (var entry in additionalValues.entries) {
          final paramName = _nextParamName();
          paramBindings[paramName] = entry.value;
          setClauses.add("${entry.key} = :$paramName");
        }
      }

      final sql =
          "UPDATE $getTable SET ${setClauses.join(', ')} WHERE $matchColumn IN (${matchValues.join(', ')})";

      await conn.execute(sql, paramBindings);
    }

    return true;
  } catch (e) {
    rethrow;
  }
}