gorm

package module
v0.0.0-...-343d07f Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2018 License: MIT Imports: 19 Imported by: 0

README

Overview

  • Full-Featured ORM (almost)
  • Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)
  • Callbacks (Before/After Create/Save/Update/Delete/Find)
  • Preloading (eager loading)
  • Transactions
  • Composite Primary Key
  • SQL Builder
  • Auto Migrations
  • Logger
  • Extendable, write Plugins based on GORM callbacks
  • Every feature comes with tests
  • Developer Friendly

Getting Started

Comments and thoughts

  • As a general idea on golang projects : "fail fast" type of logic is the best approach
  • When a function is called everytime, best idea is to allow golang to inline it
  • regexp.MustCompile is slow inside functions (10 times slower)

Last merge

  • 05.12.2016 - "Add gorm:association:source for association operations for plugins to extend GORM"
  • Note : what's not included before that merge, it's because I don't think it's good to do so

Breaking changes

  • DB struct - renamed to DBCon, since that is what it represents. However, you can do the following, to use the old gorm.DB: dbcon, err := gorm.Open("mysql", dbstr+"?parseTime=true") db = &gorm.DB{*dbcon}
  • Removed MSSQL support - out of my concerns with this project

Changes log (29.10.2016-present)

Todo

  • Documentation for tests and build examples
  • Generated SQL let's the SQL engine cast : SELECT * FROM aTable WHERE id = '1' (id being int). I think it's a bad practice and it should be fixed
  • convertInterfaceToMap in utils it's terrible : simplify

28.01.2017

  • update IsZero as in last original gorm commit

21.12.2016

  • replace fields access (where possible) via modelstruct instead of scope fields
  • Scope rType property holds reflect.Type of the Value (on clone)

20.12.2016

  • SetZero, IsZero in utils
  • Scope has getColumnAsArray instead of generic getColumnAsArray in utils
  • added field not found error
  • removed errors.New() - replaced with fmt.Errorf

19.12.2016

  • removed Scope NewScope - inlined into utils
  • Scope holds rValue (prepare removal of IndirectValue calls)
  • unified DBCon NewScope with newScope
  • replace IndirectValue calls
  • removed GetType from utils, renamed GetTType to GetType

18.12.2016

  • Quote fields are now cached and DBCon is holding them
  • Removed Search struct TableName() method
  • Replaced, where possible, GetSliceSetting with GetForeignFieldNames, GetAssociationForeignFieldNames, GetForeignDBNames, GetAssociationDBNames
  • Fix for Association.Count when there are no where conditions
  • Fixed some tests (duplicate entries errors or misspellings)
  • removed Scope's attrs interface{} - since we can pass it as argument to postUpdate()
  • Scope TableName fix : if implements tabler or dbtabler should override the search table name
  • Fix for Update after save, e.g. TestDB.Save(&animal).Update("name", "Francis") - scope table name is empty, do not execute query
  • getScannerValue removed from utils
  • toQueryMarks optimisation (concat instead of string joins)

17.12.2016

  • When error occurs, print the SQL that was executed (via AddErr of the Scope, we're passing SQL and SQLVars)
  • DBCon has modelsStructMap property which keeps the map that was a "global" variable (separate of concerns and encapsulation)
  • convertInterfaceToMap in utils - created a scope without connection (should be forbidden)
  • SetJoinTableHandler in DBCon - created a scope without connection (should be forbidden)
  • safeModelStructsMap made private
  • DBCon exposes modelsStructMap via KnownModelStructs()
  • DBCon has namesMap property which keeps the map that was a "global" variable (separate of concerns and encapsulation) same as above
  • DBCon KnownNames(name string) for checking against namesMap
  • had to modify ModelStruct FieldByName signature to FieldByName(column string, con *DBCon) to give access to namesMap

16.12.2016

  • Replaced - where possible - conditions for relation checking (readability)
  • fieldsMap struct - all methods are private
  • moved errors from utils_relations and performed some cleanups
  • Search moved flags in types and renamed to be private
  • extracted strings from dialects

15.12.2016

  • Bug fix for ManyToManyWithCustomizedForeignKeys2
  • Fix for calling AutoMigrate with JoinTableHandlerInterface
  • refactored createJoinTable in utils_migrations
  • Fix DoJoinTable test : SetJoinTableHandler should be used only if AutoMigrate creates the tables first
TestDB.AutoMigrate(&Person{},&PersonAddress{})
TestDB.SetJoinTableHandler(&Person{}, "Addresses", &PersonAddress{})

instead of

TestDB.AutoMigrate(&Person{})
TestDB.SetJoinTableHandler(&Person{}, "Addresses", &PersonAddress{})

14.12.2016

  • Bug fix in StructField ParseFieldStructForDialect : slice of bytes is wrong (probably all kind of slices are)
  • Fix for ManyToManyWithMultiPrimaryKeys test : toQueryMarks optimisation in utils was breaking it
  • Cleanup in StructField after using COLUMN tag setting
  • GetHandlerStruct of JoinTableHandler and interface - for debugging

13.12.2016

  • removed ORDER_BY_PK_SETTING and logic from dbCon First and Last (order it's kept in search)
  • removed QUERY_DEST_SETTING and logic : Scope's postQuery accepts a parameter which is destination for dbCon Scan
  • created QueryOption test for "gorm:query_option"
  • Association Count IS failing in mysql tests, because for some reason we get field and/or scope nil
  • removed IGNORE_PROTEC_SETTING : set in dbCon Updates, but never used

11.12.2016

  • CallMethod - extract string constants
  • reduced Scope callbacks
  • more string concat instead of string slices

08.12.2016

  • removed STARTED_TX_SETTING : Scope's Begin returns also a bool, CommitOrRollback accepts a bool param
  • removed BLANK_COLS_DEFAULT_SETTING : Scope's beforeCreateCallback returns also a string, forceReloadAfterCreateCallback accepts that string
  • string concat instead of string slices where possible (cheaper)
  • DBCon SetLogMode(mode int) and LOG_OFF, LOG_VERBOSE, LOG_DEBUG constants
  • removed UPDATE_ATTRS_SETTING : instead, Scope has now updateMaps map[string]interface{} which holds that data
  • got rid of InstanceSet and InstanceGet from Scope, instanceID (uint64) property was removed
  • callCallbacks gets called only we have registered functions, so we won't call function for nothing

07.12.2016

  • "Add gorm:association:source for association operations for plugins to extend GORM" from original commit
  • removed SelectWithArrayInput test
  • changed dbcon signature for Select - it doesn't accept slices of strings anymore
  • Skip order sql when quering with distinct commit
  • Search Select is using only first select clause - now it's overriding existing select clauses
  • Scope createCallback was adding BLANK_COLS_DEFAULT_SETTING inside a for loop (since it was a map, was not malfunctioning, but was bad logic)
  • BLANK_COLS_DEFAULT_SETTING is now storing a string, not a StrSlice
  • Add gorm:association:source for association operations for plugins to extend GORM commit

05.12.2016

  • removed getTableOptions from Scope : was used in creation operations, so we don't need it there
  • after processing relations, we cleanup tag setting's ASSOCIATIONFOREIGNKEY and FOREIGNKEY for allocation sake
  • added sort for test results
  • autoIndex in tables_operations calls directly addIndex (instead of going through dbcon)

04.12.2016

  • StrSlices for association and foreign keys gets created on parseTagSettings of StructField
  • tag settings map changed from map[uint8]string to map[uint8]interface{}
  • Relationship : PolymorphicType, PolymorphicDBName, PolymorphicValue were removed
  • Relationship : Moved relationship kind to tag settings
  • Relationship : removed JoinTableHandler (holded by tag settings now)
  • Relationship removed.
  • seems JoinTableHandler did nothing with sources parameter of Delete method : in association Replace method was passing relationship

03.12.2016

  • Warning for relationship
  • Unset field flag, so we can use HasRelations() instead of checking for relationship == nil (HAS_RELATIONS)
  • test/types.go
  • checking field.HasRelations() - instead of checking for relationship == nil

02.12.2016

  • tag settings are kept only if they have values - flags are set in parent StructField
  • tag settings is concurrent map
  • StructField Set method invalid logic : after setting it to zero, we don't verify is blank, we just set the flag
  • Rearranged tests, with a form of benchmarking
  • Removed SetJoinTableFK from StructField (unused)

30.11.2016

  • Simplify reflections
  • Removed the way internal callbacks were called - gorm can't be broken by un-registering internal callbacks
  • removed Struct property of StructField - added StructName property
  • removed handleBelongsToPreload from Search

29.11.2016

  • Stringer for Relationship, ModelStruct and StructField

28.11.2016

  • Benchmark Quote with regexp, runes, runes conversion and byte shifting
  • Optimized Quote in utils : uses "prepared" regexp
  • changed the Dialect interface : Quote(key string) string is now GetQuoter() string - which returns the quote string(rune)

27.11.2016

  • created Search struct methods for Query, QueryRow and Exec
  • created Search struct RowsAffected field (to replace DBCon's one)
  • argsToInterface in utils
  • updatedAttrsWithValues in utils
  • getValueFromFields in utils
  • initialize moved from Scope to Search
  • implement Warnings (like logs, but always)
  • All create, migrate and alter functions should be moved from the scope inside a separate file (since we're automigrating just at startup)
  • put back PrimaryKey() of Scope shadow of PKName()
  • put back PrimaryField() of Scope shadow of PK()
  • put back PrimaryFields() of Scope shadow of PKs()

26.11.2016

  • polished Scope methods
  • removed inlineConditions from Search
  • rearranged Search combinedConditionSql to have fewer calls
  • rearranged Search prepareQuerySQL to have fewer calls
  • Scope's instanceID is now uint64 and holds the pointer address of that Scope
  • replace current method of keeping data Set / SetInstance / Get
  • switch back to some inline function : getColumnAsArray, generatePreloadDBWithConditions, toQueryValues, toQueryMarks, toQueryCondition, QuoteIfPossible, Quote
  • moved Value from DBCon struct to Search struct (temporary)

25.11.2016

  • utils, removed toSearchableMap
  • utils, convertInterfaceToMap moved to Scope
  • DBConFunc func(*DBCon) *DBCon
  • benchmarks organized
  • DBCon, Scope have Warn
  • Scope related() fail fast logic

24.11.2016

  • moved SQL related functions from Scope to Search struct
  • Search struct replaced scope.AddToVars with addToVars , Scope AddToVars() method removed
  • slimmer Search struct : group, limit, offset gone

23.11.2016

  • file for expr struct - removed, replaced with SqlPair
  • removed Scope SelectAttrs() method and Scope selectAttrs property
  • removed Scope OmitAttrs() []string
  • because above removals, Scope changeableField() method simplified
  • Search struct - added more flags instead of using length for conditions
  • moved SQL and SQLVars from Scope to Search
  • removed Search "con" property : DBCon struct has now clear unscoped methods (stores in search property)
  • removed Search getInterfaceAsSQL since it was used by Group, which takes string parameter

22.11.2016

  • slimmer Search struct - preload gone
  • slimmer Search struct - selects gone
  • slimmer Search struct - order gone
  • Search true clone
  • Search conditions renamed to Conditions, sqlConditions struct renamed to SqlConditions, so search_test.go could be moved in tests

21.11.2016

  • slimmer Search struct - notConditions are gone
  • slimmer Search struct - flags instead of booleans
  • slimmer Search struct - initAttrs gone + method GetInitAttr()
  • slimmer Search struct - assignAttrs gone + method GetAssignAttr()

16.11.2016

  • slimmer search struct - whereConditions, orConditions, havingConditions, joinConditions are gone

15.11.2016

  • minor modification on ModelStruct Create() : moved HasRelations flag setters into StructField
  • moved getValueFromFields from utils.go to string_slice.go (even if it don't belong there)

14.11.2016

  • StructField - optimized creation
  • StructField - optimized makeSlice()
  • StructField - method PtrToValue() called in Scope (scan)
  • integrate Omit duplicates and zero-value ids in preload queries. Resolves #854 and #1054.

13.11.2016

  • ModelStruct - removed properties PrimaryFields and StructFields - they are kept in fieldsMap struct
  • ModelStruct - fieldsMap struct has method PrimaryFields() which are cached into cachedPrimaryFields
  • extracted string "id" into a const (Scope and ModelStruct)
  • ModelStruct - method for number of primary fields
  • Added flag for IS_AUTOINCREMENT (and logic for it)
  • renamed PrimaryFields to PKs, PrimaryField to PK
  • polished relationship.go methods
  • added errors on relationship.go when fields not found, but they break the tests (TODO : investigate why)
  • got rid of checkInterfaces() method of ModelStruct (simplification)
  • make StructField be able to provide a value's interface (Interface() method)
  • make ModelStruct be able to provide a value's interface (Interface() method)
  • cleanup reflect.New(blah... blah) - replaced with Interface() call (WIP)

12.11.2016

  • switched bitflag from uint64 to uint16 (we really don't need more than 16 at the time)
  • make ModelStruct map it's fields : fieldsMap struct
  • make ModelStruct map it's fields : logic modification in fieldByName() - if mapped not found, looking into NamesMap
  • make ModelStruct map it's fields : ModelStruct has addField(field) method
  • make ModelStruct map it's fields : ModelStruct has addPK(field) method (primary keys)
  • make ModelStruct map it's fields : ModelStruct has HasColumn(name) method
  • make ModelStruct map it's fields : removed Scope method HasColumn(name)
  • refactored Scope Fields() method - calls a cloneStructFields method of ModelStruct
  • simplified further the GetModelStruct() of Scope to cleanup the fields
  • renamed DB() of Scope to Con()
  • renamed NewDB() of Scope to NewCon()
  • make Relationship have some methods so we can move code from ModelStruct (part 1 - ModelStruct sliceRelationships() removed)
  • make Relationship have some methods so we can move code from ModelStruct (part 2 - ModelStruct structRelationships() removed)

11.11.2016

  • instead of having this bunch of flags in StructField - bitflag
  • removed joinTableHandlers property from DBCon (was probably leftover of work in progress)
  • simplified Setup(relationship *Relationship, source reflect.Type, destination reflect.Type) of JoinTableHandlerInterface
  • added SetTable(name string) to JoinTableHandlerInterface
  • renamed property "db" of DBCon to "sqli"
  • renamed interface sqlCommon to sqlInterf
  • renamed property "db" of Scope to "con"
  • renamed property "db" of search struct to "con"
  • search struct has collectAttrs() method which loads the cached selectAttrs of the Scope

10.11.2016

  • StructField has field UnderlyingType (should keep reflect.Type so we won't use reflection everywhere)
  • finally got rid of defer inside loop of Scope's GetModelStruct method (ModelStruct's processRelations method has a loop in which calls relationship processors)
  • introduced a HasRelations and IsTime in StructField

09.11.2016

  • Collector - a helper to avoid multiple calls on fmt.Sprintf : stores values and string
  • replaced some statements with switch
  • GetModelStruct refactoring
  • GromErrors change and fix (from original gorm commits)

08.11.2016

  • adopted skip association tag from https://github.com/slockij/gorm (gorm:"save_associations:false")
  • adopted db.Raw().First() makes wrong sql fix #1214 #1243
  • registerGORMDefaultCallbacks() calls reorder at the end of registration
  • Scope toQueryCondition() from utils.go
  • Moved callbacks into Scope (needs closure functions)
  • Removed some postgres specific functions from utils.go

07.11.2016

  • have NOT integrate original-gorm pull request #1252 (prevent delete/update if conditions are not met, thus preventing delete-all, update-all) tests fail
  • have looked upon all original-gorm pull requests - and decided to skip them
  • have NOT integrate original-gorm pull request #1251 - can be done with Scanner and Valuer
  • have NOT integrate original-gorm pull request #1242 - can be done simplier
  • ParseFieldStructForDialect() moved to struct_field.go from utils.go
  • makeSlice() moved to struct_field.go from utils.go
  • indirect() from utils.go, swallowed where needed (shows logic better when dereferencing pointer)
  • file for expr struct (will add more functionality)
  • cloneWithValue() method in db.go

06.11.2016

  • got rid of parseTagSetting method from utils.go
  • moved ToDBName into safe_map.go - renamed smap to NamesMap
  • StrSlice is used in Relationship
  • more cleanups
  • more renaming

05.11.2016

  • DefaultCallback removed from types - it's made under open and registers all callbacks there
  • callback.go has now a method named registerDefaults
  • scope's GetModelStruct refactored and fixed a few lint problems

02.11.2016

  • avoid unnecessary calls in CallbackProcessors reorder method (lengths zero)
  • Refactored sortProcessors not to be recursive, but have a method called sortCallbackProcessor inside CallbackProcessor
  • Concurent slice and map in utils (so far, unused)
  • type CallbackProcessors []*CallbackProcessor for readability
  • callback_processors.go file which holds methods for type CallbackProcessors (add, len)
  • moved sortProcessors from utils.go to callback_processors.go as method
  • created type ScopedFunc func(*Scope)
  • created type ScopedFuncs []*ScopedFunc
  • replaced types ScopedFunc and ScopedFuncs to be more readable

01.11.2016

  • TestCloneSearch could not be moved
  • Exposed some methods on Callback for tests to run (GetCreates, GetUpdates, GetQueries, GetDeletes)
  • Moved tests to tests folder (helps IDE)
  • Extracted strings from dialect_common.go
  • Extracted strings from dialect_mysql.go
  • Modified some variable names to comply to linter ("collides with imported package name")
  • Remove explicit variable name on returns
  • Removed method newDialect from utils.go (moved it into Open() method)
  • Removed MSSQL support - out of my concerns with this project
  • Fix (chore) in StructField Set method : if implements Scanner don't attempt to convert, just pass it over
  • Test named TestNot
  • CallbackProcessor kind field changed from string to uint8

30.10.2016 (Others)

  • DB struct - renamed to DBCon, since that is what it represents

30.10.2016 (Operation Field -> StructField)

  • StructFields has it's own file to get rid of append() everywhere in the code
  • TagSettings map[uint8]string in StructField will become a struct by itself, to support has(), get(), set(), clone(), loadFromTags()
  • TagSettings should be private in StructField
  • replace everywhere []*StructField with type StructFields
  • create StructFields type []*StructField for code readability
  • NewStructField method to create StructField from reflect.StructField
  • Field struct, "Field" property renamed to "Value", since it is a reflect.Value
  • StructField should swallow Field model field definition
  • created cloneWithValue(value reflect.Value) on StructField -> calls setIsBlank()
  • moved isBlank(fieldValue) from utils to StructField named setIsBlank()
  • remove getForeignField from utils.go -> ModelStruct has a method called getForeignField(fieldName string)

29.10.2016

  • Moved code around
  • Numbered tests - so I can track what fails
  • Replaced some string constants like "many_to_many" and refactor accordingly
  • StructField is parsing by it's own gorm and sql tags with method ParseTagSettings
  • Replaced string constants for the tags and created a map string-to-uint8
  • Removed field Name from StructField since Struct property of it exposes Name
  • Created method GetName() for StructField to return that name
  • Created method GetTag() for StructField to return Struct property Tag (seems unused)

Documentation

Index

Constants

View Source
const (
	CommonDialectName   = "common"
	CommonBoolean       = "BOOLEAN"
	CommonInteger       = "INTEGER"
	CommonAutoIncrement = "INTEGER AUTO_INCREMENT"
	CommonBigint        = "BIGINT"
	CommonFloat         = "FLOAT"
	CommonVarchar       = "VARCHAR"
	CommonTimestamp     = "TIMESTAMP"
	CommonBinary        = "BINARY"

	CommonHasindexsql  = "SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = ? AND table_name = ? AND index_name = ?"
	CommonDropindex    = "DROP INDEX %v"
	CommonHastableSql  = "SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?"
	CommonHascolumnSql = "SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = ? AND table_name = ? AND column_name = ?"
	CommonSelectDb     = "SELECT DATABASE()"
)
View Source
const (
	MysqlDialectName   = "mysql"
	MysqlBooleanType   = "boolean"
	MysqlIntType       = "int"
	MysqlAutoIncrement = "AUTO_INCREMENT"
	MysqlUnsigned      = "unsigned"
	MysqlBigint        = "bigint"
	MysqlDouble        = "double"
	MysqlLongtext      = "longtext"
	MysqlVarchar       = "varchar"
	MysqlTimestamp     = "timestamp"
	MysqlLongblog      = "longblob"
	MysqlVarbinary     = "varbinary"

	MysqlHasForeignKey = "" /* 156-byte string literal not displayed */
	MysqlDropIndex     = "DROP INDEX %v ON %v"
	MysqlSelectDb      = "SELECT DATABASE()"
)
View Source
const (
	PgDialectName = "postgres"
	PgBooleanType = "boolean"
	PgIntType     = "integer"
	PgSerial      = "serial"
	PgBigSerial   = "bigserial"
	PgBigint      = "bigint"
	PgNumeric     = "numeric"
	PgText        = "text"
	PgTimestamp   = "timestamp with time zone"
	PgVarchar     = "varchar(%d)"
	PgHstore      = "hstore"
	PgBytea       = "bytea"
	PgUuid        = "uuid"

	PgHasindexSql  = "SELECT count(*) FROM pg_indexes WHERE tablename = $1 AND indexname = $2"
	PgHasfkSql     = "" /* 128-byte string literal not displayed */
	PgHastableSql  = "SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE table_name = $1 AND table_type = 'BASE TABLE'"
	PgHascolumnSql = "SELECT count(*) FROM INFORMATION_SCHEMA.columns WHERE table_name = $1 AND column_name = $2"
	PgCurrdbSql    = "SELECT CURRENT_DATABASE()"
)
View Source
const (
	SqliteDialectName = "sqlite3"
	SqliteBool        = "bool"
	SqliteInteger     = "integer"
	SqlitePk          = "integer primary key autoincrement"
	SqliteBigint      = "bigint"
	SqliteReal        = "real"
	SqliteVarchar     = "varchar(%d)"
	SqliteDatetime    = "datetime"
	SqliteBlob        = "blob"
	SqliteText        = "text"

	SqliteHasindexSql  = "SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND sql LIKE '%%INDEX %v ON%%'"
	SqliteHastableSql  = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?"
	SqliteHascolumnSql = "SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND (sql LIKE '%%\"%v\" %%' OR sql LIKE '%%%v %%');\n"
)
View Source
const (
	FieldCreatedAt = "CreatedAt"
	FieldUpdatedAt = "UpdatedAt"
	FieldDeletedAt = "DeletedAt"

	LogOff     int = 1
	LogVerbose int = 2
	LogDebug   int = 3
)

Variables

View Source
var (

	// DefaultTableNameHandler default table name handler
	DefaultTableNameHandler = func(con *DBCon, defaultTableName string) string {
		return defaultTableName
	}

	// 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()
	//    }
	NowFunc = func() time.Time {
		return time.Now()
	}

	// 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")

	// ErrInvalidTransaction invalid transaction 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")
)

Functions

func FieldColumn

func FieldColumn(value reflect.Value, name string) reflect.Value

using inline advantage

func FieldValue

func FieldValue(value reflect.Value, index int) reflect.Value

using inline advantage

func GetType

func GetType(value interface{}) reflect.Type

func IndirectValue

func IndirectValue(value interface{}) reflect.Value

using inline advantage IndirectValue return scope's reflect value's indirect value

func IsZero

func IsZero(value reflect.Value) bool

func RegisterDialect

func RegisterDialect(name string, dialect Dialect)

RegisterDialect register new dialect

func SetZero

func SetZero(value reflect.Value) reflect.Value

Types

type Association

type Association struct {
	Error error
	// contains filtered or unexported fields
}

TODO : @Badu - Association has a field named Error - should be passed to DBCon TODO : @Badu - Association Mode contains some helper methods to handle relationship things easily.

func (*Association) Append

func (a *Association) Append(values ...interface{}) *Association

Append append new associations for many2many, has_many, replace current association for has_one, belongs_to

func (*Association) Clear

func (a *Association) Clear() *Association

Clear remove relationship between source & current associations, won't delete those associations

func (*Association) Count

func (a *Association) Count() int

Count return the count of current associations

func (*Association) Delete

func (a *Association) Delete(values ...interface{}) *Association

Delete remove relationship between source & passed arguments, but won't delete those arguments

func (*Association) Find

func (a *Association) Find(value interface{}) *Association

Find find out all related associations

func (*Association) Replace

func (a *Association) Replace(values ...interface{}) *Association

Replace replace current associations with new one

type Callbacks

type Callbacks struct {
	// contains filtered or unexported fields
}

Callback is a struct that contains all CURD 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 (*Callbacks) Create

func (c *Callbacks) Create() *CallbacksProcessor

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 (*Callbacks) Delete

func (c *Callbacks) Delete() *CallbacksProcessor

Delete could be used to register callbacks for deleting object, refer `Create` for usage

func (*Callbacks) GetCreates

func (c *Callbacks) GetCreates() ScopedFuncs

Added for tests : DO NOT USE DIRECTLY

func (*Callbacks) GetDeletes

func (c *Callbacks) GetDeletes() ScopedFuncs

func (*Callbacks) GetQueries

func (c *Callbacks) GetQueries() ScopedFuncs

func (*Callbacks) GetUpdates

func (c *Callbacks) GetUpdates() ScopedFuncs

func (*Callbacks) Query

func (c *Callbacks) Query() *CallbacksProcessor

Query could be used to register callbacks for querying objects with query methods like `Find`, `First`, `Related`, `Association`... Refer `Create` for usage

func (*Callbacks) RowQuery

func (c *Callbacks) RowQuery() *CallbacksProcessor

RowQuery could be used to register callbacks for querying objects with `Row`, `Rows`, refer `Create` for usage

func (*Callbacks) Update

func (c *Callbacks) Update() *CallbacksProcessor

Update could be used to register callbacks for updating object, refer `Create` for usage

type CallbacksProcessor

type CallbacksProcessor struct {
	// contains filtered or unexported fields
}

CallbackProcessor contains callback informations

func (*CallbacksProcessor) After

func (c *CallbacksProcessor) After(callbackName string) *CallbacksProcessor

After insert a new callback after callback `callbackName`, refer `Callbacks.Create`

func (*CallbacksProcessor) Before

func (c *CallbacksProcessor) Before(callbackName string) *CallbacksProcessor

Before insert a new callback before callback `callbackName`, refer `Callbacks.Create`

func (*CallbacksProcessor) Get

func (c *CallbacksProcessor) Get(callbackName string) ScopedFunc

Get registered callback

db.Callback().Create().Get("gorm:create")

func (*CallbacksProcessor) Register

func (c *CallbacksProcessor) Register(callbackName string, callback ScopedFunc)

Register a new callback, refer `Callbacks.Create`

func (*CallbacksProcessor) Remove

func (c *CallbacksProcessor) Remove(callbackName string)

Remove a registered callback

db.Callback().Create().Remove("gorm:update_time_stamp_when_create")

func (*CallbacksProcessor) Replace

func (c *CallbacksProcessor) Replace(callbackName string, callback ScopedFunc)

Replace a registered callback with new callback

    db.Callback().Create().Replace("gorm:update_time_stamp_when_create", func(*Scope) {
		   scope.SetColumn("Created", now)
		   scope.SetColumn("Updated", now)
    })

type CallbacksProcessors

type CallbacksProcessors []*CallbacksProcessor

easier to read and can apply methods

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

func (Collector) String

func (c Collector) String() string

type DB

type DB struct {
	DBCon
}

declared to allow existing code to run, dbcon.Open(...) db = &gorm.DB{*dbcon}

type DBCon

type DBCon struct {
	Error error

	RowsAffected int64 //TODO : @Badu - this should sit inside Scope, because it's contextual
	// contains filtered or unexported fields
}

DBCon contains information for current db connection

func Open

func Open(dialectName string, args ...interface{}) (*DBCon, error)

func (*DBCon) AddError

func (con *DBCon) AddError(err error) error

////////////////////////////////////////////////////////////////////////////// Errors ////////////////////////////////////////////////////////////////////////////// AddError add error to the db

func (*DBCon) AddForeignKey

func (con *DBCon) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DBCon

AddForeignKey Add foreign key to the given scope, e.g:

db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")

TODO : @Badu - make it work with interfaces instead of strings (field, dest)

func (*DBCon) AddIndex

func (con *DBCon) AddIndex(indexName string, columns ...string) *DBCon

AddIndex add index for columns with given name

func (*DBCon) AddUniqueIndex

func (con *DBCon) AddUniqueIndex(indexName string, columns ...string) *DBCon

AddUniqueIndex add unique index for columns with given name

func (*DBCon) AsSQLDB

func (con *DBCon) AsSQLDB() sqlInterf

CommonDB return the underlying `*sql.DB` or `*sql.Tx` instance, mainly intended to allow coexistence with legacy non-GORM code.

func (*DBCon) Assign

func (con *DBCon) Assign(attrs ...interface{}) *DBCon

Assign assign result with argument regardless it is found or not with `FirstOrInit` or `FirstOrCreate` Note : no scope

func (*DBCon) Association

func (con *DBCon) Association(column string) *Association

Association start `Association Mode` to handler relations things easier in that mode

func (*DBCon) Attrs

func (con *DBCon) Attrs(attrs ...interface{}) *DBCon

Attrs initialize struct with argument if record not found with `FirstOrInit` or `FirstOrCreate` Note : no scope

func (*DBCon) AutoMigrate

func (con *DBCon) AutoMigrate(values ...interface{}) *DBCon

AutoMigrate run auto migration for given models, will only add missing fields, won't delete/change current data

func (*DBCon) Begin

func (con *DBCon) Begin() *DBCon

Begin begin a transaction

func (*DBCon) Callback

func (con *DBCon) Callback() *Callbacks

Callback return `Callbacks` container, you could add/change/delete callbacks with it

db.Callback().Create().Register("update_created_at", updateCreated)

func (*DBCon) Close

func (con *DBCon) Close() error

////////////////////////////////////////////////////////////////////////////// scoped and other methods ////////////////////////////////////////////////////////////////////////////// Close close current db connection

func (*DBCon) Commit

func (con *DBCon) Commit() *DBCon

Commit commit a transaction

func (*DBCon) Count

func (con *DBCon) Count(value interface{}) *DBCon

Count get how many records for a model

func (*DBCon) Create

func (con *DBCon) Create(value interface{}) *DBCon

Create insert the value into database

func (*DBCon) CreateTable

func (con *DBCon) CreateTable(models ...interface{}) *DBCon

CreateTable create table for models

func (*DBCon) DB

func (con *DBCon) DB() *sql.DB

gets interface casted to `*sql.DB` from current connection

func (*DBCon) Debug

func (con *DBCon) Debug() *DBCon

Debug start debug mode

func (*DBCon) Delete

func (con *DBCon) Delete(value interface{}, where ...interface{}) *DBCon

Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition

func (*DBCon) Dialect

func (con *DBCon) Dialect() Dialect

Dialect get dialect

func (*DBCon) DropColumn

func (con *DBCon) DropColumn(column string) *DBCon

DropColumn drop a column

func (*DBCon) DropTable

func (con *DBCon) DropTable(values ...interface{}) *DBCon

DropTable drop table for models

func (*DBCon) DropTableIfExists

func (con *DBCon) DropTableIfExists(values ...interface{}) *DBCon

DropTableIfExists drop table if it is exist

func (*DBCon) Exec

func (con *DBCon) Exec(sql string, values ...interface{}) *DBCon

Exec execute raw sql

func (*DBCon) Find

func (con *DBCon) Find(out interface{}, where ...interface{}) *DBCon

Find find records that match given conditions

func (*DBCon) First

func (con *DBCon) First(entity interface{}, where ...interface{}) *DBCon

First find first record that match given conditions, order by primary key

func (*DBCon) FirstOrCreate

func (con *DBCon) FirstOrCreate(out interface{}, where ...interface{}) *DBCon

FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)

func (*DBCon) FirstOrInit

func (con *DBCon) FirstOrInit(out interface{}, where ...interface{}) *DBCon

FirstOrInit find first matched record or initialize a new one with given conditions (only works with struct, map conditions)

func (*DBCon) Get

func (con *DBCon) Get(name string) (interface{}, bool)

Get get setting by name

func (*DBCon) GetErrors

func (con *DBCon) GetErrors() []error

GetErrors get happened errors from the db

func (*DBCon) Group

func (con *DBCon) Group(query string) *DBCon

Group specify the group method on the find Note : no scope

func (*DBCon) HasTable

func (con *DBCon) HasTable(value interface{}) bool

HasTable check has table or not

func (*DBCon) Having

func (con *DBCon) Having(query string, values ...interface{}) *DBCon

Having specify HAVING conditions for GROUP BY Note : no scope

func (*DBCon) Joins

func (con *DBCon) Joins(query string, args ...interface{}) *DBCon

Joins specify Joins conditions

db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "user@example.org").Find(&user)

Note:no scope

func (*DBCon) KnownModelStructs

func (con *DBCon) KnownModelStructs() map[reflect.Type]*ModelStruct

func (*DBCon) KnownNames

func (con *DBCon) KnownNames(name string) string

func (*DBCon) Last

func (con *DBCon) Last(entity interface{}, where ...interface{}) *DBCon

Last find last record that match given conditions, order by primary key

func (*DBCon) Limit

func (con *DBCon) Limit(limit interface{}) *DBCon

Limit specify the number of records to be retrieved Note : no scope

func (*DBCon) Log

func (con *DBCon) Log(v ...interface{})

func (*DBCon) LogMode

func (con *DBCon) LogMode(enable bool) *DBCon

LogMode set log mode, `true` for detailed logs, `false` for no log, default, will only print error logs

func (*DBCon) Model

func (con *DBCon) Model(value interface{}) *DBCon

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 (*DBCon) ModifyColumn

func (con *DBCon) ModifyColumn(column string, typ string) *DBCon

ModifyColumn modify column to type

func (*DBCon) NewRecord

func (con *DBCon) NewRecord(value interface{}) bool

NewRecord check if value's primary key is blank

func (*DBCon) NewScope

func (con *DBCon) NewScope(value interface{}) *Scope

NewScope create a scope for current operation

func (*DBCon) Not

func (con *DBCon) Not(query interface{}, args ...interface{}) *DBCon

Not filter records that don't match current conditions, similar to `Where` Note : no scope

func (*DBCon) Offset

func (con *DBCon) Offset(offset interface{}) *DBCon

Offset specify the number of records to skip before starting to return the records Note : no scope

func (*DBCon) Omit

func (con *DBCon) Omit(columns ...string) *DBCon

Omit specify fields that you want to ignore when saving to database for creating, updating Note : no scope

func (*DBCon) Or

func (con *DBCon) Or(query interface{}, args ...interface{}) *DBCon

Or filter records that match before conditions or this one, similar to `Where` Note : no scope

func (*DBCon) Order

func (con *DBCon) Order(value interface{}, reorder ...bool) *DBCon

Order specify order when retrieve records from database, set reorder to `true` to overwrite defined conditions

db.Order("name DESC")
db.Order("name DESC", true) // reorder
db.Order(gorm.Expr("name = ? DESC", "first")) // sql expression

Note : no scope

func (*DBCon) Pluck

func (con *DBCon) Pluck(column string, value interface{}) *DBCon

Pluck used to query single column from a model as a map

var ages []int64
db.Find(&users).Pluck("age", &ages)

func (*DBCon) Preload

func (con *DBCon) Preload(column string, conditions ...interface{}) *DBCon

Preload preload associations with given conditions

db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)

Note : no scope

func (*DBCon) Raw

func (con *DBCon) Raw(sql string, values ...interface{}) *DBCon

Raw use raw sql as conditions, won't run it unless invoked by other methods

db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)

Note : no scope

func (*DBCon) RecordNotFound

func (con *DBCon) RecordNotFound() bool

RecordNotFound check if returning ErrRecordNotFound error

func (*DBCon) Related

func (con *DBCon) Related(value interface{}, foreignKeys ...string) *DBCon

Related get related associations

func (*DBCon) RemoveIndex

func (con *DBCon) RemoveIndex(indexName string) *DBCon

RemoveIndex remove index with name

func (*DBCon) Rollback

func (con *DBCon) Rollback() *DBCon

Rollback rollback a transaction

func (*DBCon) Row

func (con *DBCon) Row() *sql.Row

Row return `*sql.Row` with given conditions

func (*DBCon) Rows

func (con *DBCon) Rows() (*sql.Rows, error)

Rows return `*sql.Rows` with given conditions

func (*DBCon) Save

func (con *DBCon) Save(value interface{}) *DBCon

Save update value in database, if the value doesn't have primary key, will insert it

func (*DBCon) Scan

func (con *DBCon) Scan(dest interface{}) *DBCon

Scan scan value to a struct

func (*DBCon) ScanRows

func (con *DBCon) ScanRows(rows *sql.Rows, result interface{}) error

ScanRows scan `*sql.Rows` to give struct

func (*DBCon) Scopes

func (con *DBCon) Scopes(funcs ...DBConFunc) *DBCon

Scopes pass current database connection to arguments `func(*DBCon) *DBCon`, which could be used to add conditions dynamically

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)

func (*DBCon) Select

func (con *DBCon) Select(query string, args ...interface{}) *DBCon

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 Note : no scope

func (*DBCon) Set

func (con *DBCon) Set(name string, value interface{}) *DBCon

Set set setting by name, which could be used in callbacks, will clone a new db, and update its setting

func (*DBCon) SetJoinTableHandler

func (con *DBCon) SetJoinTableHandler(source interface{}, column string, handler JoinTableHandlerInterface)

SetJoinTableHandler set a model's join table handler for a relation

func (*DBCon) SetLogMode

func (con *DBCon) SetLogMode(mode int)

func (*DBCon) SetLogger

func (con *DBCon) SetLogger(log logger)

SetLogger replace default logger

func (*DBCon) SingularTable

func (con *DBCon) SingularTable(enable bool)

SingularTable use singular table by default

func (*DBCon) Table

func (con *DBCon) Table(name string) *DBCon

Table specify the table you would like to run db operations

func (*DBCon) Unscoped

func (con *DBCon) Unscoped() *DBCon

Unscoped return all record including deleted record, refer Soft Delete Note : no scope (as the name says)

func (*DBCon) Update

func (con *DBCon) Update(attrs ...interface{}) *DBCon

Update update attributes with callbacks

func (*DBCon) UpdateColumn

func (con *DBCon) UpdateColumn(attrs ...interface{}) *DBCon

UpdateColumn update attributes without callbacks

func (*DBCon) UpdateColumns

func (con *DBCon) UpdateColumns(values interface{}) *DBCon

UpdateColumns update attributes without callbacks

func (*DBCon) Updates

func (con *DBCon) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DBCon

Updates update attributes with callbacks

func (*DBCon) Where

func (con *DBCon) Where(query interface{}, args ...interface{}) *DBCon

////////////////////////////////////////////////////////////////////////////// "unscoped" methods ////////////////////////////////////////////////////////////////////////////// Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions Note : no scope

type DBConFunc

type DBConFunc func(*DBCon) *DBCon

type DefaultForeignKeyNamer

type DefaultForeignKeyNamer struct {
}

DefaultForeignKeyNamer contains the default foreign key name generator method

func (DefaultForeignKeyNamer) BuildForeignKeyName

func (DefaultForeignKeyNamer) BuildForeignKeyName(tableName, field, dest string) string

type Dialect

type Dialect interface {
	// GetName get dialect's name
	GetName() string
	// SetDB set db for dialect
	SetDB(db *sql.DB)
	// BindVar return the placeholder for actual values in SQL statements, in many dbs it is "?", Postgres using $1
	BindVar(i int) string
	// GetQuoter returns the rune for quoting field name to avoid SQL parsing exceptions by using a reserved word as a field name
	//TODO : @Badu - should return a rune
	GetQuoter() 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
	// LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case
	LimitAndOffsetSQL(limit, offset interface{}) string
	// SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
	SelectFromDummyTable() string
	// LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING`
	LastInsertIDReturningSuffix(tableName, columnName string) string
	// BuildForeignKeyName returns a foreign key name for the given table, field and reference
	BuildForeignKeyName(tableName, field, dest string) string
	// CurrentDatabase return current database name
	CurrentDatabase() string
}

Dialect interface contains behaviors that differ across SQL database

type GormErrors

type GormErrors []error

Errors contains all happened errors

func (GormErrors) Add

func (e GormErrors) Add(newErrors ...error) GormErrors

func (GormErrors) Error

func (e GormErrors) Error() string

Add add an error

func (GormErrors) GetErrors

func (e GormErrors) GetErrors() []error

GetErrors get all happened errors

type JoinTableForeignKey

type JoinTableForeignKey struct {
	DBName            string
	AssociationDBName string
}

JoinTableForeignKey join table foreign key struct TODO : @Badu -this holds some sort of processed clone of FOREIGN_DB_NAMES, FOREIGN_FIELD_NAMES, ASSOCIATION_FOREIGN_FIELD_NAMES, ASSOCIATION_FOREIGN_DB_NAMES

type JoinTableHandler

type JoinTableHandler struct {
	TableName   string        `sql:"-"`
	Source      JoinTableInfo `sql:"-"`
	Destination JoinTableInfo `sql:"-"`
}

JoinTableHandler default join table handler

func (JoinTableHandler) Add

func (h JoinTableHandler) Add(handler JoinTableHandlerInterface, con *DBCon, source interface{}, destination interface{}) error

implementation of JoinTableHandlerInterface Add create relationship in join table for source and destination

func (JoinTableHandler) Delete

func (h JoinTableHandler) Delete(handler JoinTableHandlerInterface, con *DBCon) error

implementation of JoinTableHandlerInterface Delete delete relationship in join table for sources

func (*JoinTableHandler) DestinationForeignKeys

func (h *JoinTableHandler) DestinationForeignKeys() []JoinTableForeignKey

implementation of JoinTableHandlerInterface DestinationForeignKeys return destination foreign keys

func (*JoinTableHandler) GetHandlerStruct

func (h *JoinTableHandler) GetHandlerStruct() *JoinTableHandler

for debugging

func (JoinTableHandler) JoinWith

func (h JoinTableHandler) JoinWith(handler JoinTableHandlerInterface, con *DBCon, source interface{}) *DBCon

implementation of JoinTableHandlerInterface JoinWith query with `Join` conditions

func (*JoinTableHandler) SetTable

func (h *JoinTableHandler) SetTable(name string)

implementation of JoinTableHandlerInterface

func (*JoinTableHandler) Setup

func (h *JoinTableHandler) Setup(
	field *StructField,
	source reflect.Type,
	destination reflect.Type)

implementation of JoinTableHandlerInterface Setup initialize a default join table handler

func (*JoinTableHandler) SourceForeignKeys

func (h *JoinTableHandler) SourceForeignKeys() []JoinTableForeignKey

implementation of JoinTableHandlerInterface SourceForeignKeys return source foreign keys

func (JoinTableHandler) String

func (h JoinTableHandler) String() string

implementation of Stringer

func (JoinTableHandler) Table

func (h JoinTableHandler) Table(db *DBCon) string

implementation of JoinTableHandlerInterface Table return join table's table name

type JoinTableHandlerInterface

type JoinTableHandlerInterface interface {
	// initialize join table handler
	Setup(field *StructField, source reflect.Type, destination reflect.Type)
	// Table return join table's table name
	Table(db *DBCon) string
	// Sets table name
	SetTable(name string)
	// Add create relationship in join table for source and destination
	Add(handler JoinTableHandlerInterface, db *DBCon, source interface{}, destination interface{}) error
	// Delete delete relationship in join table for sources
	Delete(handler JoinTableHandlerInterface, db *DBCon) error
	// JoinWith query with `Join` conditions
	JoinWith(handler JoinTableHandlerInterface, db *DBCon, source interface{}) *DBCon
	// SourceForeignKeys return source foreign keys
	SourceForeignKeys() []JoinTableForeignKey
	// DestinationForeignKeys return destination foreign keys
	DestinationForeignKeys() []JoinTableForeignKey
	//for debugging purposes
	GetHandlerStruct() *JoinTableHandler
}

JoinTableHandlerInterface is an interface for how to handle many2many relations

type JoinTableInfo

type JoinTableInfo 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 Logger

type Logger struct {
	LogWriter
}

Logger default logger

func (Logger) Print

func (l Logger) Print(values ...interface{})

Print format & print log

type Model

type Model struct {
	ID        uint `gorm:"primary_key"`
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt *time.Time `sql:"index"`
}

Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models

type User struct {
  gorm.Model
}

type ModelStruct

type ModelStruct struct {
	ModelType reflect.Type
	// contains filtered or unexported fields
}

ModelStruct model definition

func (*ModelStruct) Create

func (m *ModelStruct) Create(scope *Scope)

func (*ModelStruct) FieldByName

func (m *ModelStruct) FieldByName(column string, con *DBCon) (*StructField, bool)

func (*ModelStruct) HasColumn

func (m *ModelStruct) HasColumn(column string) bool

func (*ModelStruct) Interface

func (m *ModelStruct) Interface() interface{}

func (*ModelStruct) PKs

func (m *ModelStruct) PKs() StructFields

func (ModelStruct) String

func (m ModelStruct) String() string

implementation of Stringer

func (*ModelStruct) StructFields

func (m *ModelStruct) StructFields() StructFields

func (*ModelStruct) TableName

func (m *ModelStruct) TableName(db *DBCon) string

TableName get model's table name

type Scope

type Scope struct {
	Search *Search

	Value interface{}
	// contains filtered or unexported fields
}

Scope contain current operation's information when you perform any operation on the database

func (*Scope) CallMethod

func (s *Scope) CallMethod(methodName string)

CallMethod call scope value's method, if it is a slice, will call its element's method one by one

func (*Scope) Err

func (s *Scope) Err(err error) error

Err add error to Scope

func (*Scope) Exec

func (s *Scope) Exec() *Scope

Exec perform generated SQL

func (*Scope) FieldByName

func (s *Scope) FieldByName(name string) (*StructField, bool)

FieldByName find `gorm.StructField` with field name or db name

func (*Scope) Fields

func (s *Scope) Fields() StructFields

Fields get value's fields from ModelStruct

func (*Scope) Get

func (s *Scope) Get(settingType uint64) (interface{}, bool)

Get get setting by name

func (*Scope) GetModelStruct

func (s *Scope) GetModelStruct() *ModelStruct

GetModelStruct get value's model struct, relationships based on struct and tag definition

func (*Scope) HasError

func (s *Scope) HasError() bool

HasError check if there are any error

func (*Scope) PK

func (s *Scope) PK() *StructField

was PrimaryField() - PK() 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) PKName

func (s *Scope) PKName() string

was PrimaryKey() - PKName() get main primary field's db name

func (*Scope) PKs

func (s *Scope) PKs() StructFields

was PrimaryFields() : PKs() return scope's primary fields

func (*Scope) PrimaryField

func (s *Scope) PrimaryField() *StructField

deprecated

func (*Scope) PrimaryFields

func (s *Scope) PrimaryFields() StructFields

deprecated

func (*Scope) PrimaryKey

func (s *Scope) PrimaryKey() string

deprecated

func (*Scope) PrimaryKeyValue

func (s *Scope) PrimaryKeyValue() interface{}

PrimaryKeyValue get the primary key's value

func (*Scope) PrimaryKeyZero

func (s *Scope) PrimaryKeyZero() bool

PrimaryKeyZero check main primary field's value is blank or not

func (*Scope) Raw

func (s *Scope) Raw(sql string) *Scope

Raw set raw sql

func (*Scope) Set

func (s *Scope) Set(settingType uint64, value interface{}) *Scope

Set set value by name

func (*Scope) SetColumn

func (s *Scope) SetColumn(column interface{}, value interface{}) error

SetColumn to set the column's value, column could be field or field's name/dbname

func (*Scope) TableName

func (s *Scope) TableName() string

TableName return table name

func (*Scope) Warn

func (s *Scope) Warn(v ...interface{})

type ScopedFunc

type ScopedFunc func(*Scope)

type ScopedFuncs

type ScopedFuncs []*ScopedFunc

used for callbacks

type Search struct {
	Conditions SqlConditions

	SQL     string
	SQLVars []interface{}
	Value   interface{} //TODO : @Badu - moved here from DBCon - in the end should use Scope's Value
	// contains filtered or unexported fields
}

func (*Search) Assign

func (s *Search) Assign(attrs ...interface{}) *Search

func (*Search) Attrs

func (s *Search) Attrs(attrs ...interface{}) *Search

func (*Search) Clone

func (s *Search) Clone() *Search

func (*Search) Exec

func (s *Search) Exec(scope *Scope) (sql.Result, error)

func (*Search) Group

func (s *Search) Group(query string) *Search

func (*Search) Having

func (s *Search) Having(query string, values ...interface{}) *Search

func (*Search) IsRaw

func (s *Search) IsRaw() bool

func (*Search) Joins

func (s *Search) Joins(query string, values ...interface{}) *Search

func (*Search) Limit

func (s *Search) Limit(limit interface{}) *Search

TODO : @Badu - do the very same where we need only one instance (aka Singleton) - like select... (where getFirst is used)

func (*Search) Not

func (s *Search) Not(query interface{}, values ...interface{}) *Search

func (*Search) Offset

func (s *Search) Offset(offset interface{}) *Search

func (*Search) Omit

func (s *Search) Omit(columns ...string) *Search

func (*Search) Or

func (s *Search) Or(query interface{}, values ...interface{}) *Search

func (*Search) Order

func (s *Search) Order(value interface{}, reorder ...bool) *Search

func (*Search) Preload

func (s *Search) Preload(schema string, values ...interface{}) *Search

func (*Search) Query

func (s *Search) Query(scope *Scope) (*sql.Rows, error)

func (*Search) QueryRow

func (s *Search) QueryRow(scope *Scope) *sql.Row

func (*Search) Select

func (s *Search) Select(query string, args ...interface{}) *Search

func (*Search) SetRaw

func (s *Search) SetRaw() *Search

func (*Search) Where

func (s *Search) Where(query interface{}, values ...interface{}) *Search

func (*Search) Wheres

func (s *Search) Wheres(wheres ...interface{}) *Search

type SqlConditions

type SqlConditions map[sqlConditionType]sqlCondition

func (SqlConditions) CompareInit

func (c SqlConditions) CompareInit(cond SqlConditions) bool

utils for test case

func (SqlConditions) CompareOrder

func (c SqlConditions) CompareOrder(cond SqlConditions) bool

utils for test case

func (SqlConditions) CompareSelect

func (c SqlConditions) CompareSelect(cond SqlConditions) bool

utils for test case

func (SqlConditions) CompareWhere

func (c SqlConditions) CompareWhere(cond SqlConditions) bool

utils for test case

type SqlPair

type SqlPair struct {
	// contains filtered or unexported fields
}

func SqlExpr

func SqlExpr(expression interface{}, args ...interface{}) *SqlPair

Expr generate raw SQL expression, for example:

DB.Model(&product).Update("price", gorm.SqlPair("price * ? + ?", 2, 100))

type StrSlice

type StrSlice []string

============================================ Slice of strings for better reading ============================================

type StructField

type StructField struct {
	DBName     string
	StructName string
	Names      []string

	Value reflect.Value
	Type  reflect.Type
	// contains filtered or unexported fields
}

StructField model field's struct definition

func NewStructField

func NewStructField(fromStruct reflect.StructField, toDBName string) (*StructField, error)

func (*StructField) GetAssocFKs

func (f *StructField) GetAssocFKs() StrSlice

func (*StructField) GetAssociationDBNames

func (f *StructField) GetAssociationDBNames() StrSlice

func (*StructField) GetAssociationForeignFieldNames

func (f *StructField) GetAssociationForeignFieldNames() StrSlice

func (*StructField) GetFKs

func (f *StructField) GetFKs() StrSlice

func (*StructField) GetForeignDBNames

func (f *StructField) GetForeignDBNames() StrSlice

func (*StructField) GetForeignFieldNames

func (f *StructField) GetForeignFieldNames() StrSlice

func (*StructField) GetStrSetting

func (f *StructField) GetStrSetting(named uint8) string

TODO : make methods for each setting (readable code)

func (*StructField) HasDefaultValue

func (f *StructField) HasDefaultValue() bool

func (*StructField) HasNotNullSetting

func (f *StructField) HasNotNullSetting() bool

func (*StructField) HasRelations

func (f *StructField) HasRelations() bool

func (*StructField) HasSetting

func (f *StructField) HasSetting(named uint8) bool

gets a key (for code readability)

func (*StructField) Interface

func (f *StructField) Interface() interface{}

func (*StructField) IsAutoIncrement

func (f *StructField) IsAutoIncrement() bool

func (*StructField) IsBlank

func (f *StructField) IsBlank() bool

func (*StructField) IsEmbedOrAnon

func (f *StructField) IsEmbedOrAnon() bool

func (*StructField) IsForeignKey

func (f *StructField) IsForeignKey() bool

func (*StructField) IsIgnored

func (f *StructField) IsIgnored() bool

func (*StructField) IsNormal

func (f *StructField) IsNormal() bool

func (*StructField) IsPointer

func (f *StructField) IsPointer() bool

func (*StructField) IsPrimaryKey

func (f *StructField) IsPrimaryKey() bool

func (*StructField) IsScanner

func (f *StructField) IsScanner() bool

func (*StructField) IsSlice

func (f *StructField) IsSlice() bool

func (*StructField) IsStruct

func (f *StructField) IsStruct() bool

func (*StructField) IsTime

func (f *StructField) IsTime() bool

func (*StructField) JoinHandler

func (f *StructField) JoinHandler() JoinTableHandlerInterface

func (*StructField) LinkPoly

func (f *StructField) LinkPoly(withField *StructField, tableName string)

func (*StructField) ParseFieldStructForDialect

func (f *StructField) ParseFieldStructForDialect() (reflect.Value, string, int, string)

ParseFieldStructForDialect parse field struct for dialect

func (*StructField) RelKind

func (f *StructField) RelKind() uint8

func (*StructField) RelationIsBelongsTo

func (f *StructField) RelationIsBelongsTo() bool

func (*StructField) RelationIsHasMany

func (f *StructField) RelationIsHasMany() bool

func (*StructField) RelationIsHasOne

func (f *StructField) RelationIsHasOne() bool

func (*StructField) RelationIsMany2Many

func (f *StructField) RelationIsMany2Many() bool

func (*StructField) Set

func (f *StructField) Set(value interface{}) error

func (*StructField) SetHasRelations

func (f *StructField) SetHasRelations()

func (*StructField) SetIsAutoIncrement

func (f *StructField) SetIsAutoIncrement()

Set set a value to the field

func (*StructField) SetIsBlank

func (f *StructField) SetIsBlank()

func (*StructField) SetIsForeignKey

func (f *StructField) SetIsForeignKey()

func (*StructField) SetIsNormal

func (f *StructField) SetIsNormal()

func (*StructField) SetIsPrimaryKey

func (f *StructField) SetIsPrimaryKey()

func (*StructField) SetTagSetting

func (f *StructField) SetTagSetting(named uint8, value interface{})

func (StructField) String

func (f StructField) String() string

implementation of Stringer

func (*StructField) UnsetCheckRelations

func (f *StructField) UnsetCheckRelations()

func (*StructField) UnsetIsAutoIncrement

func (f *StructField) UnsetIsAutoIncrement()

func (*StructField) UnsetIsBlank

func (f *StructField) UnsetIsBlank()

func (*StructField) UnsetIsPrimaryKey

func (f *StructField) UnsetIsPrimaryKey()

func (*StructField) UnsetTagSetting

func (f *StructField) UnsetTagSetting(named uint8)

func (*StructField) WillCheckRelations

func (f *StructField) WillCheckRelations() bool

type StructFields

type StructFields []*StructField

easier to read and can apply methods

type TagSettings

type TagSettings struct {
	Uint8Map
	// contains filtered or unexported fields
}

since there is no other way of embedding a map

func (TagSettings) String

func (t TagSettings) String() string

Stringer implementation

type Uint8Map

type Uint8Map map[uint8]interface{}

Directories

Path Synopsis
dialects

Jump to

Keyboard shortcuts

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