SQL Adapter¶
Use the SQL adapter when your application already owns a *sql.DB connection.
The adapter wraps that connection so Limen can store users, sessions,
verifications, rate-limit state, and plugin data in the same database.
The adapter uses sqlx internally while keeping your application on standard
database/sql.
Install¶
go get github.com/ragokan/limen/adapters/sql
go get github.com/lib/pq
Use the driver package for your database:
- PostgreSQL:
github.com/lib/pq - MySQL:
github.com/go-sql-driver/mysql - SQLite:
modernc.org/sqlite
Create The Adapter¶
package main
import (
"database/sql"
"log"
"net/http"
"os"
_ "github.com/lib/pq"
"github.com/ragokan/limen"
sqladapter "github.com/ragokan/limen/adapters/sql"
credentialpassword "github.com/ragokan/limen/plugins/credential-password"
)
func main() {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer db.Close()
auth, err := limen.New(&limen.Config{
BaseURL: "http://localhost:8080",
Database: sqladapter.NewPostgreSQL(db),
Secret: []byte(os.Getenv("LIMEN_SECRET")),
HTTP: limen.NewDefaultHTTPConfig(
limen.WithHTTPBasePath("/api/auth"),
),
Plugins: []limen.Plugin{
credentialpassword.New(),
},
})
if err != nil {
log.Fatal(err)
}
mux := http.NewServeMux()
mux.Handle("/api/auth/", auth.Handler())
log.Fatal(http.ListenAndServe(":8080", mux))
}
LIMEN_SECRET must be exactly 32 bytes. For local development:
export LIMEN_SECRET="$(openssl rand -hex 16)"
Choose the constructor that matches your database:
sqladapter.NewPostgreSQL(db)
sqladapter.NewMySQL(db)
sqladapter.NewSQLite(db)
Migrations¶
Limen does not create database tables automatically. Generate SQL migrations with the CLI, then apply them with your migration tool.
limen generate migrations \
--driver postgres \
--dsn "$DATABASE_URL" \
--output ./migrations
The CLI currently generates migrations for PostgreSQL and MySQL.
Query Logging¶
For profiling or debugging, attach a query logger:
adapter := sqladapter.NewPostgreSQL(db).WithLogger(myLogger)
The logger must implement:
type QueryLogger interface {
LogQuery(ctx context.Context, query string, args any, duration time.Duration, err error)
}
MySQL Notes¶
The MySQL driver's text protocol can return []byte for string columns. The
SQL adapter normalizes those values to string after scanning so text and
prepared protocols behave consistently.