Goutils
中文
A Go utility library for database abstraction, HTTP routing, and logging.
- Requires Go 1.24+ (uses generics)
go get github.com/Carry-Rao/goutils
Modules
| Module |
Description |
Docs |
| Database |
Generic Database[T] / Table[T] over MySQL, PostgreSQL, SQLite, Redis, in-memory, and bloom filter, with a composable mixture backend |
EN · 中文 |
| HTTP Router |
Prefix-tree router with typed path variables, middleware, per-pattern CORS, and correct 404/405 handling |
EN · 中文 |
| Log |
Buffered multi-level logging with color output |
EN · 中文 |
Contributing: CONTRIBUTION.md · 中文
Database in one snippet
import (
"github.com/Carry-Rao/goutils/database"
"github.com/Carry-Rao/goutils/database/factory"
)
type User struct {
ID int `db:"id,primary"`
Name string `db:"name"`
}
db, err := factory.New[User]("memory", nil)
if err != nil {
panic(err)
}
if err := db.Create("users", map[string]database.Config{
"id": {PrimaryKey: true},
"name": {Type: "TEXT"},
}); err != nil {
panic(err)
}
tbl, _ := db.GetTable("users", User{})
_ = tbl.Ins(User{ID: 1, Name: "Alice"}, 0)
// []User, not []any; Options carries order and paging
users, _ := tbl.Get(User{ID: 1}, nil, database.Options{}, 0)
// WHERE comes from the old value, assignment from the new one
_ = tbl.Set(User{ID: 1}, User{ID: 1, Name: "Bob"}, []string{"ID"}, []string{"Name"}, 0)
_ = db.Close()
Backends register themselves on import, mirroring database/sql. Import
database/factory to get every built-in backend, or import a single backend
package and call its NewDatabase directly to skip the indirection.
Breaking changes from the generics refactor
api.Database / api.Table moved to the root database package and are now
generic: database.Database[T], database.Table[T]
- Construction moved to
factory.New[T](name, cfg) / factory.Open[T](dbType, cfg)
Table.Get returns []T instead of []any, and takes a database.Options
argument for ordering and paging
Table.Set takes the old and new values separately:
Set(old, updated T, whereFields, setFields []string, ttl)
Database.Close() error is now part of the interface, and ttl is honoured
by every backend instead of memory alone
- The
database/api and database/api/typed packages are gone
router.BadRequest became router.MethodNotAllowed; status code 400 → 405
- Router
:any was removed; :string is the only catch-all and does not span /
Status
Integration tests cover the in-process backends (memory, bloom, mixture). The
MySQL, PostgreSQL, SQLite, and Redis backends compile and are exercised by the
type checker but are not covered by automated tests, as they require external
services. Not recommended for production use without your own testing.