gomodel

package module
v2.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

README

GoModel

Go Reference Bitbucket Pipelines

See CHANGELOG.md for the release history and UPGRADING.md for migration guides between major versions.

Installation

go get bitbucket.org/amotus/gomodel/v2@latest

Users still on v1 can keep importing bitbucket.org/amotus/gomodel; see Versioning below.

Usages

Implement the ModelInterface in your model

type MyModel struct {
    Id           int64           `gorm:"primaryKey"`
    DeletedAt    *gorm.DeletedAt `json:"deleted_at"`
}

func (d *MyModel) GetId() int64 {
	return d.Id
}
func (d *MyModel) SetId(id int64) {
	d.Id = id
}

func (d *MyModel) Query(db *gorm.DB, withTrash bool) *gorm.DB {
	if withTrash {
		return db.Unscoped().Model(&MyModel{})
	}
	return db.Model(&MyModel{})
}

The primary key is not restricted to int64: any comparable type works, for example uuid.UUID or string. Just declare GetId / SetId with that type.

Use Model[M, K]

once your struct implement the interface ModelInterface, you can use the New function to get a Model[M, K] object, where M is your model type and K the type of its primary key. Both are inferred by the compiler.

modelPointer := gomodel.New(db, &MyModel{})

It is recommended to define a helper function in your model namespace

func NewMyModel(db *gorm.DB) *gomodel.Model[*MyModel, int64] {
    return gomodel.New(db, &MyModel{})
}
Use the Model[M, K] object
// Create a new model
modelPointer := NewMyModel(db)

// Create a new model with data, *data is not saved to the database
modelPointer := NewMyModel(db).Set(&MyModel{
    Id: 1,
})
Model[M, K] methods
Type Chainable Ends
Accessor Get, Query
Data Accessor (query db) Find, First, Select, Load, Fresh, Take, Skip All, Exist, Count
Mutator With, WithTrashed, Where, WhereGroup
Data Mutator Create, Update, UpdateAll,
CreateOrUpdate, CreateOrUpdateAll
Save, Delete, Restore
Save model to the database

Save is not chainable, it returns error if any


err := modelPointer.Save()
if err != nil {
    // Handle error
}
Create

Use directly the Create function to save into database a new model.

Create is chainable, it returns the model and in case of error, it is embedded in the model:

modelPointer := NewMyModel(db).Create(&MyModel{
    Id: 1,
})

if modelPointer.Err != nil {
    // Handle error
}
Find

Get a model from the database

Find is chainable, it returns the model and in case of error, it is embedded in the model:

modelStruct := NewMyModel(db).Find(1)
if modelPointer.Err != nil {
    // Handle error
}
OrderBy

Set the order of the objects returned by the query

OrderBy is chainable but must be used after a query is set:

all, err := NewMyModel(db).OrderBy("id", gomodel.ASC).All()
if err != nil {
    // Handle error
}
First

Get a model from the database using the first row corresponding to the query

First is chainable, it returns the model and in case of error, it is embedded in the model:

modelStruct := NewMyModel(db).First()
if modelPointer.Err != nil {
    // Handle error
}

modelStruct := NewMyModel(db).Where("id = ?", 1).First()
if modelPointer.Err != nil {
    // Handle error
}
Select

Select allows you to specify the fields that you want to retrieve from database. Otherwise, GORM will select all fields by default.

_ = NewMyModel(db).Select("name", "age").First()
_ = NewMyModel(db).Select([]string{"name", "age"}).First()
_ = NewMyModel(db).Select("COALESCE(age,?)", 42).First()
Grouping Where Conditions

modelStruct, err := NewMyModel(db).WhereGroup(func(q *gorm.DB) *gorm.DB { return q.Where("name = ?", "jane").Or("name = ?", "doe") }).First()
if err != nil {
    // Handle error
}
All

Get all model from the database

// perform any filter on the db object before creating the model object.
//db = db.Scopes(isProject(1)) 

items, errDb := NewMyModel(db).All()
if errDb != nil {
    // Handle error
}
for _, item := range items {
    fmt.println(item)
}
Take & Skip

Limits the number of rows returned by the query

items, errDb := NewMyModel(db).Take(10).Skip(5).All()
Count

Count the number of rows returned by the query

c, errDb := NewMyModel(db).Count()
Fresh

Refresh the model from the database

Fresh is chainable, it returns the model and in case of error, it is embedded in the model:

modelPointer.Fresh()
if modelPointer.Err != nil {
    // Handle error
}
Relations

Load relations of a model using the With function

item, errDb := NewMyModel(db).With("relation1", "relation2").Find(1).Get()
if errDb != nil {
    // Handle error
}
fmt.println(item.Relation1, item.Relation2)

If you already have a model loaded, you can use the Load function to add relations immediately

modelPointer.Load("relation1", "relation2") //Load will perform a Fresh() after adding relations

item, errDb := modelPointer.Get()
if errDb != nil {
    // Handle error
}
fmt.println(item.Relation1, item.Relation2)
Update

Update a model in database.

Update is chainable, it returns the model and in case of error, it is embedded in the model:

modelPointer := NewMyModel(db).Update(&MyModel{
    Name: "updated name",
})

if modelPointer.Err != nil {
    // Handle error
}

NOTE Update will not refresh the model, you need to call Fresh() to get the updated model from the database

NOTE When updating with struct, GORM will only update non-zero fields. You might want to use updateAll to update all attributes

UpdateAll
modelPointer := NewMyModel(db).UpdateAll(&MyModel{
    Name: "updated name",
	Count: 0,
})

if modelPointer.Err != nil {
    // Handle error
}

Count property (and also all non-set properties) will be updated to 0 while using updateAll

Create or Update

CreateOrUpdate is chainable, it returns the model and in case of error, it is embedded in the model:

modelPointer := NewMyModel(db).CreateOrUpdate(&MyModel{
    Id: 1,
})
if modelPointer.Err != nil {
    // Handle error
}
Delete a model

given the model id 1

errDb := modelPointer.Delete()
if errDb != nil {
    // Handle error
}
Restore a model
errDb := modelPointer.Restore()
if errDb != nil {
    // Handle error
}
Soft Delete

Use WithTrash to query model with deleted items included


exist, errDb := NewMyModel(db).WithTrash().Set(&MyModel{ Id: 1}).Exist()
if errDb != nil {
    // Handle error
}

Find methods doesn't use WithTrash, it will return the model only if it isn't trashed

Look at the model_test.go file for more examples

Versioning

This module follows Semantic Versioning and releases are documented in CHANGELOG.md.

Major versions use the major branch strategy: main always holds the latest major version, and each previous major keeps a maintenance branch.

Major Import path Branch Status
v2 bitbucket.org/amotus/gomodel/v2 main Active development
v1 bitbucket.org/amotus/gomodel v1 Bug and security fixes

If you installed v1 from the default branch (@main), pin it to @v1.2.12 instead — main now holds v2.

Breaking changes are only released in a new major version, with a migration guide in UPGRADING.md.

Maintainers

License

Proprietary © Dimonoff

Documentation

Overview

Package gomodel provides a simple and eloquent way to interact with the GORM ORM.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Create

func Create[K comparable](db *gorm.DB, m ModelInterface[K]) error

Create a new model in the database.

func CreateOrUpdate

func CreateOrUpdate[K comparable](db *gorm.DB, m ModelInterface[K]) error

CreateOrUpdate a new model in the database or update it if it already exists.

func CreateOrUpdateAll

func CreateOrUpdateAll[K comparable](db *gorm.DB, m ModelInterface[K]) error

CreateOrUpdateAll a new model in the database or update it if it already exists.

func Delete

func Delete[K comparable](db *gorm.DB, m ModelInterface[K], id K) error

Delete the model from the database. If ModelInterface has a deleted_at field, it will be set to the current time.

The id is always bound as a query parameter. Passing it to GORM as an inline condition would let a string key be interpreted as raw SQL.

func Exist

func Exist[K comparable](db *gorm.DB, m ModelInterface[K], id K, withTrashed bool) (bool, error)

Exist return true if the model with the primary key (id) exists in the database.

func Find

func Find[M ModelInterface[K], K comparable](db *gorm.DB, m M, id K, relations ...string) (M, error)

Find the model for a given id.

func FindWithTrashed

func FindWithTrashed[M ModelInterface[K], K comparable](db *gorm.DB, m M, id K, withTrashed bool, relations ...string) (M, error)

FindWithTrashed the model for a given id. When withTrashed is true, soft-deleted rows are included.

func MustExist

func MustExist[K comparable](db *gorm.DB, m ModelInterface[K], id K, withTrashed bool) bool

MustExist return true if the model with the primary key (id) exists in the database. Panic if an error occurs.

func Restore

func Restore[K comparable](db *gorm.DB, m ModelInterface[K], id K) error

Restore the model in the database. The deleted_at field will be set to nil.

func Update

func Update[K comparable](db *gorm.DB, m ModelInterface[K]) error

Update the model in the database.

func UpdateAll

func UpdateAll[K comparable](db *gorm.DB, m ModelInterface[K]) error

UpdateAll update the model in the database, even nil value

Types

type Model

type Model[M ModelInterface[K], K comparable] struct {
	Base        M
	DB          *gorm.DB
	FilterQuery *gorm.DB

	Err error
	// contains filtered or unexported fields
}

Model is a chainable query builder around a ModelInterface implementation. M is the model type and K the type of its primary key.

Errors are carried by the chain in Err and surfaced by the terminal methods (Get, Save, All, ...), so intermediate calls can be chained without checking an error after every step.

func New

func New[M ModelInterface[K], K comparable](db *gorm.DB, m M) *Model[M, K]

New instantiate a new Model for the given M type.

func (*Model[M, K]) All

func (m *Model[M, K]) All() ([]M, error)

All get all models from the database. returns []t

func (*Model[M, K]) Count

func (m *Model[M, K]) Count() (int64, error)

Count return the number of models for the given query.

func (*Model[M, K]) Create

func (m *Model[M, K]) Create(model M) *Model[M, K]

Create a new model in the database.

func (*Model[M, K]) CreateOrUpdate

func (m *Model[M, K]) CreateOrUpdate(model M) *Model[M, K]

CreateOrUpdate a new model in the database or update it if it already exists.

func (*Model[M, K]) CreateOrUpdateAll

func (m *Model[M, K]) CreateOrUpdateAll(model M) *Model[M, K]

CreateOrUpdateAll a new model in the database or update it if it already exists.

func (*Model[M, K]) Delete

func (m *Model[M, K]) Delete() error

Delete soft delete the model from the database.

func (*Model[M, K]) Exist

func (m *Model[M, K]) Exist() (bool, error)

Exist return true if the model with the primary key (id) exists in the database.

func (*Model[M, K]) Find

func (m *Model[M, K]) Find(id K) *Model[M, K]

Find the model for a given id.

func (*Model[M, K]) First

func (m *Model[M, K]) First() *Model[M, K]

First return the first model corresponding to query.

func (*Model[M, K]) Fresh

func (m *Model[M, K]) Fresh() *Model[M, K]

Fresh reload the model from the database.

func (*Model[M, K]) Get

func (m *Model[M, K]) Get() (M, error)

Get the model for a given id set on the model.

func (*Model[M, K]) Load

func (m *Model[M, K]) Load(relations ...string) *Model[M, K]

Load sets the relations ande load them from the database

func (*Model[M, K]) MustCreate

func (m *Model[M, K]) MustCreate(model M) *Model[M, K]

MustCreate a new model in the database. Panic if an error occurs.

func (*Model[M, K]) MustCreateOrUpdate

func (m *Model[M, K]) MustCreateOrUpdate(model M) *Model[M, K]

MustCreateOrUpdate a new model in the database or update it if it already exists. Panic if an error occurs.

func (*Model[M, K]) MustExist

func (m *Model[M, K]) MustExist() bool

MustExist return true if the model with the primary key (id) exists in the database. Panic if an error occurs.

func (*Model[M, K]) MustUpdate

func (m *Model[M, K]) MustUpdate(model M) *Model[M, K]

MustUpdate the model in the database. Panic if an error occurs.

func (*Model[M, K]) OrderBy

func (m *Model[M, K]) OrderBy(field string, sortDirection SortDirection) *Model[M, K]

OrderBy Allows to set the order

func (*Model[M, K]) Query

func (m *Model[M, K]) Query() *gorm.DB

Query return a new query builder for the model's table.

func (*Model[M, K]) Restore

func (m *Model[M, K]) Restore() error

Restore restore a soft-deleted model instance. Set deleted_at to null.

func (*Model[M, K]) Save

func (m *Model[M, K]) Save() error

Save the model to the database. If the model doesn't exist yet, it will be created. Otherwise, it will be updated.

func (*Model[M, K]) Select

func (m *Model[M, K]) Select(query interface{}, params ...interface{}) *Model[M, K]

Select allows you to specify the fields that you want to retrieve from database. Otherwise, GORM will select all fields by default.

func (*Model[M, K]) Set

func (m *Model[M, K]) Set(model M) *Model[M, K]

Set sets the internal model to the given model, but doesn't save it to the database.

func (*Model[M, K]) Skip

func (m *Model[M, K]) Skip(offset int) *Model[M, K]

Skip specify the number of records to skip before starting to return the records

model.Skip(5).All() // return 5 rows

func (*Model[M, K]) Take

func (m *Model[M, K]) Take(limit int) *Model[M, K]

Take limits the numbers of row returned.

model.Take(5).All() // return 5 rows

func (*Model[M, K]) Update

func (m *Model[M, K]) Update(model M) *Model[M, K]

Update the model in the database.

func (*Model[M, K]) UpdateAll

func (m *Model[M, K]) UpdateAll(model M) *Model[M, K]

UpdateAll the model in the database, including its zero values.

func (*Model[M, K]) Where

func (m *Model[M, K]) Where(query string, params ...interface{}) *Model[M, K]

Where filters the query with a given condition.

Find the first user with name dom
model.Where("name = ?", "dom").First()

func (*Model[M, K]) WhereGroup

func (m *Model[M, K]) WhereGroup(query func(q *gorm.DB) *gorm.DB) *Model[M, K]

func (*Model[M, K]) With

func (m *Model[M, K]) With(relations ...string) *Model[M, K]

With sets the relations to be loaded when querying the database.

func (*Model[M, K]) WithTrashed

func (m *Model[M, K]) WithTrashed() *Model[M, K]

WithTrashed returns a new Model with the withTrashed flag set to true.

type ModelInterface

type ModelInterface[K comparable] interface {
	// GetId returns the model's primary key.
	GetId() K
	// SetId sets the model's primary key.
	SetId(K)
	// Query returns the base query for the model's table. When withTrashed is
	// true, soft-deleted rows are included.
	Query(*gorm.DB, bool) *gorm.DB
}

ModelInterface is implemented by every model managed by Model. K is the type of the model's primary key, which must be comparable so that a model can be told apart from its zero value.

type SortDirection

type SortDirection int

SortDirection Enum used to sort the results of a query

const (
	ASC SortDirection = iota
	DESC
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL