Documentation ¶
Index ¶
- Variables
- func AddNamingStrategy(ns *NamingStrategy)
- func IsByteArrayOrSlice(value reflect.Value) bool
- func IsRecordNotFoundError(err error) bool
- func RegisterDialect(name string, dialect Dialect)
- func ToColumnName(name string) string
- func ToDBName(name string) string
- func ToTableName(name string) string
- type Callback
- type CallbackProcessor
- func (cp *CallbackProcessor) After(callbackName string) *CallbackProcessor
- func (cp *CallbackProcessor) Before(callbackName string) *CallbackProcessor
- func (cp *CallbackProcessor) Get(callbackName string) (callback func(scope *Scope))
- func (cp *CallbackProcessor) Register(callbackName string, callback func(scope *Scope))
- func (cp *CallbackProcessor) Remove(callbackName string)
- func (cp *CallbackProcessor) Replace(callbackName string, callback func(scope *Scope))
- type DB
- func (s *DB) AddError(err error) error
- func (s *DB) AddIndex(indexName string, columns ...string) *DB
- func (s *DB) AddUniqueIndex(indexName string, columns ...string) *DB
- func (s *DB) AutoMigrate(values ...interface{}) *DB
- func (s *DB) Exec(sql string, values ...interface{}) *DB
- func (s *DB) Get(name string) (value interface{}, ok bool)
- func (s *DB) GetErrors() []error
- func (s *DB) InstantSet(name string, value interface{}) *DB
- func (s *DB) Model(value interface{}) *DB
- func (s *DB) NewScope(value interface{}) *Scope
- func (s *DB) Set(name string, value interface{}) *DB
- func (s *DB) Table(name string) *DB
- func (s *DB) Unscoped() *DB
- type DefaultForeignKeyNamer
- type Dialect
- type Errors
- type Field
- type JoinTableForeignKey
- type JoinTableHandler
- func (s JoinTableHandler) Add(handler JoinTableHandlerInterface, db *DB, source interface{}, ...) error
- func (s *JoinTableHandler) DestinationForeignKeys() []JoinTableForeignKey
- func (s *JoinTableHandler) Setup(relationship *Relationship, tableName string, source reflect.Type, ...)
- func (s *JoinTableHandler) SourceForeignKeys() []JoinTableForeignKey
- func (s JoinTableHandler) Table(db *DB) string
- type JoinTableHandlerInterface
- type JoinTableSource
- type LogWriter
- type Logger
- type Model
- type ModelStruct
- type Namer
- type NamingStrategy
- type Relationship
- type Scope
- func (scope *Scope) AddToVars(value interface{}) string
- func (scope *Scope) CombinedConditionSql() string
- func (scope *Scope) Dialect() Dialect
- func (scope *Scope) Err(err error) error
- func (scope *Scope) Exec() *Scope
- func (scope *Scope) FieldByName(name string) (field *Field, ok bool)
- func (scope *Scope) Fields() []*Field
- func (scope *Scope) Get(name string) (interface{}, bool)
- func (scope *Scope) GetModelStruct() *ModelStruct
- func (scope *Scope) GetStructFields() (fields []*StructField)
- func (scope *Scope) IndirectValue() reflect.Value
- func (scope *Scope) InstanceGet(name string) (interface{}, bool)
- func (scope *Scope) InstanceID() string
- func (scope *Scope) InstanceSet(name string, value interface{}) *Scope
- func (scope *Scope) New(value interface{}) *Scope
- func (scope *Scope) NewDB() *DB
- func (scope *Scope) PrimaryField() *Field
- func (scope *Scope) PrimaryFields() (fields []*Field)
- func (scope *Scope) PrimaryKey() string
- func (scope *Scope) PrimaryKeyValue() interface{}
- func (scope *Scope) PrimaryKeyZero() bool
- func (scope *Scope) Quote(str string) string
- func (scope *Scope) QuotedTableName() (name string)
- func (scope *Scope) Raw(sql string) *Scope
- func (scope *Scope) Set(name string, value interface{}) *Scope
- func (scope *Scope) TableName() string
- type SqlExpr
- type StructField
Constants ¶
This section is empty.
Variables ¶
var ( // ErrRecordNotFound returns a "record not found error". Occurs only when attempting to query the database with a struct; querying with a slice won't return this error ErrRecordNotFound = errors.New("record not found") // ErrInvalidSQL occurs when you attempt a query with invalid SQL ErrInvalidSQL = errors.New("invalid SQL") // ErrInvalidTransaction occurs when you are trying to `Commit` or `Rollback` ErrInvalidTransaction = errors.New("no valid transaction") // ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin` ErrCantStartTransaction = errors.New("can't start transaction") // ErrUnaddressable unaddressable value ErrUnaddressable = errors.New("using unaddressable value") )
var DefaultCallback = &Callback{logger: nopLogger{}}
DefaultCallback default callbacks defined by gorm
var DefaultTableNameHandler = func(db *DB, defaultTableName string) string {
return defaultTableName
}
DefaultTableNameHandler default table name handler
var LogFormatter = func(values ...interface{}) (messages []interface{}) { if len(values) > 1 { var ( sql string formattedValues []string level = values[0] currentTime = "\n\033[33m[" + NowFunc().Format("2006-01-02 15:04:05") + "]\033[0m" source = fmt.Sprintf("\033[35m(%v)\033[0m", values[1]) ) messages = []interface{}{source, currentTime} if len(values) == 2 { currentTime = currentTime[1:] source = fmt.Sprintf("\033[35m%v\033[0m", values[1]) messages = []interface{}{currentTime, source} } if level == "sql" { messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0)) for _, value := range values[4].([]interface{}) { indirectValue := reflect.Indirect(reflect.ValueOf(value)) if indirectValue.IsValid() { value = indirectValue.Interface() if t, ok := value.(time.Time); ok { if t.IsZero() { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", "0000-00-00 00:00:00")) } else { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05"))) } } else if b, ok := value.([]byte); ok { if str := string(b); isPrintable(str) { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str)) } else { formattedValues = append(formattedValues, "'<binary>'") } } else if r, ok := value.(driver.Valuer); ok { if value, err := r.Value(); err == nil && value != nil { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value)) } else { formattedValues = append(formattedValues, "NULL") } } else { switch value.(type) { case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool: formattedValues = append(formattedValues, fmt.Sprintf("%v", value)) default: formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value)) } } } else { formattedValues = append(formattedValues, "NULL") } } if numericPlaceHolderRegexp.MatchString(values[3].(string)) { sql = values[3].(string) for index, value := range formattedValues { placeholder := fmt.Sprintf(`\$%d([^\d]|$)`, index+1) sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value+"$1") } } else { formattedValuesLength := len(formattedValues) for index, value := range sqlRegexp.Split(values[3].(string), -1) { sql += value if index < formattedValuesLength { sql += formattedValues[index] } } } messages = append(messages, sql) messages = append(messages, fmt.Sprintf(" \n\033[36;31m[%v]\033[0m ", strconv.FormatInt(values[5].(int64), 10)+" rows affected or returned ")) } else { messages = append(messages, "\033[31;1m") messages = append(messages, values[2:]...) messages = append(messages, "\033[0m") } } return }
var NowFunc = func() time.Time { return time.Now() }
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 needs, e.g:
gorm.NowFunc = func() time.Time { return time.Now().UTC() }
var ParseFieldStructForDialect = func(field *StructField, dialect Dialect) (fieldValue reflect.Value, sqlType string, size int, additionalType string) { // Get redirected field type var ( reflectType = field.Struct.Type dataType, _ = field.TagSettingsGet("TYPE") ) for reflectType.Kind() == reflect.Ptr { reflectType = reflectType.Elem() } fieldValue = reflect.Indirect(reflect.New(reflectType)) if gormDataType, ok := fieldValue.Interface().(interface { GormDataType(Dialect) string }); ok { dataType = gormDataType.GormDataType(dialect) } if dataType == "" { var getScannerValue func(reflect.Value) getScannerValue = func(value reflect.Value) { fieldValue = value if _, isScanner := reflect.New(fieldValue.Type()).Interface().(sql.Scanner); isScanner && fieldValue.Kind() == reflect.Struct { getScannerValue(fieldValue.Field(0)) } } getScannerValue(fieldValue) } if num, ok := field.TagSettingsGet("SIZE"); ok { size, _ = strconv.Atoi(num) } else { size = 255 } notNull, _ := field.TagSettingsGet("NOT NULL") unique, _ := field.TagSettingsGet("UNIQUE") additionalType = notNull + " " + unique if value, ok := field.TagSettingsGet("DEFAULT"); ok { additionalType = additionalType + " DEFAULT " + value } if value, ok := field.TagSettingsGet("COMMENT"); ok { additionalType = additionalType + " COMMENT " + value } return fieldValue, dataType, size, strings.TrimSpace(additionalType) }
ParseFieldStructForDialect get field's sql data type
var TheNamingStrategy = &NamingStrategy{
DB: defaultNamer,
Table: defaultNamer,
Column: defaultNamer,
}
TheNamingStrategy is being initialized with defaultNamingStrategy
Functions ¶
func AddNamingStrategy ¶
func AddNamingStrategy(ns *NamingStrategy)
AddNamingStrategy sets the naming strategy
func IsByteArrayOrSlice ¶
IsByteArrayOrSlice returns true of the reflected value is an array or slice
func IsRecordNotFoundError ¶
IsRecordNotFoundError returns true if error contains a RecordNotFound error
func RegisterDialect ¶
RegisterDialect register new dialect
Types ¶
type Callback ¶
type Callback struct {
// contains filtered or unexported fields
}
Callback is a struct that contains all CRUD callbacks
Field `creates` contains callbacks will be call when creating object Field `updates` contains callbacks will be call when updating object Field `deletes` contains callbacks will be call when deleting object Field `queries` contains callbacks will be call when querying object with query methods like Find, First, Related, Association... Field `rowQueries` contains callbacks will be call when querying object with Row, Rows... Field `processors` contains all callback processors, will be used to generate above callbacks in order
func (*Callback) Create ¶
func (c *Callback) Create() *CallbackProcessor
Create could be used to register callbacks for creating object
db.Callback().Create().After("gorm:create").Register("plugin:run_after_create", func(*Scope) { // business logic ... // set error if some thing wrong happened, will rollback the creating scope.Err(errors.New("error")) })
func (*Callback) Delete ¶
func (c *Callback) Delete() *CallbackProcessor
Delete could be used to register callbacks for deleting object, refer `Create` for usage
func (*Callback) Query ¶
func (c *Callback) Query() *CallbackProcessor
Query could be used to register callbacks for querying objects with query methods like `Find`, `First`, `Related`, `Association`... Refer `Create` for usage
func (*Callback) RowQuery ¶
func (c *Callback) RowQuery() *CallbackProcessor
RowQuery could be used to register callbacks for querying objects with `Row`, `Rows`, refer `Create` for usage
func (*Callback) Update ¶
func (c *Callback) Update() *CallbackProcessor
Update could be used to register callbacks for updating object, refer `Create` for usage
type CallbackProcessor ¶
type CallbackProcessor struct {
// contains filtered or unexported fields
}
CallbackProcessor contains callback informations
func (*CallbackProcessor) After ¶
func (cp *CallbackProcessor) After(callbackName string) *CallbackProcessor
After insert a new callback after callback `callbackName`, refer `Callbacks.Create`
func (*CallbackProcessor) Before ¶
func (cp *CallbackProcessor) Before(callbackName string) *CallbackProcessor
Before insert a new callback before callback `callbackName`, refer `Callbacks.Create`
func (*CallbackProcessor) Get ¶
func (cp *CallbackProcessor) Get(callbackName string) (callback func(scope *Scope))
Get registered callback
db.Callback().Create().Get("gorm:create")
func (*CallbackProcessor) Register ¶
func (cp *CallbackProcessor) Register(callbackName string, callback func(scope *Scope))
Register a new callback, refer `Callbacks.Create`
func (*CallbackProcessor) Remove ¶
func (cp *CallbackProcessor) Remove(callbackName string)
Remove a registered callback
db.Callback().Create().Remove("gorm:update_time_stamp_when_create")
func (*CallbackProcessor) Replace ¶
func (cp *CallbackProcessor) Replace(callbackName string, callback func(scope *Scope))
Replace a registered callback with new callback
db.Callback().Create().Replace("gorm:update_time_stamp_when_create", func(*Scope) { scope.SetColumn("CreatedAt", now) scope.SetColumn("UpdatedAt", now) })
type DB ¶
type DB struct { sync.RWMutex Value interface{} Error error RowsAffected int64 // contains filtered or unexported fields }
func (*DB) AddUniqueIndex ¶
AddUniqueIndex add unique index for columns with given name
func (*DB) AutoMigrate ¶
func (*DB) InstantSet ¶
InstantSet instant set setting, will affect current db
func (*DB) Model ¶
Model specify the model you would like to run db operations
// update all users's name to `hello` db.Model(&User{}).Update("name", "hello") // if user's primary key is non-blank, will use it as condition, then will only update the user's name to `hello` db.Model(&user).Update("name", "hello")
func (*DB) Set ¶
Set set setting by name, which could be used in callbacks, will clone a new db, and update its setting
func (*DB) Unscoped ¶
Unscoped return all record including deleted record, refer Soft Delete https://jinzhu.github.io/gorm/crud.html#soft-delete
type DefaultForeignKeyNamer ¶
type DefaultForeignKeyNamer struct { }
DefaultForeignKeyNamer contains the default foreign key name generator method
func (DefaultForeignKeyNamer) BuildKeyName ¶
func (DefaultForeignKeyNamer) BuildKeyName(kind, tableName string, fields ...string) string
BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference
type Dialect ¶
type Dialect interface { // GetName get dialect's name GetName() string // SetDB set db for dialect SetDB(db gdb.DB) // BindVar return the placeholder for actual values in SQL statements, in many dbs it is "?", Postgres using $1 BindVar(i int) string // Quote quotes field name to avoid SQL parsing exceptions by using a reserved word as a field name Quote(key string) string // DataTypeOf return data's sql type DataTypeOf(field *StructField) string // HasIndex check has index or not HasIndex(tableName string, indexName string) bool // HasForeignKey check has foreign key or not HasForeignKey(tableName string, foreignKeyName string) bool // RemoveIndex remove index RemoveIndex(tableName string, indexName string) error // HasTable check has table or not HasTable(tableName string) bool // HasColumn check has column or not HasColumn(tableName string, columnName string) bool // ModifyColumn modify column's type ModifyColumn(tableName string, columnName string, typ string) error // LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case LimitAndOffsetSQL(limit, offset interface{}) (string, error) // SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL` SelectFromDummyTable() string // LastInsertIDOutputInterstitial most dbs support LastInsertId, but mssql needs to use `OUTPUT` LastInsertIDOutputInterstitial(tableName, columnName string, columns []string) string // LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING` LastInsertIDReturningSuffix(tableName, columnName string) string // DefaultValueStr DefaultValueStr() string // BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference BuildKeyName(kind, tableName string, fields ...string) string // NormalizeIndexAndColumn returns valid index name and column name depending on each dialect NormalizeIndexAndColumn(indexName, columnName string) (string, string) // CurrentDatabase return current database name CurrentDatabase() string }
Dialect interface contains behaviors that differ across SQL database
func GetDialect ¶
GetDialect gets the dialect for the specified dialect name
type Errors ¶
type Errors []error
Errors contains all happened errors
type Field ¶
type Field struct { *StructField IsBlank bool Field reflect.Value }
Field model field definition
type JoinTableForeignKey ¶
JoinTableForeignKey join table foreign key struct
type JoinTableHandler ¶
type JoinTableHandler struct { TableName string `sql:"-"` Source JoinTableSource `sql:"-"` Destination JoinTableSource `sql:"-"` }
JoinTableHandler default join table handler
func (JoinTableHandler) Add ¶
func (s JoinTableHandler) Add(handler JoinTableHandlerInterface, db *DB, source interface{}, destination interface{}) error
Add create relationship in join table for source and destination
func (*JoinTableHandler) DestinationForeignKeys ¶
func (s *JoinTableHandler) DestinationForeignKeys() []JoinTableForeignKey
DestinationForeignKeys return destination foreign keys
func (*JoinTableHandler) Setup ¶
func (s *JoinTableHandler) Setup(relationship *Relationship, tableName string, source reflect.Type, destination reflect.Type)
Setup initialize a default join table handler
func (*JoinTableHandler) SourceForeignKeys ¶
func (s *JoinTableHandler) SourceForeignKeys() []JoinTableForeignKey
SourceForeignKeys return source foreign keys
func (JoinTableHandler) Table ¶
func (s JoinTableHandler) Table(db *DB) string
Table return join table's table name
type JoinTableHandlerInterface ¶
type JoinTableHandlerInterface interface { // initialize join table handler Setup(relationship *Relationship, tableName string, source reflect.Type, destination reflect.Type) // Table return join table's table name Table(db *DB) string // Add create relationship in join table for source and destination Add(handler JoinTableHandlerInterface, db *DB, source interface{}, destination interface{}) error // SourceForeignKeys return source foreign keys SourceForeignKeys() []JoinTableForeignKey // DestinationForeignKeys return destination foreign keys DestinationForeignKeys() []JoinTableForeignKey }
JoinTableHandlerInterface is an interface for how to handle many2many relations
type JoinTableSource ¶
type JoinTableSource struct { ModelType reflect.Type ForeignKeys []JoinTableForeignKey }
JoinTableSource is a struct that contains model type and foreign keys
type LogWriter ¶
type LogWriter interface {
Println(v ...interface{})
}
LogWriter log writer interface
type ModelStruct ¶
type ModelStruct struct { PrimaryFields []*StructField StructFields []*StructField ModelType reflect.Type // contains filtered or unexported fields }
ModelStruct model definition
func (*ModelStruct) TableName ¶
func (s *ModelStruct) TableName(db *DB) string
TableName returns model's table name
type NamingStrategy ¶
NamingStrategy represents naming strategies
func (*NamingStrategy) ColumnName ¶
func (ns *NamingStrategy) ColumnName(name string) string
ColumnName alters the given name by Column
func (*NamingStrategy) DBName ¶
func (ns *NamingStrategy) DBName(name string) string
DBName alters the given name by DB
func (*NamingStrategy) TableName ¶
func (ns *NamingStrategy) TableName(name string) string
TableName alters the given name by Table
type Relationship ¶
type Relationship struct { Kind string PolymorphicType string PolymorphicDBName string PolymorphicValue string ForeignFieldNames []string ForeignDBNames []string AssociationForeignFieldNames []string AssociationForeignDBNames []string JoinTableHandler JoinTableHandlerInterface }
Relationship described the relationship between models
type Scope ¶
type Scope struct { Search *search Value interface{} SQL string SQLVars []interface{} // contains filtered or unexported fields }
func (*Scope) CombinedConditionSql ¶
CombinedConditionSql return combined condition sql
func (*Scope) FieldByName ¶
FieldByName find `gorm.Field` with field name or db name
func (*Scope) GetModelStruct ¶
func (scope *Scope) GetModelStruct() *ModelStruct
GetModelStruct get value's model struct, relationships based on struct and tag definition
func (*Scope) GetStructFields ¶
func (scope *Scope) GetStructFields() (fields []*StructField)
GetStructFields get model's field structs
func (*Scope) IndirectValue ¶
IndirectValue return scope's reflect value's indirect value
func (*Scope) InstanceGet ¶
InstanceGet get instance setting from current operation
func (*Scope) InstanceID ¶
InstanceID get InstanceID for scope
func (*Scope) InstanceSet ¶
InstanceSet set instance setting for current operation, but not for operations in callbacks, like saving associations callback
func (*Scope) PrimaryField ¶
PrimaryField return scope's main primary field, if defined more that one primary fields, will return the one having column name `id` or the first one
func (*Scope) PrimaryFields ¶
PrimaryFields return scope's primary fields
func (*Scope) PrimaryKey ¶
PrimaryKey get main primary field's db name
func (*Scope) PrimaryKeyValue ¶
func (scope *Scope) PrimaryKeyValue() interface{}
PrimaryKeyValue get the primary key's value
func (*Scope) PrimaryKeyZero ¶
PrimaryKeyZero check main primary field's value is blank or not
func (*Scope) QuotedTableName ¶
QuotedTableName return quoted table name
type StructField ¶
type StructField struct { DBName string Name string Names []string IsPrimaryKey bool IsNormal bool IsIgnored bool IsScanner bool HasDefaultValue bool Tag reflect.StructTag TagSettings map[string]string Struct reflect.StructField IsForeignKey bool Relationship *Relationship // contains filtered or unexported fields }
StructField model field's struct definition
func (*StructField) TagSettingsDelete ¶
func (sf *StructField) TagSettingsDelete(key string)
TagSettingsDelete deletes a tag
func (*StructField) TagSettingsGet ¶
func (sf *StructField) TagSettingsGet(key string) (string, bool)
TagSettingsGet returns a tag from the tag settings
func (*StructField) TagSettingsSet ¶
func (sf *StructField) TagSettingsSet(key, val string)
TagSettingsSet Sets a tag in the tag settings map