getObjects method Null safety

  1. @Operation()
Future<Response> getObjects(
  1. {@Bind("count") int count = 0,
  2. @Bind("offset") int offset = 0,
  3. @Bind("pageBy") String? pageBy,
  4. @Bind("pageAfter") String? pageAfter,
  5. @Bind("pagePrior") String? pagePrior,
  6. @Bind("sortBy") List<String>? sortBy}
)

Implementation

@Operation.get()
Future<Response> getObjects({
  /// Limits the number of objects returned.
  @Bind.query("count") int count = 0,

  /// An integer offset into an ordered list of objects.
  ///
  /// Use with count.
  ///
  /// See pageBy for an alternative form of offsetting.
  @Bind.query("offset") int offset = 0,

  /// The property of this object to page by.
  ///
  /// Must be a key in the object type being fetched. Must
  /// provide either pageAfter or pagePrior. Use with count.
  @Bind.query("pageBy") String? pageBy,

  /// A value-based offset into an ordered list of objects.
  ///
  /// Objects are returned if their
  /// value for the property named by pageBy is greater than
  /// the value of pageAfter. Must provide pageBy, and the type
  /// of the property designated by pageBy must be the same as pageAfter.
  @Bind.query("pageAfter") String? pageAfter,

  /// A value-based offset into an ordered list of objects.
  ///
  /// Objects are returned if their
  /// value for the property named by pageBy is less than
  /// the value of pageAfter. Must provide pageBy, and the type
  /// of the property designated by pageBy must be the same as pageAfter.
  @Bind.query("pagePrior") String? pagePrior,

  /// Designates a sorting strategy for the returned objects.
  ///
  /// This value must take the form 'name,asc' or 'name,desc', where name
  /// is the property of the returned objects to sort on.
  @Bind.query("sortBy") List<String>? sortBy,
}) async {
  _query!.fetchLimit = count;
  _query!.offset = offset;

  if (pageBy != null) {
    QuerySortOrder direction;
    String pageValue;
    if (pageAfter != null) {
      direction = QuerySortOrder.ascending;
      pageValue = pageAfter;
    } else if (pagePrior != null) {
      direction = QuerySortOrder.descending;
      pageValue = pagePrior;
    } else {
      return Response.badRequest(
        body: {
          "error":
              "missing required parameter 'pageAfter' or 'pagePrior' when 'pageBy' is given"
        },
      );
    }

    final pageByProperty = _query!.entity.properties[pageBy];
    if (pageByProperty == null) {
      throw Response.badRequest(body: {"error": "cannot page by '$pageBy'"});
    }

    final parsed = _parseValueForProperty(pageValue, pageByProperty);
    _query!.pageBy(
      (t) => t[pageBy],
      direction,
      boundingValue: parsed == "null" ? null : parsed,
    );
  }

  if (sortBy != null) {
    for (final sort in sortBy) {
      final split = sort.split(",").map((str) => str.trim()).toList();
      if (split.length != 2) {
        throw Response.badRequest(
          body: {
            "error":
                "invalid 'sortyBy' format. syntax: 'name,asc' or 'name,desc'."
          },
        );
      }
      if (_query!.entity.properties[split.first] == null) {
        throw Response.badRequest(
          body: {"error": "cannot sort by '$sortBy'"},
        );
      }
      if (split.last != "asc" && split.last != "desc") {
        throw Response.badRequest(
          body: {
            "error":
                "invalid 'sortBy' format. syntax: 'name,asc' or 'name,desc'."
          },
        );
      }
      final sortOrder = split.last == "asc"
          ? QuerySortOrder.ascending
          : QuerySortOrder.descending;
      _query!.sortBy((t) => t[split.first], sortOrder);
    }
  }

  _query = await willFindObjectsWithQuery(_query);

  final results = (await _query?.fetch())!;

  return didFindObjects(results);
}