lookupIn method

Future<LookupInResult> lookupIn(
  1. String key,
  2. List<LookupInSpec> specs, [
  3. LookupInOptions? options
])

Performs a Lookup-In operation against a document, fetching individual fields or information about specific fields inside the document value.

key is the key of the document to look in.

specs is a list of LookupInSpecs describing the data to fetch from the document.

Implementation

Future<LookupInResult> lookupIn(
  String key,
  List<LookupInSpec> specs, [
  LookupInOptions? options,
]) async {
  options ??= const LookupInOptions();

  if (specs.isEmpty) {
    throw ArgumentError.value(
      specs,
      'specs',
      'must not be empty',
    );
  }

  final response = await _connection.lookupIn(
    LookupInRequest(
      id: _documentId(key),
      partition: 0,
      opaque: 0,
      accessDeleted: false,
      specs: List.generate(
        specs.length,
        (index) => specs[index].toMessage(index),
      ),
      timeout: _nonMutationTimeout(options),
    ),
  );

  final content = response.fields.map((field) {
    var error = field.ec.code != 0 ? convertMessageError(field.ec) : null;
    Object? value;

    if (field.opcode == SubdocOpcode.exists) {
      error = null;
      value = field.exists;
    } else if (error == null) {
      if (field.path == '') {
        // For an empty path, the value is the entire document.
        // We return it as raw bytes, allowing later stages to decode it.
        value = field.value;
      } else {
        value = _decodeSubDocumentValue(field.value);

        if (field.path == LookupInMacro.expiry.path) {
          final integerValue = value! as int;
          if (integerValue != 0) {
            value = DateTime.fromMillisecondsSinceEpoch(integerValue * 1000);
          } else {
            value = null;
          }
        } else if (field.path == LookupInMacro.lastModified.path) {
          final integerValue = int.parse(value! as String);
          value = DateTime.fromMillisecondsSinceEpoch(integerValue * 1000);
        } else if (field.path == LookupInMacro.cas.path) {
          // Comes from the C++ client as a hex string.
          value = Cas.parse(value! as String);
        }
      }
    }

    return LookupInResultEntry(error: error, value: value);
  }).toList();

  return LookupInResult(
    content: content,
    cas: response.cas,
  );
}