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);
|
try builder.array.append(0);
|
||||||
|
|
||||||
var results = try db.queryWithOptions(
|
var results = try db.queryRowsWithOptions(
|
||||||
Community,
|
Community,
|
||||||
std.meta.assumeSentinel(builder.array.items, 0),
|
std.meta.assumeSentinel(builder.array.items, 0),
|
||||||
query_args,
|
query_args,
|
||||||
|
max_items,
|
||||||
.{ .prep_allocator = alloc, .ignore_unused_arguments = true },
|
.{ .prep_allocator = alloc, .ignore_unused_arguments = true },
|
||||||
);
|
);
|
||||||
defer results.finish();
|
errdefer util.deepFree(alloc, results);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
var next_page = args;
|
var next_page = args;
|
||||||
var prev_page = args;
|
var prev_page = args;
|
||||||
prev_page.page_direction = .backward;
|
prev_page.page_direction = .backward;
|
||||||
next_page.page_direction = .forward;
|
next_page.page_direction = .forward;
|
||||||
if (count != 0) {
|
if (results.len != 0) {
|
||||||
prev_page.prev = .{
|
prev_page.prev = .{
|
||||||
.id = result_buf[0].id,
|
.id = results[0].id,
|
||||||
.order_val = getOrderVal(result_buf[0], args.order_by),
|
.order_val = getOrderVal(results[0], args.order_by),
|
||||||
};
|
};
|
||||||
|
|
||||||
next_page.prev = .{
|
next_page.prev = .{
|
||||||
.id = result_buf[count - 1].id,
|
.id = results[results.len - 1].id,
|
||||||
.order_val = getOrderVal(result_buf[count - 1], args.order_by),
|
.order_val = getOrderVal(results[results.len - 1], args.order_by),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// TODO: This will give incorrect links on an empty page
|
// TODO: This will give incorrect links on an empty page
|
||||||
|
|
||||||
return QueryResult{
|
return QueryResult{
|
||||||
.items = result_buf[0..count],
|
.items = results,
|
||||||
|
|
||||||
.next_page = next_page,
|
.next_page = next_page,
|
||||||
.prev_page = prev_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,
|
Note,
|
||||||
try builder.terminate(),
|
try builder.terminate(),
|
||||||
query_args,
|
query_args,
|
||||||
|
max_items,
|
||||||
.{ .prep_allocator = alloc, .ignore_unused_arguments = true },
|
.{ .prep_allocator = alloc, .ignore_unused_arguments = true },
|
||||||
);
|
);
|
||||||
defer results.finish();
|
errdefer util.deepFree(results);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
var next_page = args;
|
var next_page = args;
|
||||||
var prev_page = args;
|
var prev_page = args;
|
||||||
prev_page.page_direction = .backward;
|
prev_page.page_direction = .backward;
|
||||||
next_page.page_direction = .forward;
|
next_page.page_direction = .forward;
|
||||||
if (count != 0) {
|
if (results.len != 0) {
|
||||||
prev_page.prev = .{
|
prev_page.prev = .{
|
||||||
.id = result_buf[0].id,
|
.id = results[0].id,
|
||||||
.created_at = result_buf[0].created_at,
|
.created_at = results[0].created_at,
|
||||||
};
|
};
|
||||||
|
|
||||||
next_page.prev = .{
|
next_page.prev = .{
|
||||||
.id = result_buf[count - 1].id,
|
.id = results[results.len - 1].id,
|
||||||
.created_at = result_buf[count - 1].created_at,
|
.created_at = results[results.len - 1].created_at,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// TODO: this will give incorrect links on an empty page
|
// TODO: this will give incorrect links on an empty page
|
||||||
|
|
||||||
return QueryResult{
|
return QueryResult{
|
||||||
.items = result_buf[0..count],
|
.items = results,
|
||||||
.next_page = next_page,
|
.next_page = next_page,
|
||||||
.prev_page = prev_page,
|
.prev_page = prev_page,
|
||||||
};
|
};
|
||||||
|
|
|
@ -487,6 +487,45 @@ fn Tx(comptime tx_level: u8) type {
|
||||||
return row;
|
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
|
// Inserts a single value into a table
|
||||||
pub fn insert(
|
pub fn insert(
|
||||||
self: Self,
|
self: Self,
|
||||||
|
|
Loading…
Reference in a new issue