I’m working on qrafter, a small typed SQL query builder for Go.
The goal is not to replace SQL with an ORM. I like raw SQL, but I got tired of manually keeping SQL fragments, placeholders, and args in sync when building dynamic filters.
Example use case:
users := q.MustNewTable[UserTable]()
query := q.Select(users.ID, users.UserName, users.Age)
if status != "" {
query = query.Where(users.Status.Eq(status))
}
if minAge != nil {
query = query.Where(users.Age.Ge(*minAge))
}
sqlText, args, err := query.
OrderBy(users.ID.Asc()).
Limit(100).
Render(dialect.PostgreSQL{})
It renders regular SQL + args, so it still works with database/sql, sqlx, etc.
I’m mostly looking for API feedback before v1:
-
does this feel idiomatic for Go?
-
are typed table definitions worth the setup?
-
would this help with dynamic filters, or would you still prefer raw SQL/sqlc/Squirrel?