Add queryRowsWithOptions method to db helper
This commit is contained in:
parent
83da3c914b
commit
139fc92854
3 changed files with 57 additions and 40 deletions
|
@ -281,45 +281,34 @@ pub fn query(db: anytype, args: QueryArgs, alloc: std.mem.Allocator) !QueryResul
|
|||
|
||||
try builder.array.append(0);
|
||||
|
||||
var results = try db.queryWithOptions(
|
||||
var results = try db.queryRowsWithOptions(
|
||||
Community,
|
||||
std.meta.assumeSentinel(builder.array.items, 0),
|
||||
query_args,
|
||||
max_items,
|
||||
.{ .prep_allocator = alloc, .ignore_unused_arguments = true },
|
||||
);
|
||||
defer results.finish();
|
||||
|
||||
const result_buf = try alloc.alloc(Community, args.max_items);
|
||||
errdefer alloc.free(result_buf);
|
||||
|
||||
var count: usize = 0;
|
||||
errdefer for (result_buf[0..count]) |c| util.deepFree(alloc, c);
|
||||
|
||||
for (result_buf) |*c| {
|
||||
c.* = (try results.row(alloc)) orelse break;
|
||||
|
||||
count += 1;
|
||||
}
|
||||
errdefer util.deepFree(alloc, results);
|
||||
|
||||
var next_page = args;
|
||||
var prev_page = args;
|
||||
prev_page.page_direction = .backward;
|
||||
next_page.page_direction = .forward;
|
||||
if (count != 0) {
|
||||
if (results.len != 0) {
|
||||
prev_page.prev = .{
|
||||
.id = result_buf[0].id,
|
||||
.order_val = getOrderVal(result_buf[0], args.order_by),
|
||||
.id = results[0].id,
|
||||
.order_val = getOrderVal(results[0], args.order_by),
|
||||
};
|
||||
|
||||
next_page.prev = .{
|
||||
.id = result_buf[count - 1].id,
|
||||
.order_val = getOrderVal(result_buf[count - 1], args.order_by),
|
||||
.id = results[results.len - 1].id,
|
||||
.order_val = getOrderVal(results[results.len - 1], args.order_by),
|
||||
};
|
||||
}
|
||||
// TODO: This will give incorrect links on an empty page
|
||||
|
||||
return QueryResult{
|
||||
.items = result_buf[0..count],
|
||||
.items = results,
|
||||
|
||||
.next_page = next_page,
|
||||
.prev_page = prev_page,
|
||||
|
|
|
@ -125,45 +125,34 @@ pub fn query(db: anytype, args: QueryArgs, alloc: std.mem.Allocator) !QueryResul
|
|||
};
|
||||
};
|
||||
|
||||
var results = try db.queryWithOptions(
|
||||
const results = try db.queryRowsWithOptions(
|
||||
Note,
|
||||
try builder.terminate(),
|
||||
query_args,
|
||||
max_items,
|
||||
.{ .prep_allocator = alloc, .ignore_unused_arguments = true },
|
||||
);
|
||||
defer results.finish();
|
||||
|
||||
const result_buf = try alloc.alloc(Note, args.max_items);
|
||||
errdefer alloc.free(result_buf);
|
||||
|
||||
var count: usize = 0;
|
||||
errdefer for (result_buf[0..count]) |c| util.deepFree(alloc, c);
|
||||
|
||||
for (result_buf) |*c| {
|
||||
c.* = (try results.row(alloc)) orelse break;
|
||||
|
||||
count += 1;
|
||||
}
|
||||
errdefer util.deepFree(results);
|
||||
|
||||
var next_page = args;
|
||||
var prev_page = args;
|
||||
prev_page.page_direction = .backward;
|
||||
next_page.page_direction = .forward;
|
||||
if (count != 0) {
|
||||
if (results.len != 0) {
|
||||
prev_page.prev = .{
|
||||
.id = result_buf[0].id,
|
||||
.created_at = result_buf[0].created_at,
|
||||
.id = results[0].id,
|
||||
.created_at = results[0].created_at,
|
||||
};
|
||||
|
||||
next_page.prev = .{
|
||||
.id = result_buf[count - 1].id,
|
||||
.created_at = result_buf[count - 1].created_at,
|
||||
.id = results[results.len - 1].id,
|
||||
.created_at = results[results.len - 1].created_at,
|
||||
};
|
||||
}
|
||||
// TODO: this will give incorrect links on an empty page
|
||||
|
||||
return QueryResult{
|
||||
.items = result_buf[0..count],
|
||||
.items = results,
|
||||
.next_page = next_page,
|
||||
.prev_page = prev_page,
|
||||
};
|
||||
|
|
|
@ -487,6 +487,45 @@ fn Tx(comptime tx_level: u8) type {
|
|||
return row;
|
||||
}
|
||||
|
||||
// Runs a query to completion and returns the results as a slice
|
||||
pub fn queryRowsWithOptions(
|
||||
self: Self,
|
||||
comptime RowType: type,
|
||||
q: [:0]const u8,
|
||||
args: anytype,
|
||||
max_items: ?usize,
|
||||
options: QueryOptions,
|
||||
) QueryRowError![]RowType {
|
||||
var results = try self.queryWithOptions(RowType, q, args, options);
|
||||
defer results.finish();
|
||||
|
||||
const alloc = options.prep_allocator orelse return error.AllocatorRequired;
|
||||
|
||||
var result_array = std.ArrayList(RowType).init(alloc);
|
||||
errdefer result_array.deinit();
|
||||
if (max_items) |max| try result_array.ensureTotalCapacity(max);
|
||||
|
||||
errdefer for (result_array.items) |r| util.deepFree(alloc, r);
|
||||
|
||||
var too_many: bool = false;
|
||||
while (try results.row(alloc)) |row| {
|
||||
errdefer util.deepFree(alloc, row);
|
||||
if (max_items) |max| {
|
||||
if (result_array.items.len >= max) {
|
||||
util.deepFree(alloc, row);
|
||||
too_many = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
try result_array.append(row);
|
||||
}
|
||||
|
||||
if (too_many) return error.TooManyRows;
|
||||
|
||||
return result_array.toOwnedSlice();
|
||||
}
|
||||
|
||||
// Inserts a single value into a table
|
||||
pub fn insert(
|
||||
self: Self,
|
||||
|
|
Loading…
Reference in a new issue