mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 14:06:08 +00:00
WIP
This commit is contained in:
parent
9bc1b26c10
commit
198754eef2
@ -14,12 +14,13 @@ pub fn main() !void {
|
|||||||
|
|
||||||
const allocator = arena.allocator();
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
|
// FIXME: Load config from app
|
||||||
var repo = try jetquery.Repo.init(
|
var repo = try jetquery.Repo.init(
|
||||||
allocator,
|
allocator,
|
||||||
.{
|
.{
|
||||||
.adapter = .{
|
.adapter = .{
|
||||||
.postgresql = .{
|
.postgresql = .{
|
||||||
.database = "postgres",
|
.database = "jetzig_website",
|
||||||
.username = "postgres",
|
.username = "postgres",
|
||||||
.hostname = "127.0.0.1",
|
.hostname = "127.0.0.1",
|
||||||
.password = "password",
|
.password = "password",
|
||||||
|
148
src/jetzig.zig
148
src/jetzig.zig
@ -17,7 +17,9 @@ pub const markdown = @import("jetzig/markdown.zig");
|
|||||||
pub const jobs = @import("jetzig/jobs.zig");
|
pub const jobs = @import("jetzig/jobs.zig");
|
||||||
pub const mail = @import("jetzig/mail.zig");
|
pub const mail = @import("jetzig/mail.zig");
|
||||||
pub const kv = @import("jetzig/kv.zig");
|
pub const kv = @import("jetzig/kv.zig");
|
||||||
|
pub const database = @import("jetzig/database.zig");
|
||||||
pub const testing = @import("jetzig/testing.zig");
|
pub const testing = @import("jetzig/testing.zig");
|
||||||
|
pub const config = @import("jetzig/config.zig");
|
||||||
|
|
||||||
/// The primary interface for a Jetzig application. Create an `App` in your application's
|
/// The primary interface for a Jetzig application. Create an `App` in your application's
|
||||||
/// `src/main.zig` and call `start` to launch the application.
|
/// `src/main.zig` and call `start` to launch the application.
|
||||||
@ -69,152 +71,6 @@ pub const root = @import("root");
|
|||||||
pub const Global = if (@hasDecl(root, "Global")) root.Global else DefaultGlobal;
|
pub const Global = if (@hasDecl(root, "Global")) root.Global else DefaultGlobal;
|
||||||
pub const DefaultGlobal = struct { __jetzig_default: bool };
|
pub const DefaultGlobal = struct { __jetzig_default: bool };
|
||||||
|
|
||||||
/// Global configuration. Override these values by defining in `src/main.zig` with:
|
|
||||||
/// ```zig
|
|
||||||
/// pub const jetzig_options = struct {
|
|
||||||
/// // ...
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
/// All constants defined below can be overridden.
|
|
||||||
pub const config = struct {
|
|
||||||
/// Maximum bytes to allow in request body.
|
|
||||||
pub const max_bytes_request_body: usize = std.math.pow(usize, 2, 16);
|
|
||||||
|
|
||||||
/// Maximum filesize for `public/` content.
|
|
||||||
pub const max_bytes_public_content: usize = std.math.pow(usize, 2, 20);
|
|
||||||
|
|
||||||
/// Maximum filesize for `static/` content (applies only to apps using `jetzig.http.StaticRequest`).
|
|
||||||
pub const max_bytes_static_content: usize = std.math.pow(usize, 2, 18);
|
|
||||||
|
|
||||||
/// Maximum length of a header name. There is no limit imposed by the HTTP specification but
|
|
||||||
/// AWS load balancers reference 40 as a limit so we use that as a baseline:
|
|
||||||
/// https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_HttpHeaderConditionConfig.html
|
|
||||||
/// This can be increased if needed.
|
|
||||||
pub const max_bytes_header_name: u16 = 40;
|
|
||||||
|
|
||||||
/// Maximum number of `multipart/form-data`-encoded fields to accept per request.
|
|
||||||
pub const max_multipart_form_fields: usize = 20;
|
|
||||||
|
|
||||||
/// Log message buffer size. Log messages exceeding this size spill to heap with degraded
|
|
||||||
/// performance. Log messages should aim to fit in the message buffer.
|
|
||||||
pub const log_message_buffer_len: usize = 4096;
|
|
||||||
|
|
||||||
/// Maximum log pool size. When a log buffer is no longer required it is returned to a pool
|
|
||||||
/// for recycling. When logging i/o is slow, a high volume of requests will result in this
|
|
||||||
/// pool growing. When the pool size reaches the maximum value defined here, log events are
|
|
||||||
/// freed instead of recycled.
|
|
||||||
pub const max_log_pool_len: usize = 256;
|
|
||||||
|
|
||||||
/// Number of request threads. Defaults to number of detected CPUs.
|
|
||||||
pub const thread_count: ?u16 = null;
|
|
||||||
|
|
||||||
/// Per-thread stack memory to use before spilling into request arena (possibly with allocations).
|
|
||||||
pub const buffer_size: usize = 64 * 1024;
|
|
||||||
|
|
||||||
/// The pre-heated size of each item in the available memory pool used by requests for
|
|
||||||
/// rendering. Total retained allocation: `worker_count * max_connections`. Requests
|
|
||||||
/// requiring more memory will allocate per-request, leaving `arena_size` bytes pre-allocated
|
|
||||||
/// for the next request.
|
|
||||||
pub const arena_size: usize = 1024 * 1024;
|
|
||||||
|
|
||||||
/// Number of response worker threads.
|
|
||||||
pub const worker_count: u16 = 4;
|
|
||||||
|
|
||||||
/// Total number of connections managed by worker threads.
|
|
||||||
pub const max_connections: u16 = 512;
|
|
||||||
|
|
||||||
/// Path relative to cwd() to serve public content from. Symlinks are not followed.
|
|
||||||
pub const public_content_path = "public";
|
|
||||||
|
|
||||||
/// Middleware chain. Add any custom middleware here, or use middleware provided in
|
|
||||||
/// `jetzig.middleware` (e.g. `jetzig.middleware.HtmxMiddleware`).
|
|
||||||
pub const middleware = &.{};
|
|
||||||
|
|
||||||
/// HTTP buffer. Must be large enough to store all headers. This should typically not be
|
|
||||||
/// modified.
|
|
||||||
pub const http_buffer_size: usize = std.math.pow(usize, 2, 16);
|
|
||||||
|
|
||||||
/// A struct of fragments to use when rendering Markdown templates.
|
|
||||||
pub const markdown_fragments = zmd.html.DefaultFragments;
|
|
||||||
|
|
||||||
/// The number of worker threads to spawn on startup for processing Jobs (NOT the number of
|
|
||||||
/// HTTP server worker threads).
|
|
||||||
pub const job_worker_threads: usize = 1;
|
|
||||||
|
|
||||||
/// Duration before looking for more Jobs when the queue is found to be empty, in
|
|
||||||
/// milliseconds.
|
|
||||||
pub const job_worker_sleep_interval_ms: usize = 10;
|
|
||||||
|
|
||||||
/// Key-value store options. Set backend to `.file` to use a file-based store.
|
|
||||||
/// When using `.file` backend, you must also set `.file_options`.
|
|
||||||
/// The key-value store is exposed as `request.store` in views and is also available in as
|
|
||||||
/// `env.store` in all jobs/mailers.
|
|
||||||
pub const store: kv.Store.KVOptions = .{
|
|
||||||
.backend = .memory,
|
|
||||||
// .backend = .file,
|
|
||||||
// .file_options = .{
|
|
||||||
// .path = "/path/to/jetkv-store.db",
|
|
||||||
// .truncate = false, // Set to `true` to clear the store on each server launch.
|
|
||||||
// .address_space_size = jetzig.jetkv.JetKV.FileBackend.addressSpace(4096),
|
|
||||||
// },
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Job queue options. Identical to `store` options, but allows using different
|
|
||||||
/// backends (e.g. `.memory` for key-value store, `.file` for jobs queue.
|
|
||||||
/// The job queue is managed internally by Jetzig.
|
|
||||||
pub const job_queue: kv.Store.KVOptions = .{
|
|
||||||
.backend = .memory,
|
|
||||||
// .backend = .file,
|
|
||||||
// .file_options = .{
|
|
||||||
// .path = "/path/to/jetkv-queue.db",
|
|
||||||
// .truncate = false, // Set to `true` to clear the store on each server launch.
|
|
||||||
// .address_space_size = jetzig.jetkv.JetKV.FileBackend.addressSpace(4096),
|
|
||||||
// },
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Cache. Identical to `store` options, but allows using different
|
|
||||||
/// backends (e.g. `.memory` for key-value store, `.file` for cache.
|
|
||||||
pub const cache: kv.Store.KVOptions = .{
|
|
||||||
.backend = .memory,
|
|
||||||
// .backend = .file,
|
|
||||||
// .file_options = .{
|
|
||||||
// .path = "/path/to/jetkv-cache.db",
|
|
||||||
// .truncate = false, // Set to `true` to clear the store on each server launch.
|
|
||||||
// .address_space_size = jetzig.jetkv.JetKV.FileBackend.addressSpace(4096),
|
|
||||||
// },
|
|
||||||
};
|
|
||||||
|
|
||||||
/// SMTP configuration for Jetzig Mail.
|
|
||||||
pub const smtp: mail.SMTPConfig = .{
|
|
||||||
.port = 25,
|
|
||||||
.encryption = .none, // .insecure, .none, .tls, .start_tls
|
|
||||||
.host = "localhost",
|
|
||||||
.username = null,
|
|
||||||
.password = null,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// HTTP cookie configuration
|
|
||||||
pub const cookie_options: http.Cookies.CookieOptions = .{
|
|
||||||
.domain = "localhost",
|
|
||||||
.path = "/",
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Force email delivery in development mode (instead of printing email body to logger).
|
|
||||||
pub const force_development_email_delivery = false;
|
|
||||||
|
|
||||||
/// Reconciles a configuration value from user-defined values and defaults provided by Jetzig.
|
|
||||||
pub fn get(T: type, comptime key: []const u8) T {
|
|
||||||
const self = @This();
|
|
||||||
if (!@hasDecl(self, key)) @panic("Unknown config option: " ++ key);
|
|
||||||
|
|
||||||
if (@hasDecl(root, "jetzig_options") and @hasDecl(root.jetzig_options, key)) {
|
|
||||||
return @field(root.jetzig_options, key);
|
|
||||||
} else {
|
|
||||||
return @field(self, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const initHook: ?*const fn (*App) anyerror!void = if (@hasDecl(root, "init")) root.init else null;
|
pub const initHook: ?*const fn (*App) anyerror!void = if (@hasDecl(root, "init")) root.init else null;
|
||||||
|
|
||||||
/// Initialize a new Jetzig app. Call this from `src/main.zig` and then call
|
/// Initialize a new Jetzig app. Call this from `src/main.zig` and then call
|
||||||
|
@ -41,7 +41,6 @@ pub fn start(self: *const App, routes_module: type, options: AppOptions) !void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
defer for (self.custom_routes.items) |custom_route| {
|
defer for (self.custom_routes.items) |custom_route| {
|
||||||
self.allocator.free(custom_route.view_name);
|
|
||||||
self.allocator.free(custom_route.template);
|
self.allocator.free(custom_route.template);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,6 +69,12 @@ pub fn start(self: *const App, routes_module: type, options: AppOptions) !void {
|
|||||||
);
|
);
|
||||||
defer log_thread.join();
|
defer log_thread.join();
|
||||||
|
|
||||||
|
var repo = try jetzig.database.repo(
|
||||||
|
self.allocator,
|
||||||
|
jetzig.config.get(?jetzig.database.DatabaseOptions, "database"),
|
||||||
|
);
|
||||||
|
defer repo.deinit();
|
||||||
|
|
||||||
if (self.env.detach) {
|
if (self.env.detach) {
|
||||||
const argv = try std.process.argsAlloc(self.allocator);
|
const argv = try std.process.argsAlloc(self.allocator);
|
||||||
defer std.process.argsFree(self.allocator, argv);
|
defer std.process.argsFree(self.allocator, argv);
|
||||||
@ -96,6 +101,7 @@ pub fn start(self: *const App, routes_module: type, options: AppOptions) !void {
|
|||||||
&store,
|
&store,
|
||||||
&job_queue,
|
&job_queue,
|
||||||
&cache,
|
&cache,
|
||||||
|
&repo,
|
||||||
options.global,
|
options.global,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
183
src/jetzig/config.zig
Normal file
183
src/jetzig/config.zig
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const zmpl = @import("zmpl").zmpl;
|
||||||
|
pub const zmd = @import("zmd").zmd;
|
||||||
|
pub const jetkv = @import("jetkv").jetkv;
|
||||||
|
pub const jetquery = @import("jetquery");
|
||||||
|
|
||||||
|
pub const http = @import("http.zig");
|
||||||
|
pub const loggers = @import("loggers.zig");
|
||||||
|
pub const data = @import("data.zig");
|
||||||
|
pub const views = @import("views.zig");
|
||||||
|
pub const colors = @import("colors.zig");
|
||||||
|
pub const util = @import("util.zig");
|
||||||
|
pub const types = @import("types.zig");
|
||||||
|
pub const markdown = @import("markdown.zig");
|
||||||
|
pub const jobs = @import("jobs.zig");
|
||||||
|
pub const mail = @import("mail.zig");
|
||||||
|
pub const kv = @import("kv.zig");
|
||||||
|
pub const db = @import("database.zig");
|
||||||
|
|
||||||
|
const root = @import("root");
|
||||||
|
|
||||||
|
/// Global configuration. Override these values by defining in `src/main.zig` with:
|
||||||
|
/// ```zig
|
||||||
|
/// pub const jetzig_options = struct {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// All constants defined below can be overridden.
|
||||||
|
const config = @This();
|
||||||
|
|
||||||
|
/// Maximum bytes to allow in request body.
|
||||||
|
pub const max_bytes_request_body: usize = std.math.pow(usize, 2, 16);
|
||||||
|
|
||||||
|
/// Maximum filesize for `public/` content.
|
||||||
|
pub const max_bytes_public_content: usize = std.math.pow(usize, 2, 20);
|
||||||
|
|
||||||
|
/// Maximum filesize for `static/` content (applies only to apps using `jetzig.http.StaticRequest`).
|
||||||
|
pub const max_bytes_static_content: usize = std.math.pow(usize, 2, 18);
|
||||||
|
|
||||||
|
/// Maximum length of a header name. There is no limit imposed by the HTTP specification but
|
||||||
|
/// AWS load balancers reference 40 as a limit so we use that as a baseline:
|
||||||
|
/// https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_HttpHeaderConditionConfig.html
|
||||||
|
/// This can be increased if needed.
|
||||||
|
pub const max_bytes_header_name: u16 = 40;
|
||||||
|
|
||||||
|
/// Maximum number of `multipart/form-data`-encoded fields to accept per request.
|
||||||
|
pub const max_multipart_form_fields: usize = 20;
|
||||||
|
|
||||||
|
/// Log message buffer size. Log messages exceeding this size spill to heap with degraded
|
||||||
|
/// performance. Log messages should aim to fit in the message buffer.
|
||||||
|
pub const log_message_buffer_len: usize = 4096;
|
||||||
|
|
||||||
|
/// Maximum log pool size. When a log buffer is no longer required it is returned to a pool
|
||||||
|
/// for recycling. When logging i/o is slow, a high volume of requests will result in this
|
||||||
|
/// pool growing. When the pool size reaches the maximum value defined here, log events are
|
||||||
|
/// freed instead of recycled.
|
||||||
|
pub const max_log_pool_len: usize = 256;
|
||||||
|
|
||||||
|
/// Number of request threads. Defaults to number of detected CPUs.
|
||||||
|
pub const thread_count: ?u16 = null;
|
||||||
|
|
||||||
|
/// Per-thread stack memory to use before spilling into request arena (possibly with allocations).
|
||||||
|
pub const buffer_size: usize = 64 * 1024;
|
||||||
|
|
||||||
|
/// The pre-heated size of each item in the available memory pool used by requests for
|
||||||
|
/// rendering. Total retained allocation: `worker_count * max_connections`. Requests
|
||||||
|
/// requiring more memory will allocate per-request, leaving `arena_size` bytes pre-allocated
|
||||||
|
/// for the next request.
|
||||||
|
pub const arena_size: usize = 1024 * 1024;
|
||||||
|
|
||||||
|
/// Number of response worker threads.
|
||||||
|
pub const worker_count: u16 = 4;
|
||||||
|
|
||||||
|
/// Total number of connections managed by worker threads.
|
||||||
|
pub const max_connections: u16 = 512;
|
||||||
|
|
||||||
|
/// Path relative to cwd() to serve public content from. Symlinks are not followed.
|
||||||
|
pub const public_content_path = "public";
|
||||||
|
|
||||||
|
/// Middleware chain. Add any custom middleware here, or use middleware provided in
|
||||||
|
/// `jetzig.middleware` (e.g. `jetzig.middleware.HtmxMiddleware`).
|
||||||
|
pub const middleware = &.{};
|
||||||
|
|
||||||
|
/// HTTP buffer. Must be large enough to store all headers. This should typically not be
|
||||||
|
/// modified.
|
||||||
|
pub const http_buffer_size: usize = std.math.pow(usize, 2, 16);
|
||||||
|
|
||||||
|
/// A struct of fragments to use when rendering Markdown templates.
|
||||||
|
pub const markdown_fragments = zmd.html.DefaultFragments;
|
||||||
|
|
||||||
|
/// The number of worker threads to spawn on startup for processing Jobs (NOT the number of
|
||||||
|
/// HTTP server worker threads).
|
||||||
|
pub const job_worker_threads: usize = 1;
|
||||||
|
|
||||||
|
/// Duration before looking for more Jobs when the queue is found to be empty, in
|
||||||
|
/// milliseconds.
|
||||||
|
pub const job_worker_sleep_interval_ms: usize = 10;
|
||||||
|
|
||||||
|
/// Database configuration.
|
||||||
|
pub const database: ?db.DatabaseOptions = null;
|
||||||
|
|
||||||
|
/// Database Schema.
|
||||||
|
pub const Schema: type = struct {
|
||||||
|
pub const _null = struct {}; // https://github.com/ziglang/zig/pull/21331
|
||||||
|
pub const Blogs = struct {
|
||||||
|
pub const table_name = "blogs";
|
||||||
|
pub const Definition = struct {
|
||||||
|
id: []const u8,
|
||||||
|
title: []const u8,
|
||||||
|
content: []const u8,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Key-value store options. Set backend to `.file` to use a file-based store.
|
||||||
|
/// When using `.file` backend, you must also set `.file_options`.
|
||||||
|
/// The key-value store is exposed as `request.store` in views and is also available in as
|
||||||
|
/// `env.store` in all jobs/mailers.
|
||||||
|
pub const store: kv.Store.KVOptions = .{
|
||||||
|
.backend = .memory,
|
||||||
|
// .backend = .file,
|
||||||
|
// .file_options = .{
|
||||||
|
// .path = "/path/to/jetkv-store.db",
|
||||||
|
// .truncate = false, // Set to `true` to clear the store on each server launch.
|
||||||
|
// .address_space_size = jetzig.jetkv.JetKV.FileBackend.addressSpace(4096),
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Job queue options. Identical to `store` options, but allows using different
|
||||||
|
/// backends (e.g. `.memory` for key-value store, `.file` for jobs queue.
|
||||||
|
/// The job queue is managed internally by Jetzig.
|
||||||
|
pub const job_queue: kv.Store.KVOptions = .{
|
||||||
|
.backend = .memory,
|
||||||
|
// .backend = .file,
|
||||||
|
// .file_options = .{
|
||||||
|
// .path = "/path/to/jetkv-queue.db",
|
||||||
|
// .truncate = false, // Set to `true` to clear the store on each server launch.
|
||||||
|
// .address_space_size = jetzig.jetkv.JetKV.FileBackend.addressSpace(4096),
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Cache. Identical to `store` options, but allows using different
|
||||||
|
/// backends (e.g. `.memory` for key-value store, `.file` for cache.
|
||||||
|
pub const cache: kv.Store.KVOptions = .{
|
||||||
|
.backend = .memory,
|
||||||
|
// .backend = .file,
|
||||||
|
// .file_options = .{
|
||||||
|
// .path = "/path/to/jetkv-cache.db",
|
||||||
|
// .truncate = false, // Set to `true` to clear the store on each server launch.
|
||||||
|
// .address_space_size = jetzig.jetkv.JetKV.FileBackend.addressSpace(4096),
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// SMTP configuration for Jetzig Mail.
|
||||||
|
pub const smtp: mail.SMTPConfig = .{
|
||||||
|
.port = 25,
|
||||||
|
.encryption = .none, // .insecure, .none, .tls, .start_tls
|
||||||
|
.host = "localhost",
|
||||||
|
.username = null,
|
||||||
|
.password = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// HTTP cookie configuration
|
||||||
|
pub const cookie_options: http.Cookies.CookieOptions = .{
|
||||||
|
.domain = "localhost",
|
||||||
|
.path = "/",
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Force email delivery in development mode (instead of printing email body to logger).
|
||||||
|
pub const force_development_email_delivery = false;
|
||||||
|
|
||||||
|
/// Reconciles a configuration value from user-defined values and defaults provided by Jetzig.
|
||||||
|
pub fn get(T: type, comptime key: []const u8) T {
|
||||||
|
const self = @This();
|
||||||
|
if (!@hasDecl(self, key)) @panic("Unknown config option: " ++ key);
|
||||||
|
|
||||||
|
if (@hasDecl(root, "jetzig_options") and @hasDecl(root.jetzig_options, key)) {
|
||||||
|
return @field(root.jetzig_options, key);
|
||||||
|
} else {
|
||||||
|
return @field(self, key);
|
||||||
|
}
|
||||||
|
}
|
38
src/jetzig/database.zig
Normal file
38
src/jetzig/database.zig
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const jetzig = @import("../jetzig.zig");
|
||||||
|
|
||||||
|
pub const DatabaseOptions = struct {
|
||||||
|
adapter: enum { postgresql },
|
||||||
|
hostname: []const u8,
|
||||||
|
port: u16,
|
||||||
|
username: []const u8,
|
||||||
|
password: []const u8,
|
||||||
|
database: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Schema = jetzig.get(type, "Schema");
|
||||||
|
|
||||||
|
pub fn repo(allocator: std.mem.Allocator, maybe_options: ?DatabaseOptions) !jetzig.jetquery.Repo {
|
||||||
|
const options = maybe_options orelse return try jetzig.jetquery.Repo.init(
|
||||||
|
allocator,
|
||||||
|
.{ .adapter = .null },
|
||||||
|
);
|
||||||
|
|
||||||
|
return switch (options.adapter) {
|
||||||
|
.postgresql => try jetzig.jetquery.Repo.init(
|
||||||
|
allocator,
|
||||||
|
.{
|
||||||
|
.adapter = .{
|
||||||
|
.postgresql = .{
|
||||||
|
.hostname = options.hostname,
|
||||||
|
.port = options.port,
|
||||||
|
.username = options.username,
|
||||||
|
.password = options.password,
|
||||||
|
.database = options.database,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
@ -43,6 +43,7 @@ rendered_view: ?jetzig.views.View = null,
|
|||||||
start_time: i128,
|
start_time: i128,
|
||||||
store: RequestStore,
|
store: RequestStore,
|
||||||
cache: RequestStore,
|
cache: RequestStore,
|
||||||
|
repo: *jetzig.jetquery.Repo,
|
||||||
global: *jetzig.Global,
|
global: *jetzig.Global,
|
||||||
|
|
||||||
/// Wrapper for KV store that uses the request's arena allocator for fetching values.
|
/// Wrapper for KV store that uses the request's arena allocator for fetching values.
|
||||||
@ -104,6 +105,7 @@ pub fn init(
|
|||||||
httpz_request: *httpz.Request,
|
httpz_request: *httpz.Request,
|
||||||
httpz_response: *httpz.Response,
|
httpz_response: *httpz.Response,
|
||||||
response: *jetzig.http.Response,
|
response: *jetzig.http.Response,
|
||||||
|
repo: *jetzig.jetquery.Repo,
|
||||||
) !Request {
|
) !Request {
|
||||||
const method = switch (httpz_request.method) {
|
const method = switch (httpz_request.method) {
|
||||||
.DELETE => Method.DELETE,
|
.DELETE => Method.DELETE,
|
||||||
@ -131,6 +133,7 @@ pub fn init(
|
|||||||
.start_time = start_time,
|
.start_time = start_time,
|
||||||
.store = .{ .store = server.store, .allocator = allocator },
|
.store = .{ .store = server.store, .allocator = allocator },
|
||||||
.cache = .{ .store = server.cache, .allocator = allocator },
|
.cache = .{ .store = server.cache, .allocator = allocator },
|
||||||
|
.repo = repo,
|
||||||
.global = if (@hasField(jetzig.Global, "__jetzig_default"))
|
.global = if (@hasField(jetzig.Global, "__jetzig_default"))
|
||||||
undefined
|
undefined
|
||||||
else
|
else
|
||||||
@ -517,6 +520,15 @@ pub fn mail(self: *Request, name: []const u8, mail_params: jetzig.mail.MailParam
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn query(
|
||||||
|
self: *const Request,
|
||||||
|
comptime table: std.meta.DeclEnum(jetzig.config.get(type, "Schema")),
|
||||||
|
) jetzig.jetquery.Query(@field(jetzig.config.get(type, "Schema"), @tagName(table))) {
|
||||||
|
return jetzig.jetquery.Query(
|
||||||
|
@field(jetzig.config.get(type, "Schema"), @tagName(table)),
|
||||||
|
).init(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
fn extensionFormat(self: *const Request) ?jetzig.http.Request.Format {
|
fn extensionFormat(self: *const Request) ?jetzig.http.Request.Format {
|
||||||
const extension = self.path.extension orelse return null;
|
const extension = self.path.extension orelse return null;
|
||||||
if (std.mem.eql(u8, extension, ".html")) {
|
if (std.mem.eql(u8, extension, ".html")) {
|
||||||
|
@ -19,6 +19,7 @@ initialized: bool = false,
|
|||||||
store: *jetzig.kv.Store,
|
store: *jetzig.kv.Store,
|
||||||
job_queue: *jetzig.kv.Store,
|
job_queue: *jetzig.kv.Store,
|
||||||
cache: *jetzig.kv.Store,
|
cache: *jetzig.kv.Store,
|
||||||
|
repo: *jetzig.jetquery.Repo,
|
||||||
global: *anyopaque,
|
global: *anyopaque,
|
||||||
decoded_static_route_params: []*jetzig.data.Value = &.{},
|
decoded_static_route_params: []*jetzig.data.Value = &.{},
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ pub fn init(
|
|||||||
store: *jetzig.kv.Store,
|
store: *jetzig.kv.Store,
|
||||||
job_queue: *jetzig.kv.Store,
|
job_queue: *jetzig.kv.Store,
|
||||||
cache: *jetzig.kv.Store,
|
cache: *jetzig.kv.Store,
|
||||||
|
repo: *jetzig.jetquery.Repo,
|
||||||
global: *anyopaque,
|
global: *anyopaque,
|
||||||
) Server {
|
) Server {
|
||||||
return .{
|
return .{
|
||||||
@ -49,6 +51,7 @@ pub fn init(
|
|||||||
.store = store,
|
.store = store,
|
||||||
.job_queue = job_queue,
|
.job_queue = job_queue,
|
||||||
.cache = cache,
|
.cache = cache,
|
||||||
|
.repo = repo,
|
||||||
.global = global,
|
.global = global,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -130,6 +133,7 @@ pub fn processNextRequest(
|
|||||||
httpz_request,
|
httpz_request,
|
||||||
httpz_response,
|
httpz_response,
|
||||||
&response,
|
&response,
|
||||||
|
self.repo,
|
||||||
);
|
);
|
||||||
|
|
||||||
try request.process();
|
try request.process();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user