96 lines
3.2 KiB
Markdown
96 lines
3.2 KiB
Markdown
# Development
|
|
|
|
<!-- toc -->
|
|
|
|
## Architecture
|
|
|
|
Gorm use chainable API, `*gorm.DB` is the bridge of chains, for each chain API, it will create a new relation.
|
|
|
|
```go
|
|
db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")
|
|
|
|
// create a new relation
|
|
db = db.Where("name = ?", "jinzhu")
|
|
|
|
// filter even more
|
|
if SomeCondition {
|
|
db = db.Where("age = ?", 20)
|
|
} else {
|
|
db = db.Where("age = ?", 30)
|
|
}
|
|
if YetAnotherCondition {
|
|
db = db.Where("active = ?", 1)
|
|
}
|
|
```
|
|
|
|
When we start to perform any operations, GROM will create a new `*gorm.Scope` instance based on current `*gorm.DB`
|
|
|
|
```go
|
|
// perform a querying operation
|
|
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](callbacks.html#querying-an-object)
|
|
|
|
## Write Plugins
|
|
|
|
GORM itself is powered by `Callbacks`, so you could fully customize GORM as you want
|
|
|
|
### Register a new callback
|
|
|
|
func updateCreated(scope *Scope) {
|
|
if scope.HasColumn("Created") {
|
|
scope.SetColumn("Created", NowFunc())
|
|
}
|
|
}
|
|
|
|
db.Callback().Create().Register("update_created_at", updateCreated)
|
|
// register a callback for Create process
|
|
|
|
### Delete an existing callback
|
|
|
|
db.Callback().Create().Remove("gorm:create")
|
|
// delete callback `gorm:create` from Create callbacks
|
|
|
|
### Replace an existing callback
|
|
|
|
db.Callback().Create().Replace("gorm:create", newCreateFunction)
|
|
// replace callback `gorm:create` with new function `newCreateFunction` for Create process
|
|
|
|
### Register callback orders
|
|
|
|
db.Callback().Create().Before("gorm:create").Register("update_created_at", updateCreated)
|
|
db.Callback().Create().After("gorm:create").Register("update_created_at", updateCreated)
|
|
db.Callback().Query().After("gorm:query").Register("my_plugin:after_query", afterQuery)
|
|
db.Callback().Delete().After("gorm:delete").Register("my_plugin:after_delete", afterDelete)
|
|
db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", beforeUpdate)
|
|
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
|
|
|
|
- [Create callbacks](https://github.com/jinzhu/gorm/blob/master/callback_create.go)
|
|
|
|
- [Update callbacks](https://github.com/jinzhu/gorm/blob/master/callback_update.go)
|
|
|
|
- [Query callbacks](https://github.com/jinzhu/gorm/blob/master/callback_query.go)
|
|
|
|
- [Delete callbacks](https://github.com/jinzhu/gorm/blob/master/callback_delete.go)
|
|
|
|
- Row Query callbacks
|
|
|
|
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:
|
|
|
|
```go
|
|
func updateTableName(scope *gorm.Scope) {
|
|
scope.Search.Table(scope.TableName() + "_draft") // append `_draft` to table name
|
|
}
|
|
|
|
db.Callback().RowQuery().Register("publish:update_table_name", updateTableName)
|
|
```
|
|
|
|
View [https://godoc.org/github.com/jinzhu/gorm](https://godoc.org/github.com/jinzhu/gorm) to view all available API
|