substitute static method

String substitute(
  1. String fmtString,
  2. Map<String, dynamic>? values, {
  3. SQLReplaceIdentifierFunction? replace,
})

Implementation

static String substitute(String fmtString, Map<String, dynamic>? values,
    {SQLReplaceIdentifierFunction? replace}) {
  if (values == null || values.isEmpty) return fmtString;
  final converter = PostgresTextEncoder();
  replace ??= (spec, index) => converter.convert(values![spec.name]);

  final items = <PostgreSQLFormatToken>[];
  PostgreSQLFormatToken? currentPtr;
  final iterator = RuneIterator(fmtString);

  PostgreSQLFormatToken startToken(
      PostgreSQLFormatTokenType type, int charCode) {
    final token = PostgreSQLFormatToken(type);
    token.buffer.writeCharCode(charCode);
    items.add(token);
    return token;
  }

  PostgreSQLFormatToken startVariable(int charCode) =>
      startToken(PostgreSQLFormatTokenType.variable, charCode);
  PostgreSQLFormatToken startText(int charCode) =>
      startToken(PostgreSQLFormatTokenType.text, charCode);

  while (iterator.moveNext()) {
    if (currentPtr == null) {
      final type = iterator.current == _atSignCodeUnit
          ? PostgreSQLFormatTokenType.variable
          : PostgreSQLFormatTokenType.text;
      currentPtr = startToken(type, iterator.current);
    } else if (currentPtr.type == PostgreSQLFormatTokenType.text) {
      if (iterator.current == _atSignCodeUnit) {
        currentPtr = startVariable(iterator.current);
      } else {
        currentPtr.buffer.writeCharCode(iterator.current);
      }
    } else if (currentPtr.type == PostgreSQLFormatTokenType.variable) {
      if (iterator.current == _atSignCodeUnit) {
        iterator.movePrevious();
        if (iterator.current == _atSignCodeUnit) {
          currentPtr.buffer.writeCharCode(iterator.current);
          currentPtr.type = PostgreSQLFormatTokenType.text;
        } else {
          currentPtr = startVariable(iterator.current);
        }
        iterator.moveNext();
      } else if (_isIdentifier(iterator.current)) {
        currentPtr.buffer.writeCharCode(iterator.current);
      } else {
        currentPtr = startText(iterator.current);
      }
    }
  }

  var idx = 1;
  return items.map((t) {
    if (t.type == PostgreSQLFormatTokenType.text) {
      return t.buffer;
    } else if (t.buffer.length == 1 && t.buffer.toString() == '@') {
      return t.buffer;
    } else {
      final identifier = PostgreSQLFormatIdentifier(t.buffer.toString());

      if (values != null && !values.containsKey(identifier.name)) {
        // Format string specified identifier with name ${identifier.name},
        // but key was not present in values.
        return t.buffer;
      }

      final val = replace!(identifier, idx);
      idx++;

      if (identifier.typeCast != null) {
        return '$val::${identifier.typeCast}';
      }

      return val;
    }
  }).join('');
}