Documentation
¶
Index ¶
- Constants
- Variables
- func AutoMigrate(ctx context.Context, db *gorm.DB, models ...any) error
- func Close(db *gorm.DB) error
- func Create[T any](ctx context.Context, db *gorm.DB, record *T) (*T, error)
- func Default() *gorm.DB
- func DeleteByID[T any](ctx context.Context, db *gorm.DB, id any) error
- func DeleteWhere(ctx context.Context, db *gorm.DB, model any, query any, args ...any) error
- func ExecRaw(ctx context.Context, db *gorm.DB, sql string, args ...any) (int64, error)
- func FirstByID[T any](ctx context.Context, db *gorm.DB, id any) (*T, error)
- func FirstWhere[T any](ctx context.Context, db *gorm.DB, query any, args ...any) (*T, error)
- func HealthChecker() health.Checker
- func IsNotFound(err error) bool
- func IsSafeSQLIdentifierPath(value string) bool
- func IsSafeSQLName(value string) bool
- func NormalizeSortDirection(direction string) string
- func Open(dialector gorm.Dialector, conf *GormConfig) (*gorm.DB, error)
- func OrderBy(allowed map[string]string, sort, direction string) func(*gorm.DB) *gorm.DB
- func PageSql(para *dto.PageParameter) string
- func Paginate(page, limit int) func(*gorm.DB) *gorm.DB
- func ScanRaw(ctx context.Context, db *gorm.DB, dest any, sql string, args ...any) error
- func SetDefault(db *gorm.DB)
- func SortSql(para *dto.PageParameter) string
- func UpdateByID[T any](ctx context.Context, db *gorm.DB, id any, values any) error
- func UpdateWhere(ctx context.Context, db *gorm.DB, model any, values any, query any, ...) error
- type GormConfig
Examples ¶
Constants ¶
const ( MaxOpenConns = 100 // MaxOpenConns is the maximum number of open database connections in the pool. MaxIdleConns = 25 // MaxIdleConns is the maximum number of idle database connections (1/4 of MaxOpenConns). ConnMaxLifetime = 60 * time.Minute // ConnMaxLifetime is the maximum lifetime of a database connection in minutes. ConnMaxIdletime = 10 * time.Minute // ConnMaxIdletime is the maximum idle lifetime of a database connection in minutes. )
Variables ¶
var ( // ErrNilDialector is returned when Open receives a nil GORM dialector. ErrNilDialector = errors.New("dbgorm: nil gorm dialector") // ErrMissingConfig is returned when an adapter lacks required connection fields. ErrMissingConfig = errors.New("dbgorm: missing connection fields") )
Functions ¶
func AutoMigrate ¶ added in v0.1.23
AutoMigrate runs GORM auto-migration for all provided model types.
Example ¶
ExampleAutoMigrate shows how to create database tables from GORM model structs. Pass all models in a single call; AutoMigrate creates or updates each table in order.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
)
func main() {
ctx := context.Background()
dialector, _ := sqlite.Dialector(&sqlite.Config{Path: ":memory:"})
db, _ := libgorm.Open(dialector, &libgorm.GormConfig{MaxOpenConns: 1})
type Article struct {
ID uint `gorm:"primaryKey"`
Title string
}
type Tag struct {
ID uint `gorm:"primaryKey"`
Name string
}
err := libgorm.AutoMigrate(ctx, db, &Article{}, &Tag{})
fmt.Println(err == nil)
fmt.Println(db.Migrator().HasTable(&Article{}))
fmt.Println(db.Migrator().HasTable(&Tag{}))
}
Output: true true true
func Close ¶
Close closes the underlying database/sql connection for db.
Example ¶
ExampleClose shows how to close a GORM database obtained from an adapter. Close is a no-op when db is nil.
package main
import (
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
db := exDB()
err := libgorm.Close(db)
fmt.Println(err == nil)
}
Output: true
func Create ¶ added in v0.1.23
Create inserts record into the database and returns the created record. The returned pointer reflects auto-populated fields (primary key, timestamps, etc.).
Example ¶
ExampleCreate shows how to insert a new record and retrieve its auto-populated fields.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
created, err := libgorm.Create(ctx, db, &exProduct{Name: "chisel", Category: "tools"})
fmt.Println(err == nil)
fmt.Println(created.ID > 0) // primary key populated by the database
fmt.Println(created.Name)
}
Output: true true chisel
func Default ¶
Default returns the process-wide default GORM database instance.
Example ¶
ExampleDefault shows how to retrieve the process-wide default *gorm.DB.
package main
import (
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
)
func main() {
prev := libgorm.Default()
libgorm.SetDefault(nil)
defer libgorm.SetDefault(prev) // restore after example
fmt.Println(libgorm.Default() == nil) // nil — not yet initialised
}
Output: true
func DeleteByID ¶
DeleteByID deletes the record of type T matching the primary key id.
Example ¶
ExampleDeleteByID shows how to delete a record by primary key. Returns gorm.ErrRecordNotFound when no row is deleted.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
p := &exProduct{Name: "bolt"}
db.Create(p)
err := libgorm.DeleteByID[exProduct](ctx, db, p.ID)
fmt.Println(err == nil)
// Deleting again returns not-found.
fmt.Println(libgorm.IsNotFound(libgorm.DeleteByID[exProduct](ctx, db, p.ID)))
}
Output: true true
func DeleteWhere ¶
DeleteWhere deletes records for model matching query and args.
Example ¶
ExampleDeleteWhere shows how to delete all records matching a condition. Zero affected rows is treated as success.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "nail", Category: "fasteners"})
db.Create(&exProduct{Name: "screw", Category: "fasteners"})
err := libgorm.DeleteWhere(ctx, db, &exProduct{}, "category = ?", "fasteners")
fmt.Println(err == nil)
}
Output: true
func ExecRaw ¶
ExecRaw executes a raw SQL statement with positional arguments.
Example ¶
ExampleExecRaw shows how to execute a raw SQL statement with positional args.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
p := &exProduct{Name: "gear", Category: "parts"}
db.Create(p)
rows, err := libgorm.ExecRaw(ctx, db,
"UPDATE ex_products SET category = ? WHERE id = ?", "machinery", p.ID)
fmt.Println(err == nil)
fmt.Println(rows) // 1 row updated
}
Output: true 1
func FirstByID ¶
FirstByID returns the first record of type T matching the primary key id.
Example ¶
ExampleFirstByID shows how to fetch a record by primary key. Returns gorm.ErrRecordNotFound when no row matches.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
p := &exProduct{Name: "widget", Category: "tools"}
db.Create(p)
found, err := libgorm.FirstByID[exProduct](ctx, db, p.ID)
fmt.Println(err == nil)
fmt.Println(found.Name)
}
Output: true widget
func FirstWhere ¶
FirstWhere returns the first record of type T matching query and args.
Example ¶
ExampleFirstWhere shows how to fetch the first record matching a condition.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "hammer", Category: "tools"})
db.Create(&exProduct{Name: "wrench", Category: "tools"})
found, err := libgorm.FirstWhere[exProduct](ctx, db, "name = ?", "wrench")
fmt.Println(err == nil)
fmt.Println(found.Name)
}
Output: true wrench
func HealthChecker ¶
HealthChecker returns a health.Checker that verifies database connectivity by pinging the default GORM database.
The Checker is dialect-agnostic — it works with any driver (MySQL, PostgreSQL, SQLite, …) that was used to initialise Default. Reports health.StatusUnhealthy when Default() is nil or when the ping fails; health.StatusHealthy when reachable.
Example ¶
ExampleHealthChecker shows how to wire HealthChecker into a health.Check call for a /health HTTP endpoint.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/health"
)
func main() {
prev := libgorm.Default()
libgorm.SetDefault(nil)
defer libgorm.SetDefault(prev)
results := health.Check(context.Background(), libgorm.HealthChecker())
fmt.Println(results[0].Name)
fmt.Println(results[0].Status == health.StatusUnhealthy) // true — Default() is nil
}
Output: database true
func IsNotFound ¶
IsNotFound reports whether err represents GORM's record-not-found condition.
Example ¶
ExampleIsNotFound shows how to distinguish a not-found error from other database errors. Use it instead of comparing directly against gorm.ErrRecordNotFound.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
_, err := libgorm.FirstByID[exProduct](ctx, db, 9999)
fmt.Println(libgorm.IsNotFound(err)) // true — no row with id=9999
}
Output: true
func IsSafeSQLIdentifierPath ¶ added in v0.1.26
IsSafeSQLIdentifierPath reports whether value is a dot-separated path of safe SQL identifiers (e.g. "table.column"), guarding SortSql against injection via the Sort field. Exported so dialect packages building their own ORDER BY expressions (e.g. ChineseSortSql in dbgorm/postgres, dbgorm/mysql) can validate a column name with the same rules.
func IsSafeSQLName ¶ added in v0.1.26
IsSafeSQLName reports whether value is a safe single SQL identifier: letters, digits (not leading), and underscores only. Also usable to validate a charset/encoding name interpolated directly into SQL (e.g. by ChineseSortSql), since it follows the same safe-token shape.
func NormalizeSortDirection ¶ added in v0.1.26
NormalizeSortDirection returns direction upper-cased and trimmed, falling back to "ASC" when it is empty or not one of "ASC"/"DESC". Exported so dialect packages building their own ORDER BY expressions (e.g. ChineseSortSql in dbgorm/postgres, dbgorm/mysql) apply the exact same direction rules SortSql does.
func Open ¶
Open opens a GORM database using the supplied dialector and common config.
Example ¶
ExampleOpen shows the low-level Open API using a GORM dialector directly. Prefer the adapter packages (dbgorm/mysql, dbgorm/postgres, dbgorm/sqlite) for application code.
package main
import (
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
)
func main() {
dialector, _ := sqlite.Dialector(&sqlite.Config{Path: ":memory:"})
db, err := libgorm.Open(dialector, &libgorm.GormConfig{
MaxOpenConns: 1,
MaxIdleConns: 1,
})
fmt.Println(err == nil)
fmt.Println(db != nil)
}
Output: true true
func OrderBy ¶
OrderBy returns a GORM scope that orders by an allow-listed column.
Example ¶
ExampleOrderBy shows how to apply an allow-listed column sort as a GORM scope.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "zebra"})
db.Create(&exProduct{Name: "apple"})
db.Create(&exProduct{Name: "mango"})
allowed := map[string]string{"name": "name"}
var results []exProduct
db.WithContext(ctx).Scopes(libgorm.OrderBy(allowed, "name", "ASC")).Find(&results)
fmt.Println(results[0].Name)
fmt.Println(results[2].Name)
}
Output: apple zebra
func PageSql ¶
func PageSql(para *dto.PageParameter) string
PageSql builds a LIMIT/OFFSET SQL clause from the pagination fields in para. When Limit is -1, all records are returned without a LIMIT clause. Defaults to page 1 and defaultPageLimit when values are unset or invalid; caps Limit at maxPageLimit and Page at maxPage.
Page and Limit are ints, not strings, so — unlike Sort — they carry no SQL injection risk: strconv.Itoa on an int can only ever produce a plain decimal digit string. The Page cap here is a resource-usage guard instead, not a security fix: without it, an arbitrarily large Page still produces a syntactically valid but enormous OFFSET that the database must count past before returning zero rows.
func Paginate ¶
Paginate returns a GORM scope that applies limit and offset pagination. Caps limit at maxPageLimit and page at maxPage — see PageSql's doc comment for why an unbounded page is a resource-usage guard, not a security fix.
Example ¶
ExamplePaginate shows how to apply limit/offset pagination as a GORM scope.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
for i := range 5 {
db.Create(&exProduct{Name: fmt.Sprintf("item-%d", i)})
}
var page []exProduct
db.WithContext(ctx).Scopes(libgorm.Paginate(1, 3)).Find(&page)
fmt.Println(len(page)) // page 1, limit 3
}
Output: 3
func ScanRaw ¶
ScanRaw executes a raw SQL query and scans the result into dest.
Example ¶
ExampleScanRaw shows how to scan a scalar result (e.g. COUNT) from a raw query.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "pin", Category: "fasteners"})
db.Create(&exProduct{Name: "clip", Category: "fasteners"})
var total int64
err := libgorm.ScanRaw(ctx, db, &total,
"SELECT COUNT(*) FROM ex_products WHERE category = ?", "fasteners")
fmt.Println(err == nil)
fmt.Println(total)
}
Output: true 2
Example (MultipleRows) ¶
ExampleScanRaw_multipleRows shows how to scan all matching rows into a slice. Pass a pointer to a slice as dest to collect every returned row.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "nail", Category: "fasteners"})
db.Create(&exProduct{Name: "bolt", Category: "fasteners"})
db.Create(&exProduct{Name: "screw", Category: "fasteners"})
var products []exProduct
err := libgorm.ScanRaw(ctx, db, &products,
"SELECT * FROM ex_products WHERE category = ? ORDER BY name", "fasteners")
fmt.Println(err == nil)
fmt.Println(len(products))
fmt.Println(products[0].Name)
}
Output: true 3 bolt
Example (SingleRow) ¶
ExampleScanRaw_singleRow shows how to scan the first matching row into a struct. Only the first row is populated; additional rows are discarded.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "hammer", Category: "tools"})
var p exProduct
err := libgorm.ScanRaw(ctx, db, &p,
"SELECT * FROM ex_products WHERE name = ?", "hammer")
fmt.Println(err == nil)
fmt.Println(p.Name)
}
Output: true hammer
func SetDefault ¶
SetDefault replaces the process-wide default GORM database instance.
Example ¶
ExampleSetDefault shows how to store a *gorm.DB as the process-wide default. Call SetDefault once at application startup after opening the database.
package main
import (
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
prev := libgorm.Default()
defer libgorm.SetDefault(prev) // restore after example
libgorm.SetDefault(exDB())
fmt.Println(libgorm.Default() != nil)
}
Output: true
func SortSql ¶
func SortSql(para *dto.PageParameter) string
SortSql builds an ORDER BY SQL clause from the sort fields in para. Defaults to ordering by "id ASC" when Sort is empty or unsafe.
SortSql only ever produces a plain "ORDER BY <column> <direction>" clause — it deliberately has no locale/charset-aware sorting, since that requires a database-specific SQL function (e.g. PostgreSQL's convert_to, MySQL's CONVERT(... USING ...)) that this dialect-agnostic root package cannot pick correctly on its own. For approximate pinyin ordering of Chinese text, see the dedicated ChineseSortSql in the relevant dialect package (dbgorm/postgres, dbgorm/mysql) instead.
func UpdateByID ¶ added in v0.1.22
UpdateByID updates columns of the record of type T matching the primary key id. values may be a struct (only non-zero fields are updated) or a map[string]any (all specified keys are updated regardless of zero value). Returns gorm.ErrRecordNotFound when no row is matched.
Example ¶
ExampleUpdateByID shows how to update specific columns of a record by primary key. Pass a struct to update only non-zero fields, or a map[string]any to update all specified keys regardless of zero value.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
p := &exProduct{Name: "wrench", Category: "tools"}
db.Create(p)
// Update a single field using a map to avoid zero-value filtering.
err := libgorm.UpdateByID[exProduct](ctx, db, p.ID, map[string]any{"category": "hardware"})
fmt.Println(err == nil)
// Verify the update.
updated, _ := libgorm.FirstByID[exProduct](ctx, db, p.ID)
fmt.Println(updated.Category)
// Returns ErrRecordNotFound when no row matches.
fmt.Println(libgorm.IsNotFound(libgorm.UpdateByID[exProduct](ctx, db, 9999, map[string]any{"name": "x"})))
}
Output: true hardware true
Example (Struct) ¶
ExampleUpdateByID_struct shows how to update using a struct value. Only non-zero fields are written — zero values (empty string, 0, false, …) are silently skipped. Use a map[string]any when zero values must be persisted.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
p := &exProduct{Name: "hammer", Category: "tools"}
db.Create(p)
// Only Category is non-zero, so only that column is updated.
err := libgorm.UpdateByID[exProduct](ctx, db, p.ID, exProduct{Category: "hand-tools"})
fmt.Println(err == nil)
updated, _ := libgorm.FirstByID[exProduct](ctx, db, p.ID)
fmt.Println(updated.Name) // unchanged — Name was zero in the struct
fmt.Println(updated.Category) // updated
}
Output: true hammer hand-tools
func UpdateWhere ¶ added in v0.1.23
func UpdateWhere(ctx context.Context, db *gorm.DB, model any, values any, query any, args ...any) error
UpdateWhere updates columns of all records for model matching query and args. values may be a struct (only non-zero fields are updated) or a map[string]any (all specified keys are updated regardless of zero value). Zero affected rows is treated as success, consistent with DeleteWhere.
Example ¶
ExampleUpdateWhere shows how to update all records matching a condition. Zero affected rows is treated as success, consistent with DeleteWhere.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "nail", Category: "fasteners"})
db.Create(&exProduct{Name: "bolt", Category: "fasteners"})
db.Create(&exProduct{Name: "brush", Category: "painting"})
// Promote all fasteners to the "hardware" category.
err := libgorm.UpdateWhere(ctx, db, &exProduct{}, map[string]any{"category": "hardware"}, "category = ?", "fasteners")
fmt.Println(err == nil)
var count int64
db.Model(&exProduct{}).Where("category = ?", "hardware").Count(&count)
fmt.Println(count) // nail + bolt
}
Output: true 2
Example (Struct) ¶
ExampleUpdateWhere_struct shows how to pass a struct as values. Only non-zero fields in the struct are written to the database.
package main
import (
"context"
"fmt"
libgorm "github.com/phcp-tech/common-library-golang/dbgorm"
"github.com/phcp-tech/common-library-golang/dbgorm/sqlite"
"gorm.io/gorm"
)
// exProduct is a minimal GORM model used by the example functions.
type exProduct struct {
ID uint `gorm:"primaryKey"`
Name string
Category string
}
// exDB opens a private in-memory SQLite database and migrates exProduct.
// Each call returns an independent database — no shared state between examples.
func exDB() *gorm.DB {
db, err := sqlite.NewSQLite(&sqlite.Config{Path: ":memory:"})
if err != nil {
panic("exDB: " + err.Error())
}
if err := db.AutoMigrate(&exProduct{}); err != nil {
panic("exDB migrate: " + err.Error())
}
return db
}
func main() {
ctx := context.Background()
db := exDB()
db.Create(&exProduct{Name: "saw", Category: "tools"})
db.Create(&exProduct{Name: "drill", Category: "tools"})
// Category is the only non-zero field — Name is left unchanged.
err := libgorm.UpdateWhere(ctx, db, &exProduct{}, exProduct{Category: "power-tools"}, "name = ?", "drill")
fmt.Println(err == nil)
updated, _ := libgorm.FirstWhere[exProduct](ctx, db, "name = ?", "drill")
fmt.Println(updated.Name)
fmt.Println(updated.Category)
}
Output: true drill power-tools
Types ¶
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
component
Package component provides GORM ClickHouse lifecycle integration for bootstrap.
|
Package component provides GORM ClickHouse lifecycle integration for bootstrap. |
|
component
Package component provides GORM MySQL lifecycle integration for bootstrap.
|
Package component provides GORM MySQL lifecycle integration for bootstrap. |
|
component
Package component provides GORM PostgreSQL lifecycle integration for bootstrap.
|
Package component provides GORM PostgreSQL lifecycle integration for bootstrap. |
|
component
Package component provides GORM SQLite lifecycle integration for bootstrap.
|
Package component provides GORM SQLite lifecycle integration for bootstrap. |
|
vfs
Package vfs opens a SQLite database embedded inside a Go binary using modernc.org/sqlite/vfs and Go's embed.FS.
|
Package vfs opens a SQLite database embedded inside a Go binary using modernc.org/sqlite/vfs and Go's embed.FS. |