generateUpdateSQL method

FutureOr<SQL> generateUpdateSQL(
  1. Transaction transaction,
  2. String entityName,
  3. String table,
  4. Object id,
  5. Map<String, Object?> fields,
)

Implementation

FutureOr<SQL> generateUpdateSQL(
  Transaction transaction,
  String entityName,
  String table,
  Object id,
  Map<String, Object?> fields,
) {
  if (fields.isEmpty) return SQL.dummy;

  var retTableScheme = getTableScheme(table);

  return retTableScheme.resolveMapped((tableScheme) {
    if (tableScheme == null) {
      var errorMsg = "Can't find `TableScheme` for table: $table";
      _log.severe(errorMsg);
      throw StateError(errorMsg);
    }

    var context = EncodingContext(
      entityName,
      namedParameters: fields,
      transaction: transaction,
      tableFieldID: tableScheme.idFieldName,
    );

    var idFieldName = tableScheme.idFieldName!;
    var idPlaceholder = _conditionSQLGenerator.parameterPlaceholder(
      idFieldName,
    );

    var fieldsValues = tableScheme.getFieldsValues(
      fields,
      fields: fields.keys.toSet(),
    );

    // No value to update:
    if (fieldsValues.isEmpty) {
      return SQL.dummy;
    }

    var fieldsKeys = fieldsValues.keys.toList();

    var fieldsValuesInSQL = <String, Object?>{idFieldName: id};

    return fieldsKeys
        .map(
          (f) => fieldValueToSQL(
            context,
            tableScheme,
            f,
            fieldsValues[f],
            fieldsValuesInSQL,
          ),
        )
        .toList(growable: false)
        .resolveAll()
        .resolveMapped((values) {
          var q = dialect.elementQuote;
          var sql = StringBuffer();

          sql.write('UPDATE $q');
          sql.write(table);
          sql.write('$q SET ');

          for (var i = 0; i < values.length; ++i) {
            var f = fieldsKeys[i];
            var v = values[i];

            if (i > 0) sql.write(' , ');
            sql.write(q);
            sql.write(f);
            sql.write(q);
            sql.write(' = ');
            sql.write(v);
          }

          if (dialect.acceptsOutputSyntax) {
            sql.write(' OUTPUT INSERTED.');
            sql.write(q);
            sql.write(idFieldName);
            sql.write(q);
          }

          sql.write(' WHERE ');

          var conditionSQL = '$idFieldName = $idPlaceholder';
          sql.write(conditionSQL);

          if (dialect.acceptsReturningSyntax) {
            sql.write(' RETURNING $q$table$q.$q$idFieldName$q');
          }

          return SQL(
            sql.toString(),
            null,
            fields,
            fieldsValuesInSQL,
            sqlCondition: conditionSQL,
            entityName: table,
            idFieldName: idFieldName,
            mainTable: table,
          );
        });
  });
}