Explicit queries
Keep SQL visible, named, and easy to change without indirection.
Godex
Godex keeps reusable table-level queries close to your code. It stays small, explicit, and readable: named parameters, typed reads, and a compact set of write helpers.
Overview
Godex is a small sqlx-based query store for reusable
table-level queries. Define your table, register your SQL, and use
a typed facade when you want concrete values instead of scanning
into destination pointers.
Keep SQL visible, named, and easy to change without indirection.
Use godex.For[T](...) to return concrete model values.
Support :id style placeholders with godex.Args, maps, or structs.
Small API, predictable defaults, and compatibility helpers where needed.
Quick Start
Define a codex, then use the typed facade for the model you want to read.
import godex "github.com/sphireinc/godex/v2"
db := sqlx.MustConnect("mysql", dsn)
q := godex.NewWithQueries(db, "posts", godex.DefaultQueries{
SelectById: "SELECT id, title, created_at FROM posts WHERE id = :id",
SelectOne: "SELECT id, title, created_at FROM posts WHERE id = :id AND title = :title",
Select: "SELECT id, title, created_at FROM posts WHERE created_at >= :created_after",
Insert: "INSERT INTO posts (title) VALUES (:title)",
Update: "UPDATE posts SET title = :title WHERE id = :id",
Delete: "DELETE FROM posts WHERE id = :id",
SoftDelete: "UPDATE posts SET deleted_at = CURRENT_TIMESTAMP WHERE id = :id",
}, map[string]string{
"SelectUsersByFirstName": "SELECT id, first_name FROM users WHERE first_name = :first_name",
})
type Post struct {
ID int `db:"id"`
Title string `db:"title"`
}
posts := godex.For[Post](q)
Examples
Common read and write patterns stay short. The API is small on purpose, so the examples look like the code you will actually write.
Use the typed facade when you want a single concrete value back.
post, err := posts.SelectOne(godex.Args{
"id": 154,
"title": "Hello World",
})
Pass named arguments to a query that returns a collection.
recentPosts, err := posts.Select(godex.Args{
"created_after": time.Now().Add(-24 * time.Hour),
})
Register a query once, then call it by name when needed.
err := q.QueryNamedInto("SelectUsersByFirstName", &users, godex.Args{
"first_name": "John",
})
Write helpers stay explicit and accept small payload structs.
id, err := q.InsertWith(struct {
Title string `db:"title"`
}{
Title: "Hello World",
})
Core API
QueryOne, SelectOneInto, and SelectByIDInto handle single-row reads.
QueryMany, QueryInto, and SelectInto handle multi-row results.
InsertWith, UpdateWith, DeleteWith, and SoftDeleteWith keep writes explicit.
QueryNamed... helpers.
Why v2
v2 removes the old Mantis dependency, uses *sqlx.DB, and keeps
the preferred API centered on godex.For[T](...).
Import from github.com/sphireinc/godex/v2 and build around sqlx.DB.
Legacy helpers still exist, but the docs point to the typed path first.