Development

Architecture

Gorm use chainable API, *gorm.DB is the bridge of chains, for each chain API, it will create a new relation.

  1. db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")
  2. // create a new relation
  3. db = db.Where("name = ?", "jinzhu")
  4. // filter even more
  5. if SomeCondition {
  6. db = db.Where("age = ?", 20)
  7. } else {
  8. db = db.Where("age = ?", 30)
  9. }
  10. if YetAnotherCondition {
  11. db = db.Where("active = ?", 1)
  12. }

When we start to perform any operations, GORM will create a new *gorm.Scope instance based on current *gorm.DB

  1. // perform a querying operation
  2. db.First(&user)

And based on current operation’s type, it will call registered creating, updating, querying, deleting or row_querying callbacks to run the operation.

For above example, will call querying callbacks, refer Querying Callbacks

Write Plugins

GORM itself is powered by Callbacks, so you could fully customize GORM as you want

Register a new callback

  1. func updateCreated(scope *Scope) {
  2. if scope.HasColumn("Created") {
  3. scope.SetColumn("Created", NowFunc())
  4. }
  5. }
  6. db.Callback().Create().Register("update_created_at", updateCreated)
  7. // register a callback for Create process

Delete an existing callback

  1. db.Callback().Create().Remove("gorm:create")
  2. // delete callback `gorm:create` from Create callbacks

Replace an existing callback

  1. db.Callback().Create().Replace("gorm:create", newCreateFunction)
  2. // replace callback `gorm:create` with new function `newCreateFunction` for Create process

Register callback orders

  1. db.Callback().Create().Before("gorm:create").Register("update_created_at", updateCreated)
  2. db.Callback().Create().After("gorm:create").Register("update_created_at", updateCreated)
  3. db.Callback().Query().After("gorm:query").Register("my_plugin:after_query", afterQuery)
  4. db.Callback().Delete().After("gorm:delete").Register("my_plugin:after_delete", afterDelete)
  5. db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", beforeUpdate)
  6. db.Callback().Create().Before("gorm:create").After("gorm:before_create").Register("my_plugin:before_create", beforeCreate)

Pre-Defined Callbacks

GORM has defiend callbacks to perform its CRUD operations, check them out before start write your plugins

Row Query callbacks will be called when run Row or Rows, by default there is no registered callbacks for it, you could register a new one like:

  1. func updateTableName(scope *gorm.Scope) {
  2. scope.Search.Table(scope.TableName() + "_draft") // append `_draft` to table name
  3. }
  4. db.Callback().RowQuery().Register("publish:update_table_name", updateTableName)

View https://godoc.org/github.com/jinzhu/gorm to view all available API