mirror of https://github.com/go-gorm/gorm.git
Update godoc
This commit is contained in:
parent
779c4d436e
commit
88184a989e
18
callback.go
18
callback.go
|
@ -7,13 +7,13 @@ import (
|
||||||
// DefaultCallback default callbacks defined by gorm
|
// DefaultCallback default callbacks defined by gorm
|
||||||
var DefaultCallback = &Callback{}
|
var DefaultCallback = &Callback{}
|
||||||
|
|
||||||
// Callback contains callbacks that used when CURD objects
|
// Callback is a struct that contains all CURD callbacks
|
||||||
// Field `creates` hold callbacks will be call when creating object
|
// Field `creates` contains callbacks will be call when creating object
|
||||||
// Field `updates` hold callbacks will be call when updating object
|
// Field `updates` contains callbacks will be call when updating object
|
||||||
// Field `deletes` hold callbacks will be call when deleting object
|
// Field `deletes` contains callbacks will be call when deleting object
|
||||||
// Field `queries` hold callbacks will be call when querying object with query methods like Find, First, Related, Association...
|
// Field `queries` contains callbacks will be call when querying object with query methods like Find, First, Related, Association...
|
||||||
// Field `rowQueries` hold callbacks will be call when querying object with Row, Rows...
|
// Field `rowQueries` contains callbacks will be call when querying object with Row, Rows...
|
||||||
// Field `processors` hold all callback processors, will be used to generate above callbacks in order
|
// Field `processors` contains all callback processors, will be used to generate above callbacks in order
|
||||||
type Callback struct {
|
type Callback struct {
|
||||||
creates []*func(scope *Scope)
|
creates []*func(scope *Scope)
|
||||||
updates []*func(scope *Scope)
|
updates []*func(scope *Scope)
|
||||||
|
@ -23,7 +23,7 @@ type Callback struct {
|
||||||
processors []*CallbackProcessor
|
processors []*CallbackProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallbackProcessor contains all informations for a callback
|
// CallbackProcessor contains callback informations
|
||||||
type CallbackProcessor struct {
|
type CallbackProcessor struct {
|
||||||
name string // current callback's name
|
name string // current callback's name
|
||||||
before string // register current callback before a callback
|
before string // register current callback before a callback
|
||||||
|
@ -68,7 +68,7 @@ func (c *Callback) Delete() *CallbackProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query could be used to register callbacks for querying objects with query methods like `Find`, `First`, `Related`, `Association`...
|
// Query could be used to register callbacks for querying objects with query methods like `Find`, `First`, `Related`, `Association`...
|
||||||
// refer `Create` for usage
|
// Refer `Create` for usage
|
||||||
func (c *Callback) Query() *CallbackProcessor {
|
func (c *Callback) Query() *CallbackProcessor {
|
||||||
return &CallbackProcessor{kind: "query", parent: c}
|
return &CallbackProcessor{kind: "query", parent: c}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ type Dialect interface {
|
||||||
// HasColumn check has column or not
|
// HasColumn check has column or not
|
||||||
HasColumn(tableName string, columnName string) bool
|
HasColumn(tableName string, columnName string) bool
|
||||||
|
|
||||||
// LimitAndOffsetSQL return generate SQL with limit and offset, as mssql has special case
|
// LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case
|
||||||
LimitAndOffsetSQL(limit, offset int) string
|
LimitAndOffsetSQL(limit, offset int) string
|
||||||
// SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
|
// SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
|
||||||
SelectFromDummyTable() string
|
SelectFromDummyTable() string
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrRecordNotFound record not found, happens when you are looking up with a struct, and haven't find any matched data
|
// ErrRecordNotFound record not found error, happens when haven't find any matched data when looking up with a struct
|
||||||
ErrRecordNotFound = errors.New("record not found")
|
ErrRecordNotFound = errors.New("record not found")
|
||||||
// ErrInvalidSQL invalid SQL, happens when you passed invalid SQL
|
// ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL
|
||||||
ErrInvalidSQL = errors.New("invalid SQL")
|
ErrInvalidSQL = errors.New("invalid SQL")
|
||||||
// ErrInvalidTransaction invalid transaction when you are trying to `Commit` or `Rollback`
|
// ErrInvalidTransaction invalid transaction when you are trying to `Commit` or `Rollback`
|
||||||
ErrInvalidTransaction = errors.New("no valid transaction")
|
ErrInvalidTransaction = errors.New("no valid transaction")
|
||||||
|
|
89
main.go
89
main.go
|
@ -26,14 +26,17 @@ type DB struct {
|
||||||
joinTableHandlers map[string]JoinTableHandler
|
joinTableHandlers map[string]JoinTableHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open open a new db connection, need to import driver first, for example:
|
// Open initialize a new db connection, need to import driver first, e.g:
|
||||||
//
|
//
|
||||||
// import _ "github.com/go-sql-driver/mysql"
|
// import _ "github.com/go-sql-driver/mysql"
|
||||||
// func main() {
|
// func main() {
|
||||||
// db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
|
// db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
|
||||||
// }
|
// }
|
||||||
// GORM has wrapped some drivers, for easier to remember its name, so you could import the mysql driver with
|
// GORM has wrapped some drivers, for easier to remember driver's import path, so you could import the mysql driver with
|
||||||
// import _ "github.com/jinzhu/gorm/dialects/mysql"
|
// import _ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
// // import _ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
// // import _ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
|
// // import _ "github.com/jinzhu/gorm/dialects/mssql"
|
||||||
func Open(dialect string, args ...interface{}) (*DB, error) {
|
func Open(dialect string, args ...interface{}) (*DB, error) {
|
||||||
var db DB
|
var db DB
|
||||||
var err error
|
var err error
|
||||||
|
@ -87,7 +90,7 @@ func (s *DB) DB() *sql.DB {
|
||||||
return s.db.(*sql.DB)
|
return s.db.(*sql.DB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New initialize a new db connection without any search conditions
|
// New clone a new db connection without search conditions
|
||||||
func (s *DB) New() *DB {
|
func (s *DB) New() *DB {
|
||||||
clone := s.clone()
|
clone := s.clone()
|
||||||
clone.search = nil
|
clone.search = nil
|
||||||
|
@ -102,16 +105,14 @@ func (s *DB) NewScope(value interface{}) *Scope {
|
||||||
return &Scope{db: dbClone, Search: dbClone.search.clone(), Value: value}
|
return &Scope{db: dbClone, Search: dbClone.search.clone(), Value: value}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommonDB return the underlying sql.DB or sql.Tx instance.
|
// CommonDB return the underlying `*sql.DB` or `*sql.Tx` instance, mainly intended to allow coexistence with legacy non-GORM code.
|
||||||
// Use of this method is discouraged. It's mainly intended to allow
|
|
||||||
// coexistence with legacy non-GORM code.
|
|
||||||
func (s *DB) CommonDB() sqlCommon {
|
func (s *DB) CommonDB() sqlCommon {
|
||||||
return s.db
|
return s.db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback return Callbacks container, you could add/remove/change callbacks with it
|
// Callback return `Callbacks` container, you could add/change/delete callbacks with it
|
||||||
// db.Callback().Create().Register("update_created_at", updateCreated)
|
// db.Callback().Create().Register("update_created_at", updateCreated)
|
||||||
// Refer: https://jinzhu.github.io/gorm/development.html#callbacks for more
|
// Refer https://jinzhu.github.io/gorm/development.html#callbacks
|
||||||
func (s *DB) Callback() *Callback {
|
func (s *DB) Callback() *Callback {
|
||||||
s.parent.callbacks = s.parent.callbacks.clone()
|
s.parent.callbacks = s.parent.callbacks.clone()
|
||||||
return s.parent.callbacks
|
return s.parent.callbacks
|
||||||
|
@ -138,17 +139,17 @@ func (s *DB) SingularTable(enable bool) {
|
||||||
s.parent.singularTable = enable
|
s.parent.singularTable = enable
|
||||||
}
|
}
|
||||||
|
|
||||||
// Where return a new relation, accepts use `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/curd.html#query
|
// Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/curd.html#query
|
||||||
func (s *DB) Where(query interface{}, args ...interface{}) *DB {
|
func (s *DB) Where(query interface{}, args ...interface{}) *DB {
|
||||||
return s.clone().search.Where(query, args...).db
|
return s.clone().search.Where(query, args...).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Or match before conditions or this one, similar to `Where`
|
// Or filter records that match before conditions or this one, similar to `Where`
|
||||||
func (s *DB) Or(query interface{}, args ...interface{}) *DB {
|
func (s *DB) Or(query interface{}, args ...interface{}) *DB {
|
||||||
return s.clone().search.Or(query, args...).db
|
return s.clone().search.Or(query, args...).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not don't match current conditions, similar to `Where`
|
// Not filter records that don't match current conditions, similar to `Where`
|
||||||
func (s *DB) Not(query interface{}, args ...interface{}) *DB {
|
func (s *DB) Not(query interface{}, args ...interface{}) *DB {
|
||||||
return s.clone().search.Not(query, args...).db
|
return s.clone().search.Not(query, args...).db
|
||||||
}
|
}
|
||||||
|
@ -163,18 +164,18 @@ func (s *DB) Offset(offset int) *DB {
|
||||||
return s.clone().search.Offset(offset).db
|
return s.clone().search.Offset(offset).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order specify order when retrieve records from database, pass `true` as the second argument to overwrite `Order` conditions
|
// Order specify order when retrieve records from database, set reorder to `true` to overwrite defined conditions
|
||||||
func (s *DB) Order(value string, reorder ...bool) *DB {
|
func (s *DB) Order(value string, reorder ...bool) *DB {
|
||||||
return s.clone().search.Order(value, reorder...).db
|
return s.clone().search.Order(value, reorder...).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select When querying, specify fields that you want to retrieve from database, by default, will select all fields;
|
// Select specify fields that you want to retrieve from database when querying, by default, will select all fields;
|
||||||
// When creating/updating, specify fields that you want to save to database
|
// When creating/updating, specify fields that you want to save to database
|
||||||
func (s *DB) Select(query interface{}, args ...interface{}) *DB {
|
func (s *DB) Select(query interface{}, args ...interface{}) *DB {
|
||||||
return s.clone().search.Select(query, args...).db
|
return s.clone().search.Select(query, args...).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Omit specify fields that you want to ignore when save to database when creating/updating
|
// Omit specify fields that you want to ignore when saving to database for creating, updating
|
||||||
func (s *DB) Omit(columns ...string) *DB {
|
func (s *DB) Omit(columns ...string) *DB {
|
||||||
return s.clone().search.Omit(columns...).db
|
return s.clone().search.Omit(columns...).db
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,18 @@ func (s *DB) Joins(query string, args ...interface{}) *DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically
|
// Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically
|
||||||
// Refer https://jinzhu.github.io/gorm/curd.html#scopes for more
|
// func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
|
||||||
|
// return db.Where("amount > ?", 1000)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
|
||||||
|
// return func (db *gorm.DB) *gorm.DB {
|
||||||
|
// return db.Scopes(AmountGreaterThan1000).Where("status in (?)", status)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
|
||||||
|
// Refer https://jinzhu.github.io/gorm/curd.html#scopes
|
||||||
func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
|
func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
|
||||||
for _, f := range funcs {
|
for _, f := range funcs {
|
||||||
s = f(s)
|
s = f(s)
|
||||||
|
@ -204,7 +216,7 @@ func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unscoped return all record including deleted record, refer Soft Delete https://jinzhu.github.io/gorm/curd.html#scopes
|
// Unscoped return all record including deleted record, refer Soft Delete https://jinzhu.github.io/gorm/curd.html#soft-delete
|
||||||
func (s *DB) Unscoped() *DB {
|
func (s *DB) Unscoped() *DB {
|
||||||
return s.clone().search.unscoped().db
|
return s.clone().search.unscoped().db
|
||||||
}
|
}
|
||||||
|
@ -245,12 +257,12 @@ func (s *DB) Scan(dest interface{}) *DB {
|
||||||
return s.clone().NewScope(s.Value).Set("gorm:query_destination", dest).callCallbacks(s.parent.callbacks.queries).db
|
return s.clone().NewScope(s.Value).Set("gorm:query_destination", dest).callCallbacks(s.parent.callbacks.queries).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Row return `*sql.Row` with given condtions
|
// Row return `*sql.Row` with given conditions
|
||||||
func (s *DB) Row() *sql.Row {
|
func (s *DB) Row() *sql.Row {
|
||||||
return s.NewScope(s.Value).row()
|
return s.NewScope(s.Value).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rows return `*sql.Rows` with given condtions
|
// Rows return `*sql.Rows` with given conditions
|
||||||
func (s *DB) Rows() (*sql.Rows, error) {
|
func (s *DB) Rows() (*sql.Rows, error) {
|
||||||
return s.NewScope(s.Value).rows()
|
return s.NewScope(s.Value).rows()
|
||||||
}
|
}
|
||||||
|
@ -271,6 +283,8 @@ func (s *DB) ScanRows(rows *sql.Rows, result interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pluck used to query single column from a model as a map
|
// Pluck used to query single column from a model as a map
|
||||||
|
// var ages []int64
|
||||||
|
// db.Find(&users).Pluck("age", &ages)
|
||||||
func (s *DB) Pluck(column string, value interface{}) *DB {
|
func (s *DB) Pluck(column string, value interface{}) *DB {
|
||||||
return s.NewScope(s.Value).pluck(column, value).db
|
return s.NewScope(s.Value).pluck(column, value).db
|
||||||
}
|
}
|
||||||
|
@ -286,6 +300,7 @@ func (s *DB) Related(value interface{}, foreignKeys ...string) *DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FirstOrInit find first matched record or initalize a new one with given conditions (only works with struct, map conditions)
|
// FirstOrInit find first matched record or initalize a new one with given conditions (only works with struct, map conditions)
|
||||||
|
// https://jinzhu.github.io/gorm/curd.html#firstorinit
|
||||||
func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
|
func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
|
||||||
c := s.clone()
|
c := s.clone()
|
||||||
if result := c.First(out, where...); result.Error != nil {
|
if result := c.First(out, where...); result.Error != nil {
|
||||||
|
@ -300,6 +315,7 @@ func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)
|
// FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)
|
||||||
|
// https://jinzhu.github.io/gorm/curd.html#firstorcreate
|
||||||
func (s *DB) FirstOrCreate(out interface{}, where ...interface{}) *DB {
|
func (s *DB) FirstOrCreate(out interface{}, where ...interface{}) *DB {
|
||||||
c := s.clone()
|
c := s.clone()
|
||||||
if result := c.First(out, where...); result.Error != nil {
|
if result := c.First(out, where...); result.Error != nil {
|
||||||
|
@ -340,7 +356,7 @@ func (s *DB) UpdateColumns(values interface{}) *DB {
|
||||||
callCallbacks(s.parent.callbacks.updates).db
|
callCallbacks(s.parent.callbacks.updates).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save update the value in database, if the value doesn't have primary key, will insert it
|
// Save update value in database, if the value doesn't have primary key, will insert it
|
||||||
func (s *DB) Save(value interface{}) *DB {
|
func (s *DB) Save(value interface{}) *DB {
|
||||||
scope := s.clone().NewScope(value)
|
scope := s.clone().NewScope(value)
|
||||||
if scope.PrimaryKeyZero() {
|
if scope.PrimaryKeyZero() {
|
||||||
|
@ -355,7 +371,7 @@ func (s *DB) Create(value interface{}) *DB {
|
||||||
return scope.callCallbacks(s.parent.callbacks.creates).db
|
return scope.callCallbacks(s.parent.callbacks.creates).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete delete value that match given conditions, if the value has primary key, then will including the primary key as condition
|
// Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition
|
||||||
func (s *DB) Delete(value interface{}, where ...interface{}) *DB {
|
func (s *DB) Delete(value interface{}, where ...interface{}) *DB {
|
||||||
return s.clone().NewScope(value).inlineCondition(where...).callCallbacks(s.parent.callbacks.deletes).db
|
return s.clone().NewScope(value).inlineCondition(where...).callCallbacks(s.parent.callbacks.deletes).db
|
||||||
}
|
}
|
||||||
|
@ -432,14 +448,19 @@ func (s *DB) Rollback() *DB {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRecord check if value's primary key is blank or not
|
// NewRecord check if value's primary key is blank
|
||||||
func (s *DB) NewRecord(value interface{}) bool {
|
func (s *DB) NewRecord(value interface{}) bool {
|
||||||
return s.clone().NewScope(value).PrimaryKeyZero()
|
return s.clone().NewScope(value).PrimaryKeyZero()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordNotFound check if returning record not found error
|
// RecordNotFound check if returning ErrRecordNotFound error
|
||||||
func (s *DB) RecordNotFound() bool {
|
func (s *DB) RecordNotFound() bool {
|
||||||
return s.Error == ErrRecordNotFound
|
for _, err := range s.GetErrors() {
|
||||||
|
if err == ErrRecordNotFound {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateTable create table for models
|
// CreateTable create table for models
|
||||||
|
@ -464,19 +485,6 @@ func (s *DB) DropTable(values ...interface{}) *DB {
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
// DropTableIfExists drop table for models only when it exists
|
|
||||||
func (s *DB) DropTableIfExists(values ...interface{}) *DB {
|
|
||||||
db := s.clone()
|
|
||||||
for _, value := range values {
|
|
||||||
if tableName, ok := value.(string); ok {
|
|
||||||
db = db.Table(tableName)
|
|
||||||
}
|
|
||||||
|
|
||||||
db = db.NewScope(value).dropTableIfExists().db
|
|
||||||
}
|
|
||||||
return db
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasTable check has table or not
|
// HasTable check has table or not
|
||||||
func (s *DB) HasTable(value interface{}) bool {
|
func (s *DB) HasTable(value interface{}) bool {
|
||||||
var (
|
var (
|
||||||
|
@ -539,8 +547,8 @@ func (s *DB) RemoveIndex(indexName string) *DB {
|
||||||
return scope.db
|
return scope.db
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddForeignKey Add foreign key to the given scope
|
// AddForeignKey Add foreign key to the given scope, e.g:
|
||||||
// Example: db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
|
// db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
|
||||||
func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB {
|
func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB {
|
||||||
scope := s.clone().NewScope(s.Value)
|
scope := s.clone().NewScope(s.Value)
|
||||||
scope.addForeignKey(field, dest, onDelete, onUpdate)
|
scope.addForeignKey(field, dest, onDelete, onUpdate)
|
||||||
|
@ -569,7 +577,8 @@ func (s *DB) Association(column string) *Association {
|
||||||
return &Association{Error: err}
|
return &Association{Error: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preload preload column with given conditions
|
// Preload preload associations with given conditions
|
||||||
|
// db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
|
||||||
func (s *DB) Preload(column string, conditions ...interface{}) *DB {
|
func (s *DB) Preload(column string, conditions ...interface{}) *DB {
|
||||||
return s.clone().search.Preload(column, conditions...).db
|
return s.clone().search.Preload(column, conditions...).db
|
||||||
}
|
}
|
||||||
|
@ -631,7 +640,7 @@ func (s *DB) AddError(err error) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetErrors get happened errors for the db
|
// GetErrors get happened errors from the db
|
||||||
func (s *DB) GetErrors() (errors []error) {
|
func (s *DB) GetErrors() (errors []error) {
|
||||||
if errs, ok := s.Error.(errorsInterface); ok {
|
if errs, ok := s.Error.(errorsInterface); ok {
|
||||||
return errs.GetErrors()
|
return errs.GetErrors()
|
||||||
|
|
5
model.go
5
model.go
|
@ -2,7 +2,10 @@ package gorm
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// Model base model definition, including `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embeded in your models
|
// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embeded in your models
|
||||||
|
// type User struct {
|
||||||
|
// gorm.Model
|
||||||
|
// }
|
||||||
type Model struct {
|
type Model struct {
|
||||||
ID uint `gorm:"primary_key"`
|
ID uint `gorm:"primary_key"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
|
|
|
@ -109,7 +109,7 @@ func getForeignField(column string, fields []*StructField) *StructField {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetModelStruct generate model struct & relationships based on struct and tag definition
|
// GetModelStruct get value's model struct, relationships based on struct and tag definition
|
||||||
func (scope *Scope) GetModelStruct() *ModelStruct {
|
func (scope *Scope) GetModelStruct() *ModelStruct {
|
||||||
var modelStruct ModelStruct
|
var modelStruct ModelStruct
|
||||||
// Scope value can't be nil
|
// Scope value can't be nil
|
||||||
|
|
32
scope.go
32
scope.go
|
@ -10,7 +10,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scope contain any information of current operation when you perform any operation on the database
|
// Scope contain current operation's information when you perform any operation on the database
|
||||||
type Scope struct {
|
type Scope struct {
|
||||||
Search *search
|
Search *search
|
||||||
Value interface{}
|
Value interface{}
|
||||||
|
@ -60,7 +60,7 @@ func (scope *Scope) SkipLeft() {
|
||||||
scope.skipLeft = true
|
scope.skipLeft = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quote used to quote database column name according to database dialect
|
// Quote used to quote string to escape them for database
|
||||||
func (scope *Scope) Quote(str string) string {
|
func (scope *Scope) Quote(str string) string {
|
||||||
if strings.Index(str, ".") != -1 {
|
if strings.Index(str, ".") != -1 {
|
||||||
newStrs := []string{}
|
newStrs := []string{}
|
||||||
|
@ -85,7 +85,7 @@ func (scope *Scope) Dialect() Dialect {
|
||||||
return scope.db.parent.dialect
|
return scope.db.parent.dialect
|
||||||
}
|
}
|
||||||
|
|
||||||
// Err write error
|
// Err add error to Scope
|
||||||
func (scope *Scope) Err(err error) error {
|
func (scope *Scope) Err(err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
scope.db.AddError(err)
|
scope.db.AddError(err)
|
||||||
|
@ -126,7 +126,7 @@ func (scope *Scope) PrimaryField() *Field {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrimaryKey get the primary key's column name
|
// PrimaryKey get main primary field's db name
|
||||||
func (scope *Scope) PrimaryKey() string {
|
func (scope *Scope) PrimaryKey() string {
|
||||||
if field := scope.PrimaryField(); field != nil {
|
if field := scope.PrimaryField(); field != nil {
|
||||||
return field.DBName
|
return field.DBName
|
||||||
|
@ -134,7 +134,7 @@ func (scope *Scope) PrimaryKey() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrimaryKeyZero check the primary key is blank or not
|
// PrimaryKeyZero check main primary field's value is blank or not
|
||||||
func (scope *Scope) PrimaryKeyZero() bool {
|
func (scope *Scope) PrimaryKeyZero() bool {
|
||||||
field := scope.PrimaryField()
|
field := scope.PrimaryField()
|
||||||
return field == nil || field.IsBlank
|
return field == nil || field.IsBlank
|
||||||
|
@ -158,7 +158,7 @@ func (scope *Scope) HasColumn(column string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetColumn to set the column's value
|
// SetColumn to set the column's value, column could be field or field's name/dbname
|
||||||
func (scope *Scope) SetColumn(column interface{}, value interface{}) error {
|
func (scope *Scope) SetColumn(column interface{}, value interface{}) error {
|
||||||
var updateAttrs = map[string]interface{}{}
|
var updateAttrs = map[string]interface{}{}
|
||||||
if attrs, ok := scope.InstanceGet("gorm:update_attrs"); ok {
|
if attrs, ok := scope.InstanceGet("gorm:update_attrs"); ok {
|
||||||
|
@ -221,7 +221,7 @@ func (scope *Scope) callMethod(methodName string, reflectValue reflect.Value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallMethod call scope value's method, if it is a slice, will call value's method one by one
|
// CallMethod call scope value's method, if it is a slice, will call its element's method one by one
|
||||||
func (scope *Scope) CallMethod(methodName string) {
|
func (scope *Scope) CallMethod(methodName string) {
|
||||||
if scope.Value == nil {
|
if scope.Value == nil {
|
||||||
return
|
return
|
||||||
|
@ -236,7 +236,7 @@ func (scope *Scope) CallMethod(methodName string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddToVars add value as sql's vars, gorm will escape them
|
// AddToVars add value as sql's vars, used to prevent SQL injection
|
||||||
func (scope *Scope) AddToVars(value interface{}) string {
|
func (scope *Scope) AddToVars(value interface{}) string {
|
||||||
if expr, ok := value.(*expr); ok {
|
if expr, ok := value.(*expr); ok {
|
||||||
exp := expr.expr
|
exp := expr.expr
|
||||||
|
@ -293,7 +293,7 @@ func (scope *Scope) CombinedConditionSql() string {
|
||||||
scope.havingSQL() + scope.orderSQL() + scope.limitAndOffsetSQL()
|
scope.havingSQL() + scope.orderSQL() + scope.limitAndOffsetSQL()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldByName find gorm.Field with name and db name
|
// FieldByName find `gorm.Field` with field name or db name
|
||||||
func (scope *Scope) FieldByName(name string) (field *Field, ok bool) {
|
func (scope *Scope) FieldByName(name string) (field *Field, ok bool) {
|
||||||
var (
|
var (
|
||||||
dbName = ToDBName(name)
|
dbName = ToDBName(name)
|
||||||
|
@ -311,13 +311,13 @@ func (scope *Scope) FieldByName(name string) (field *Field, ok bool) {
|
||||||
return mostMatchedField, mostMatchedField != nil
|
return mostMatchedField, mostMatchedField != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw set sql
|
// Raw set raw sql
|
||||||
func (scope *Scope) Raw(sql string) *Scope {
|
func (scope *Scope) Raw(sql string) *Scope {
|
||||||
scope.SQL = strings.Replace(sql, "$$", "?", -1)
|
scope.SQL = strings.Replace(sql, "$$", "?", -1)
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec invoke sql
|
// Exec perform generated SQL
|
||||||
func (scope *Scope) Exec() *Scope {
|
func (scope *Scope) Exec() *Scope {
|
||||||
defer scope.trace(NowFunc())
|
defer scope.trace(NowFunc())
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ func (scope *Scope) Set(name string, value interface{}) *Scope {
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get get value by name
|
// Get get setting by name
|
||||||
func (scope *Scope) Get(name string) (interface{}, bool) {
|
func (scope *Scope) Get(name string) (interface{}, bool) {
|
||||||
return scope.db.Get(name)
|
return scope.db.Get(name)
|
||||||
}
|
}
|
||||||
|
@ -350,12 +350,12 @@ func (scope *Scope) InstanceID() string {
|
||||||
return scope.instanceID
|
return scope.instanceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstanceSet set value for current instance, but not for associations
|
// InstanceSet set instance setting for current operation, but not for operations in callbacks, like saving associations callback
|
||||||
func (scope *Scope) InstanceSet(name string, value interface{}) *Scope {
|
func (scope *Scope) InstanceSet(name string, value interface{}) *Scope {
|
||||||
return scope.Set(name+scope.InstanceID(), value)
|
return scope.Set(name+scope.InstanceID(), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstanceGet get setting from current instance
|
// InstanceGet get instance setting from current operation
|
||||||
func (scope *Scope) InstanceGet(name string) (interface{}, bool) {
|
func (scope *Scope) InstanceGet(name string) (interface{}, bool) {
|
||||||
return scope.Get(name + scope.InstanceID())
|
return scope.Get(name + scope.InstanceID())
|
||||||
}
|
}
|
||||||
|
@ -371,7 +371,7 @@ func (scope *Scope) Begin() *Scope {
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitOrRollback commit current transaction if there is no error, otherwise rollback it
|
// CommitOrRollback commit current transaction if no error happened, otherwise will rollback it
|
||||||
func (scope *Scope) CommitOrRollback() *Scope {
|
func (scope *Scope) CommitOrRollback() *Scope {
|
||||||
if _, ok := scope.InstanceGet("gorm:started_transaction"); ok {
|
if _, ok := scope.InstanceGet("gorm:started_transaction"); ok {
|
||||||
if db, ok := scope.db.db.(sqlTx); ok {
|
if db, ok := scope.db.db.(sqlTx); ok {
|
||||||
|
@ -386,7 +386,7 @@ func (scope *Scope) CommitOrRollback() *Scope {
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectAttrs retur nselected attributes
|
// SelectAttrs return selected attributes
|
||||||
func (scope *Scope) SelectAttrs() []string {
|
func (scope *Scope) SelectAttrs() []string {
|
||||||
if scope.selectAttrs == nil {
|
if scope.selectAttrs == nil {
|
||||||
attrs := []string{}
|
attrs := []string{}
|
||||||
|
|
|
@ -569,13 +569,6 @@ func (scope *Scope) dropTable() *Scope {
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scope *Scope) dropTableIfExists() *Scope {
|
|
||||||
if scope.Dialect().HasTable(scope.TableName()) {
|
|
||||||
scope.dropTable()
|
|
||||||
}
|
|
||||||
return scope
|
|
||||||
}
|
|
||||||
|
|
||||||
func (scope *Scope) modifyColumn(column string, typ string) {
|
func (scope *Scope) modifyColumn(column string, typ string) {
|
||||||
scope.Raw(fmt.Sprintf("ALTER TABLE %v MODIFY %v %v", scope.QuotedTableName(), scope.Quote(column), typ)).Exec()
|
scope.Raw(fmt.Sprintf("ALTER TABLE %v MODIFY %v %v", scope.QuotedTableName(), scope.Quote(column), typ)).Exec()
|
||||||
}
|
}
|
||||||
|
|
10
utils.go
10
utils.go
|
@ -14,10 +14,10 @@ import (
|
||||||
|
|
||||||
// NowFunc returns current time, this function is exported in order to be able
|
// NowFunc returns current time, this function is exported in order to be able
|
||||||
// to give the flexibility to the developer to customize it according to their
|
// to give the flexibility to the developer to customize it according to their
|
||||||
// needs
|
// needs, e.g:
|
||||||
//
|
// gorm.NowFunc = func() time.Time {
|
||||||
// e.g: return time.Now().UTC()
|
// return time.Now().UTC()
|
||||||
//
|
// }
|
||||||
var NowFunc = func() time.Time {
|
var NowFunc = func() time.Time {
|
||||||
return time.Now()
|
return time.Now()
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ type expr struct {
|
||||||
args []interface{}
|
args []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expr generate raw SQL expression for SQL, for example:
|
// Expr generate raw SQL expression, for example:
|
||||||
// DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
|
// DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
|
||||||
func Expr(expression string, args ...interface{}) *expr {
|
func Expr(expression string, args ...interface{}) *expr {
|
||||||
return &expr{expr: expression, args: args}
|
return &expr{expr: expression, args: args}
|
||||||
|
|
Loading…
Reference in New Issue