pubfnplace_bid(tx: *zyn.Database.Transaction, id: []constu8, bidder: []constu8, amount: u32) !bool {
// Acquire the lock before checking the deadline, including time spent waiting.
_ = (try tx.one(struct { id: []constu8 },
\\SELECT id FROM lots WHERE id = $1 FOR UPDATE
, .{id})) orelsereturnfalse;
return1 == try tx.exec_count(
\\UPDATE lots SET highest_bid = $1, bidder_id = $2\\WHERE id = $3 AND NOT closed\\AND closes_at > clock_timestamp() AND highest_bid < $1
, .{ @as(i64, amount), bidder, id });
}
After bidding £40 · preview
✦ Cabinet of Curiosities ✦
Haunted toaster
Two slices. Three shadows.
Your bid stands. For now.
Current bid£40
Close the auction
src/jobs.zig · close_lot
pubfnclose_lot(job: *zyn.Job, args: Args) !void {
var tx = try job.db.begin();
defer tx.cancel();
const lot = (try tx.one(struct { closed: bool },
\\SELECT closed FROM lots WHERE id = $1 FOR UPDATE
, .{args.lot_id})) orelsereturn;
if (lot.closed) return;
const winner = (try tx.one(struct { bidder_id: ?[]constu8 },
\\UPDATE lots SET closed = true\\WHERE id = $1 AND closes_at <= clock_timestamp()\\RETURNING bidder_id
, .{args.lot_id})) orelsereturnerror.AuctionStillOpen;
if (winner.bidder_id != null)
try tx.notifications.deliver_later("lot_won", .{ .lot_id = args.lot_id });
try tx.commit();
}