Return next set of query arguments

This commit is contained in:
jaina heartles 2022-10-10 22:19:58 -07:00
parent 195b201564
commit 37e0192c4f
3 changed files with 45 additions and 5 deletions

View file

@ -54,6 +54,7 @@ pub const NoteResponse = struct {
};
pub const CommunityQueryArgs = services.communities.QueryArgs;
pub const CommunityQueryResult = services.communities.QueryResult;
pub fn isAdminSetup(db: sql.Db) !bool {
_ = services.communities.adminCommunityId(db) catch |err| switch (err) {
@ -339,9 +340,9 @@ fn ApiConn(comptime DbConn: type) type {
};
}
pub fn queryCommunities(self: *Self, args: services.communities.QueryArgs) ![]services.communities.Community {
pub fn queryCommunities(self: *Self, args: services.communities.QueryArgs) !CommunityQueryResult {
if (!self.isAdmin()) return error.PermissionDenied;
return services.communities.query(self.db, args, self.arena.allocator());
return try services.communities.query(self.db, args, self.arena.allocator());
}
};
}

View file

@ -168,6 +168,7 @@ pub const QueryArgs = struct {
};
pub const Prev = std.meta.Child(std.meta.fieldInfo(QueryArgs, .prev).field_type);
pub const OrderVal = std.meta.fieldInfo(Prev, .order_val).field_type;
// Max items to fetch
max_items: usize = 20,
@ -203,6 +204,13 @@ pub const QueryArgs = struct {
page_direction: PageDirection = .forward,
};
pub const QueryResult = struct {
items: []const Community,
prev_page: QueryArgs,
next_page: QueryArgs,
};
const QueryBuilder = struct {
array: std.ArrayList(u8),
where_clauses_appended: usize = 0,
@ -237,7 +245,7 @@ pub const QueryError = error{
// Retrieves up to `args.max_items` Community entries matching the given query
// arguments.
// `args.max_items` is only a request, and fewer entries may be returned.
pub fn query(db: anytype, args: QueryArgs, alloc: std.mem.Allocator) ![]Community {
pub fn query(db: anytype, args: QueryArgs, alloc: std.mem.Allocator) !QueryResult {
var builder = QueryBuilder.init(alloc);
defer builder.deinit();
@ -318,7 +326,38 @@ pub fn query(db: anytype, args: QueryArgs, alloc: std.mem.Allocator) ![]Communit
count += 1;
}
return result_buf[0..count];
var next_page = args;
var prev_page = args;
prev_page.page_direction = .backward;
next_page.page_direction = .forward;
if (count != 0) {
prev_page.prev = .{
.id = result_buf[0].id,
.order_val = getOrderVal(result_buf[0], args.order_by),
};
next_page.prev = .{
.id = result_buf[count - 1].id,
.order_val = getOrderVal(result_buf[count - 1], args.order_by),
};
} else {
prev_page.prev = null;
}
return QueryResult{
.items = result_buf[0..count],
.next_page = next_page,
.prev_page = prev_page,
};
}
fn getOrderVal(community: Community, order_val: QueryArgs.OrderBy) QueryArgs.OrderVal {
return switch (order_val) {
.name => .{ .name = community.name },
.host => .{ .host = community.host },
.created_at => .{ .created_at = community.created_at },
};
}
pub fn adminCommunityId(db: anytype) !Uuid {

View file

@ -76,7 +76,7 @@ pub fn isAfter(lhs: DateTime, rhs: DateTime) bool {
}
pub fn epochSeconds(value: DateTime) std.time.epoch.EpochSeconds {
return .{ .secs = @intCast(u64, value.seconds_since_epoch) };
return .{ .secs = std.math.cast(u64, value.seconds_since_epoch) orelse 0 };
}
pub fn year(value: DateTime) std.time.epoch.Year {