Merge pull request #130 from jetzig-framework/per-request-database-connection

Per-request database connection
This commit is contained in:
bobf 2024-11-30 12:58:57 +00:00 committed by GitHub
commit 7b03850593
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 60 additions and 26 deletions

View File

@ -15,8 +15,8 @@
.hash = "12201d75d73aad5e1c996de4d5ae87a00e58479c8d469bc2eeb5fdeeac8857bc09af", .hash = "12201d75d73aad5e1c996de4d5ae87a00e58479c8d469bc2eeb5fdeeac8857bc09af",
}, },
.jetquery = .{ .jetquery = .{
.url = "https://github.com/jetzig-framework/jetquery/archive/f520d4bb3f7099f8d670926328c93efd8849c3cc.tar.gz", .url = "https://github.com/jetzig-framework/jetquery/archive/52e1cf900c94f3c103727ade6ba2dab3057c8663.tar.gz",
.hash = "1220021eb5c36e78c1aafbf04a303433deb9fcb7edf29d8686b3bb33881884f2d23b", .hash = "12208a37407d1a7548fd7e81d9f6a9d4897793918023ed559a279a7647dab2d43145",
}, },
.jetcommon = .{ .jetcommon = .{
.url = "https://github.com/jetzig-framework/jetcommon/archive/86f24cfdf2aaa0e8ada4539a6edef882708ced2b.tar.gz", .url = "https://github.com/jetzig-framework/jetcommon/archive/86f24cfdf2aaa0e8ada4539a6edef882708ced2b.tar.gz",
@ -27,8 +27,8 @@
.hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c", .hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c",
}, },
.pg = .{ .pg = .{
.url = "https://github.com/karlseguin/pg.zig/archive/f376f4b30c63f1fdf90bc3afe246d3bc4175cd46.tar.gz", .url = "https://github.com/karlseguin/pg.zig/archive/0bfc46029c6a3e8ded7a3e0544fcbcb5baba2208.tar.gz",
.hash = "12200a55304988e942015b6244570b2dc0e87e5764719c9e7d5c812cd7ad34f6b138", .hash = "1220fb3f43073a6f9f201764c3ae78aa87b29edbc7b021c1174b29b020967d0b146c",
}, },
.smtp_client = .{ .smtp_client = .{
.url = "https://github.com/karlseguin/smtp_client.zig/archive/3cbe8f269e4c3a6bce407e7ae48b2c76307c559f.tar.gz", .url = "https://github.com/karlseguin/smtp_client.zig/archive/3cbe8f269e4c3a6bce407e7ae48b2c76307c559f.tar.gz",

View File

@ -9,8 +9,8 @@
.hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c", .hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c",
}, },
.jetquery = .{ .jetquery = .{
.url = "https://github.com/jetzig-framework/jetquery/archive/f520d4bb3f7099f8d670926328c93efd8849c3cc.tar.gz", .url = "https://github.com/jetzig-framework/jetquery/archive/52e1cf900c94f3c103727ade6ba2dab3057c8663.tar.gz",
.hash = "1220021eb5c36e78c1aafbf04a303433deb9fcb7edf29d8686b3bb33881884f2d23b", .hash = "12208a37407d1a7548fd7e81d9f6a9d4897793918023ed559a279a7647dab2d43145",
}, },
}, },
.paths = .{ .paths = .{

View File

@ -24,9 +24,10 @@ pub fn main() !void {
.get => jetzig.colors.cyan("{s: <7}"), .get => jetzig.colors.cyan("{s: <7}"),
.index => jetzig.colors.blue("{s: <7}"), .index => jetzig.colors.blue("{s: <7}"),
.new => jetzig.colors.green("{s: <7}"), .new => jetzig.colors.green("{s: <7}"),
.edit => jetzig.colors.bold(.yellow, "{s: <7}"),
.post => jetzig.colors.yellow("{s: <7}"), .post => jetzig.colors.yellow("{s: <7}"),
.put => jetzig.colors.magenta("{s: <7}"), .put => jetzig.colors.magenta("{s: <7}"),
.patch => jetzig.colors.bright_magenta("{s: <7}"), .patch => jetzig.colors.bold(.magenta, "{s: <7}"),
.delete => jetzig.colors.red("{s: <7}"), .delete => jetzig.colors.red("{s: <7}"),
.custom => unreachable, .custom => unreachable,
}; };
@ -36,6 +37,7 @@ pub fn main() !void {
route.uri_path ++ switch (route.action) { route.uri_path ++ switch (route.action) {
.index, .post => "", .index, .post => "",
.new => "/new", .new => "/new",
.edit => "/:id/edit",
.get, .put, .patch, .delete => "/:id", .get, .put, .patch, .delete => "/:id",
.custom => "", .custom => "",
}, },
@ -54,7 +56,7 @@ pub fn main() !void {
for (jetzig_app.custom_routes.items) |route| { for (jetzig_app.custom_routes.items) |route| {
log( log(
" " ++ jetzig.colors.bold(jetzig.colors.white("{s: <7}")) ++ " " ++ padded_path ++ " {s}:{s}", " " ++ jetzig.colors.bold(.white, "{s: <7}") ++ " " ++ padded_path ++ " {s}:{s}",
.{ route.name, route.uri_path, route.view_name, route.name }, .{ route.name, route.uri_path, route.view_name, route.name },
); );
} }

View File

@ -5,6 +5,25 @@ const builtin = @import("builtin");
const types = @import("types.zig"); const types = @import("types.zig");
const jetzig = @import("../jetzig.zig"); const jetzig = @import("../jetzig.zig");
pub const Color = enum {
black,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
bright_black,
bright_red,
bright_green,
bright_yellow,
bright_blue,
bright_magenta,
bright_cyan,
bright_white,
};
// Must be consistent with `std.io.tty.Color` for Windows compatibility. // Must be consistent with `std.io.tty.Color` for Windows compatibility.
pub const codes = .{ pub const codes = .{
.escape = "\x1b[", .escape = "\x1b[",
@ -53,12 +72,7 @@ const ansi_colors = .{
.{ "2", .dim }, .{ "2", .dim },
.{ "0", .reset }, .{ "0", .reset },
}; };
pub const codes_map = if (@hasDecl(std, "ComptimeStringMap")) pub const codes_map = std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors);
std.ComptimeStringMap(std.io.tty.Color, ansi_colors)
else if (@hasDecl(std, "StaticStringMap"))
std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors)
else
unreachable;
// Map basic ANSI color codes to Windows TextAttribute colors // Map basic ANSI color codes to Windows TextAttribute colors
// used by std.os.windows.SetConsoleTextAttribute() // used by std.os.windows.SetConsoleTextAttribute()
@ -83,12 +97,7 @@ const windows_colors = .{
.{ "2", 7 }, .{ "2", 7 },
.{ "0", 7 }, .{ "0", 7 },
}; };
pub const windows_map = if (@hasDecl(std, "ComptimeStringMap")) pub const windows_map = std.StaticStringMap(u16).initComptime(windows_colors);
std.ComptimeStringMap(u16, windows_colors)
else if (@hasDecl(std, "StaticStringMap"))
std.StaticStringMap(u16).initComptime(windows_colors)
else
unreachable;
/// Colorize a log message. Note that we force `.escape_codes` when we are a TTY even on Windows. /// Colorize a log message. Note that we force `.escape_codes` when we are a TTY even on Windows.
/// `jetzig.loggers.LogQueue` parses the ANSI codes and uses `std.io.tty.Config.setColor` to /// `jetzig.loggers.LogQueue` parses the ANSI codes and uses `std.io.tty.Config.setColor` to
@ -122,8 +131,8 @@ fn runtimeWrap(allocator: std.mem.Allocator, attribute: []const u8, message: []c
); );
} }
pub fn bold(comptime message: []const u8) []const u8 { pub fn bold(comptime color: Color, comptime message: []const u8) []const u8 {
return codes.escape ++ codes.bold ++ message ++ codes.escape ++ codes.reset; return codes.escape ++ @field(codes, @tagName(color)) ++ codes.escape ++ codes.bold ++ message ++ codes.escape ++ codes.reset;
} }
pub fn black(comptime message: []const u8) []const u8 { pub fn black(comptime message: []const u8) []const u8 {

View File

@ -21,6 +21,7 @@ cache: *jetzig.kv.Store,
repo: *jetzig.database.Repo, repo: *jetzig.database.Repo,
global: *anyopaque, global: *anyopaque,
decoded_static_route_params: []*jetzig.data.Value = &.{}, decoded_static_route_params: []*jetzig.data.Value = &.{},
debug_mutex: std.Thread.Mutex = .{},
const Server = @This(); const Server = @This();
@ -92,6 +93,7 @@ pub fn listen(self: *Server) !void {
}, },
.request = .{ .request = .{
.max_multiform_count = jetzig.config.get(usize, "max_multipart_form_fields"), .max_multiform_count = jetzig.config.get(usize, "max_multipart_form_fields"),
.max_body_size = jetzig.config.get(usize, "max_bytes_request_body"),
}, },
}, },
Dispatcher{ .server = self }, Dispatcher{ .server = self },
@ -116,7 +118,11 @@ pub fn errorHandlerFn(self: *Server, request: *httpz.Request, response: *httpz.R
self.logger.ERROR("Encountered error: {s} {s}", .{ @errorName(err), request.url.raw }) catch {}; self.logger.ERROR("Encountered error: {s} {s}", .{ @errorName(err), request.url.raw }) catch {};
const stack = @errorReturnTrace(); const stack = @errorReturnTrace();
if (stack) |capture| self.logStackTrace(capture, request.arena) catch {}; if (stack) |capture| {
self.debug_mutex.lock();
defer self.debug_mutex.unlock();
self.logStackTrace(capture, request.arena) catch {};
}
response.body = "500 Internal Server Error"; response.body = "500 Internal Server Error";
} }
@ -128,6 +134,9 @@ pub fn processNextRequest(
) !void { ) !void {
const start_time = std.time.nanoTimestamp(); const start_time = std.time.nanoTimestamp();
var repo = try self.repo.bindConnect(.{ .allocator = httpz_response.arena });
defer repo.release();
var response = try jetzig.http.Response.init(httpz_response.arena, httpz_response); var response = try jetzig.http.Response.init(httpz_response.arena, httpz_response);
var request = try jetzig.http.Request.init( var request = try jetzig.http.Request.init(
httpz_response.arena, httpz_response.arena,
@ -136,7 +145,7 @@ pub fn processNextRequest(
httpz_request, httpz_request,
httpz_response, httpz_response,
&response, &response,
self.repo, &repo,
); );
try request.process(); try request.process();

View File

@ -166,9 +166,16 @@ const sql_tokens = .{
"VALUES", "VALUES",
}; };
const sql_statement_map = std.StaticStringMap(jetzig.colors.Color).initComptime(.{
.{ "SELECT", .blue },
.{ "DELETE", .red },
.{ "UPDATE", .yellow },
.{ "INSERT", .green },
});
fn printSql(self: *const DevelopmentLogger, sql: []const u8) !void { fn printSql(self: *const DevelopmentLogger, sql: []const u8) !void {
const string_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.green; const string_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.green;
const identifier_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.yellow; const identifier_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.white;
const reset_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.reset; const reset_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.reset;
var buf: [4096]u8 = undefined; var buf: [4096]u8 = undefined;
var stream = std.io.fixedBufferStream(&buf); var stream = std.io.fixedBufferStream(&buf);
@ -221,9 +228,16 @@ fn printSql(self: *const DevelopmentLogger, sql: []const u8) !void {
try writer.print("{c}", .{sql[index]}); try writer.print("{c}", .{sql[index]});
index += 1; index += 1;
} else { } else {
@setEvalBranchQuota(2000);
inline for (sql_tokens) |token| { inline for (sql_tokens) |token| {
if (std.mem.startsWith(u8, sql[index..], token)) { if (std.mem.startsWith(u8, sql[index..], token)) {
try writer.print(jetzig.colors.cyan(token), .{}); const formatted_token = if (sql_statement_map.get(token)) |color|
switch (color) {
inline else => |tag| jetzig.colors.bold(tag, token),
}
else
jetzig.colors.cyan(token);
try writer.print("{s}", .{formatted_token});
index += token.len; index += token.len;
break; break;
} }