diff --git a/build.zig.zon b/build.zig.zon index d2b36d8..fd0251e 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -15,8 +15,8 @@ .hash = "12201d75d73aad5e1c996de4d5ae87a00e58479c8d469bc2eeb5fdeeac8857bc09af", }, .jetquery = .{ - .url = "https://github.com/jetzig-framework/jetquery/archive/f520d4bb3f7099f8d670926328c93efd8849c3cc.tar.gz", - .hash = "1220021eb5c36e78c1aafbf04a303433deb9fcb7edf29d8686b3bb33881884f2d23b", + .url = "https://github.com/jetzig-framework/jetquery/archive/52e1cf900c94f3c103727ade6ba2dab3057c8663.tar.gz", + .hash = "12208a37407d1a7548fd7e81d9f6a9d4897793918023ed559a279a7647dab2d43145", }, .jetcommon = .{ .url = "https://github.com/jetzig-framework/jetcommon/archive/86f24cfdf2aaa0e8ada4539a6edef882708ced2b.tar.gz", @@ -27,8 +27,8 @@ .hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c", }, .pg = .{ - .url = "https://github.com/karlseguin/pg.zig/archive/f376f4b30c63f1fdf90bc3afe246d3bc4175cd46.tar.gz", - .hash = "12200a55304988e942015b6244570b2dc0e87e5764719c9e7d5c812cd7ad34f6b138", + .url = "https://github.com/karlseguin/pg.zig/archive/0bfc46029c6a3e8ded7a3e0544fcbcb5baba2208.tar.gz", + .hash = "1220fb3f43073a6f9f201764c3ae78aa87b29edbc7b021c1174b29b020967d0b146c", }, .smtp_client = .{ .url = "https://github.com/karlseguin/smtp_client.zig/archive/3cbe8f269e4c3a6bce407e7ae48b2c76307c559f.tar.gz", diff --git a/cli/build.zig.zon b/cli/build.zig.zon index ff86b95..c0ebfae 100644 --- a/cli/build.zig.zon +++ b/cli/build.zig.zon @@ -9,8 +9,8 @@ .hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c", }, .jetquery = .{ - .url = "https://github.com/jetzig-framework/jetquery/archive/f520d4bb3f7099f8d670926328c93efd8849c3cc.tar.gz", - .hash = "1220021eb5c36e78c1aafbf04a303433deb9fcb7edf29d8686b3bb33881884f2d23b", + .url = "https://github.com/jetzig-framework/jetquery/archive/52e1cf900c94f3c103727ade6ba2dab3057c8663.tar.gz", + .hash = "12208a37407d1a7548fd7e81d9f6a9d4897793918023ed559a279a7647dab2d43145", }, }, .paths = .{ diff --git a/src/commands/routes.zig b/src/commands/routes.zig index c70b79d..b966259 100644 --- a/src/commands/routes.zig +++ b/src/commands/routes.zig @@ -24,9 +24,10 @@ pub fn main() !void { .get => jetzig.colors.cyan("{s: <7}"), .index => jetzig.colors.blue("{s: <7}"), .new => jetzig.colors.green("{s: <7}"), + .edit => jetzig.colors.bold(.yellow, "{s: <7}"), .post => jetzig.colors.yellow("{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}"), .custom => unreachable, }; @@ -36,6 +37,7 @@ pub fn main() !void { route.uri_path ++ switch (route.action) { .index, .post => "", .new => "/new", + .edit => "/:id/edit", .get, .put, .patch, .delete => "/:id", .custom => "", }, @@ -54,7 +56,7 @@ pub fn main() !void { for (jetzig_app.custom_routes.items) |route| { 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 }, ); } diff --git a/src/jetzig/colors.zig b/src/jetzig/colors.zig index d62379e..4b1c2cb 100644 --- a/src/jetzig/colors.zig +++ b/src/jetzig/colors.zig @@ -5,6 +5,25 @@ const builtin = @import("builtin"); const types = @import("types.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. pub const codes = .{ .escape = "\x1b[", @@ -53,12 +72,7 @@ const ansi_colors = .{ .{ "2", .dim }, .{ "0", .reset }, }; -pub const codes_map = if (@hasDecl(std, "ComptimeStringMap")) - std.ComptimeStringMap(std.io.tty.Color, ansi_colors) -else if (@hasDecl(std, "StaticStringMap")) - std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors) -else - unreachable; +pub const codes_map = std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors); // Map basic ANSI color codes to Windows TextAttribute colors // used by std.os.windows.SetConsoleTextAttribute() @@ -83,12 +97,7 @@ const windows_colors = .{ .{ "2", 7 }, .{ "0", 7 }, }; -pub const windows_map = if (@hasDecl(std, "ComptimeStringMap")) - std.ComptimeStringMap(u16, windows_colors) -else if (@hasDecl(std, "StaticStringMap")) - std.StaticStringMap(u16).initComptime(windows_colors) -else - unreachable; +pub const windows_map = std.StaticStringMap(u16).initComptime(windows_colors); /// 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 @@ -122,8 +131,8 @@ fn runtimeWrap(allocator: std.mem.Allocator, attribute: []const u8, message: []c ); } -pub fn bold(comptime message: []const u8) []const u8 { - return codes.escape ++ codes.bold ++ message ++ codes.escape ++ codes.reset; +pub fn bold(comptime color: Color, comptime message: []const u8) []const u8 { + 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 { diff --git a/src/jetzig/http/Server.zig b/src/jetzig/http/Server.zig index 193bdef..cdb9a85 100644 --- a/src/jetzig/http/Server.zig +++ b/src/jetzig/http/Server.zig @@ -21,6 +21,7 @@ cache: *jetzig.kv.Store, repo: *jetzig.database.Repo, global: *anyopaque, decoded_static_route_params: []*jetzig.data.Value = &.{}, +debug_mutex: std.Thread.Mutex = .{}, const Server = @This(); @@ -92,6 +93,7 @@ pub fn listen(self: *Server) !void { }, .request = .{ .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 }, @@ -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 {}; 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"; } @@ -128,6 +134,9 @@ pub fn processNextRequest( ) !void { 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 request = try jetzig.http.Request.init( httpz_response.arena, @@ -136,7 +145,7 @@ pub fn processNextRequest( httpz_request, httpz_response, &response, - self.repo, + &repo, ); try request.process(); diff --git a/src/jetzig/loggers/DevelopmentLogger.zig b/src/jetzig/loggers/DevelopmentLogger.zig index 8ff0dbf..191f4a9 100644 --- a/src/jetzig/loggers/DevelopmentLogger.zig +++ b/src/jetzig/loggers/DevelopmentLogger.zig @@ -166,9 +166,16 @@ const sql_tokens = .{ "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 { 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; var buf: [4096]u8 = undefined; 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]}); index += 1; } else { + @setEvalBranchQuota(2000); inline for (sql_tokens) |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; break; }