caddymodule

package module
v0.1.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

README

hazedb as a Caddy module

This package wraps hazedb as a Caddy HTTP handler, so a single Caddy binary serves your site and an in-process SQL store — no separate database process, no network hop.

It exposes two endpoints. Both take POST with a JSON body {"sql": "...", "args": [...]}:

Endpoint Runs Returns
POST /query SELECT {"columns":[...],"rows":[[...],...]}
POST /exec INSERT / UPDATE / DELETE / CREATE TABLE / DROP TABLE {"affected":N}

args is an optional positional list for ? placeholders. JSON → SQL value mapping: number → INT, bool → BOOL, null → NULL, string → STRING, except a string in canonical UUID form (8-4-4-4-12 hex) → UUID — so you can address and insert UUID columns from JSON.

Build a Caddy binary with the module

Uses xcaddy. Until the core hazedb version that ships db_registry.go + wire.go is tagged, build against the local checkout (the submodule's replace points at ../):

# from a checkout of this repo
xcaddy build \
    --with github.com/VeloxCoding/hazedb/caddymodule=./caddymodule \
    --with github.com/VeloxCoding/hazedb=.

After the core is published, the plain form works:

xcaddy build --with github.com/VeloxCoding/hazedb/caddymodule

Configure (Caddyfile)

:8080 {
    handle /db/* {
        hazedb {
            wal_path      /var/lib/hazedb/data.wal   # omit for memory-only
            size_hint     100000
            wal_sync                                 # fsync on the flush ticker
            wal_flush_ms  1000
            init_sql      /etc/hazedb/schema.sql     # CREATE TABLE + seed, run once
            registry_name default
        }
    }
}

All subdirectives are optional. With no wal_path the store is memory-only. Tables are created at runtime: put your CREATE TABLE statements in the init_sql file, or POST them to /exec.

Schema / tables

hazedb creates tables at runtime, so the module opens with an empty schema. Define tables one of two ways:

  • init_sql — a file of ;-separated statements run once at startup (typical: CREATE TABLE ... plus any seed rows). Don't put a ; inside a string literal in that file.
  • POST /exec — send CREATE TABLE ... like any other write.

Sharing the instance with PHP

The module publishes its *DB in hazedb's process-wide registry under registry_name (default "default"). The FrankenPHP/PHP extension (addons/frankenphp-ext) looks up that same name, so PHP calls and HTTP calls hit one identical database — no second copy.

WAL + config reload caveat

With wal_path set, a Caddy graceful config reload runs the new handler's Provision (which opens the WAL file) before the old handler's Cleanup (which closes it) — briefly two writers on one file. Memory mode reloads cleanly. For durable deployments, prefer a full restart over a graceful reload when changing this handler.

Documentation

Overview

Package caddymodule exposes hazedb as a Caddy HTTP handler.

The core hazedb package stays stdlib-only (plus goccy/go-json); this adapter owns the transport: it opens a *DB, serves POST /query and POST /exec over an internal mux, and registers the *DB under a name in the core registry so an in-process consumer (the FrankenPHP/PHP extension) reaches the very same instance. Per the gateway boundary in the RFC, request-context cross-cutting concerns (auth, per-tenant routing, rate limits) belong here, never in core.

Schema: the module opens with an empty schema by default. hazedb supports runtime CREATE TABLE, so operators define tables via an init_sql file (run once at Provision) or by POSTing DDL to /exec.

WAL + reload caveat: with wal_path set, Caddy config reload runs the new Provision (which opens the same file) before the old Cleanup (which closes it) — two writers on one WAL file for that window. Memory mode (no wal_path) reloads cleanly. For durable deployments, restart rather than graceful-reload when changing this handler.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Handler

type Handler struct {
	// WALLevel is the durability switch: 0 = memory only, 1 = background fsync
	// (~1s window), 2 = fsync every write (slowest, safest). Above 0, WALPath
	// is required.
	WALLevel int `json:"wal_level,omitempty"`
	// WALPath is the directory holding the write-ahead log segments. Required
	// when wal_level > 0.
	WALPath string `json:"wal_path,omitempty"`
	// WALRotateMillis is how often the active segment is sealed, in ms. 0 = 5s.
	WALRotateMillis int `json:"wal_rotate_ms,omitempty"`
	// SQLitePath enables the on-disk SQLite mirror at this path (system of record
	// + recovery source). Empty = no mirror. Requires wal_level > 0.
	SQLitePath string `json:"sqlite_path,omitempty"`
	// InitSQL is an absolute path to a .sql file run once at Provision, before
	// Caddy serves — typically CREATE TABLE + seed rows. Statements are split on
	// ';'; do not put a semicolon inside a string literal in this file.
	InitSQL string `json:"init_sql,omitempty"`
	// RegistryName is the name the *DB is published under for in-process
	// consumers. Empty = "default" (what the PHP extension looks up).
	RegistryName string `json:"registry_name,omitempty"`
	// contains filtered or unexported fields
}

Handler is the Caddy HTTP handler that embeds hazedb.

func (Handler) CaddyModule

func (Handler) CaddyModule() caddy.ModuleInfo

CaddyModule registers the handler under http.handlers.* so it works as a `handle`/`hazedb` directive or a JSON handler entry.

func (*Handler) Cleanup

func (h *Handler) Cleanup() error

Cleanup deregisters and closes the *DB. DeregisterDBIf is the CAS-safe form: during a config reload the new Provision has already overwritten the slot, so this won't clobber it; it only clears when the handler is fully removed.

func (*Handler) Provision

func (h *Handler) Provision(ctx caddy.Context) error

Provision opens the *DB, runs init_sql, wires the routes, and registers the instance. Called once per module instance at Caddy start / config reload.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

ServeHTTP dispatches to the hazedb mux; unmatched paths fall through to the next handler, so the module can be mounted under a prefix alongside others.

func (*Handler) UnmarshalCaddyfile

func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile parses the `hazedb` handler directive. Example:

hazedb {
    wal_level       1
    wal_path        /var/lib/hazedb/wal
    wal_rotation    5s
    sqlite_path     /var/lib/hazedb/hazedb.db
    init_sql        /etc/hazedb/schema.sql
    registry_name   default
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL