diff --git a/documents/SUMMARY.md b/documents/SUMMARY.md index b6a66634..7fb70aa7 100644 --- a/documents/SUMMARY.md +++ b/documents/SUMMARY.md @@ -29,5 +29,6 @@ * [Composite Primary Key](advanced.md#compose-primary-key) * [Overriding Logger](advanced.md#logger) * [Development](development.md) - * [Write Plugins](development.md#callbacks) + * [Architecture](development.md#architecture) + * [Write Plugins](development.md#write-plugins) * [Change Log](changelog.md) diff --git a/documents/advanced.md b/documents/advanced.md index 99559165..c563e3a3 100644 --- a/documents/advanced.md +++ b/documents/advanced.md @@ -64,16 +64,29 @@ func CreateAnimals(db *gorm.DB) err { } ``` -## Raw SQL +## SQL Builder + +#### Run Raw SQL + +Run Raw SQL ```go db.Exec("DROP TABLE users;") db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33}) + +// Scan +type Result struct { + Name string + Age int +} + +var result Result +db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result) ``` -## Row & Rows +#### sql.Row & sql.Rows -It is even possible to get query result as `*sql.Row` or `*sql.Rows` +Get query result as `*sql.Row` or `*sql.Rows` ```go row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row) @@ -97,7 +110,7 @@ for rows.Next() { } ``` -### Scan Rows +#### Scan sql.Rows In Iteration ```go rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error) @@ -112,22 +125,27 @@ for rows.Next() { ## Generic database interface sql.DB -Get generic database interface from `*gorm.DB` connection [*sql.DB](http://golang.org/pkg/database/sql/#DB) +Get generic database interface [*sql.DB](http://golang.org/pkg/database/sql/#DB) from `*gorm.DB` connection ```go -// Get generic database object *sql.DB to use its functions +// Get generic database object `*sql.DB` to use its functions db.DB() -// Connection Pool -db.DB().SetMaxIdleConns(10) -db.DB().SetMaxOpenConns(100) - - // Ping +// Ping db.DB().Ping() ``` +#### Connection Pool + +```go +db.DB().SetMaxIdleConns(10) +db.DB().SetMaxOpenConns(100) +``` + ## Composite Primary Key +Set multiple fields as priamry key to enable composite primary key + ```go type Product struct { ID string `gorm:"primary_key"` @@ -137,25 +155,24 @@ type Product struct { ## Logger -Gorm has built-in logger support +Gorm has built-in logger support, by default, it will print happened errors ```go -// Enable Logger +// Enable Logger, show detailed log db.LogMode(true) -// Diable Logger +// Diable Logger, don't show any log db.LogMode(false) -// Debug a single operation +// Debug a single operation, show detailed log for this operation db.Debug().Where("name = ?", "jinzhu").First(&User{}) ``` -![logger](https://raw.github.com/jinzhu/gorm/master/doc/logger.png) +#### Customize Logger -### Customize Logger +Refer GORM's default logger for how to customize it [https://github.com/jinzhu/gorm/blob/master/logger.go](https://github.com/jinzhu/gorm/blob/master/logger.go) ```go -// Refer gorm's default logger for how to: https://github.com/jinzhu/gorm/blob/master/logger.go#files db.SetLogger(gorm.Logger{revel.TRACE}) db.SetLogger(log.New(os.Stdout, "\r\n", 0)) ``` diff --git a/documents/curd.md b/documents/curd.md index 144cf4eb..8a0c5145 100644 --- a/documents/curd.md +++ b/documents/curd.md @@ -445,7 +445,7 @@ db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzh ### Pluck -Query single column from a model as a map +Query single column from a model as a map, if you want to query multiple columns, you could use [`Scan`](#scan) ```go var ages []int64 diff --git a/documents/development.md b/documents/development.md index 021cc1f9..ae50d2f1 100644 --- a/documents/development.md +++ b/documents/development.md @@ -1,29 +1,35 @@ -# Gorm Development +# Development ## Architecture -The most notable component of Gorm is`gorm.DB`, which hold database connection. It could be initialized like this: +Gorm use chainable API, `*gorm.DB` is the bridge of chains, for each chain API, it will create a new relation. - db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable") +```go +db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable") -Gorm has chainable API, `gorm.DB` is the bridge of chains, it save related information and pass it to the next chain. +// create a new relation +db = db.Where("name = ?", "jinzhu") -Lets use below code to explain how it works: +// create another new relation +db = db.Where("age = ?", 20) +``` - db.Where("name = ?", "jinzhu").Find(&users) +When we start to perform any operations, GROM will create a new `*gorm.Scope` instance based on current `*gorm.DB` - // equivalent code - newdb := db.Where("name =?", "jinzhu") - newdb.Find(&user) +```go +// perform a querying operation +db.First(&user) +``` -`newdb` is `db`'s clone, in addition, it contains search conditions from the `Where` method. -`Find` is a query method, it creates a `Scope` instance, and pass it as argument to query callbacks. +And based on current operation's type, it will call registered `creating`, `updating`, `querying`, `deleting` or `row_querying` callbacks to run the operation. -There are four kinds of callbacks corresponds to sql's CURD: create callbacks, update callbacks, query callbacks, delete callbacks. +For above example, will call `querying` callbacks, refer [Querying Callbacks](callbacks.html#querying-an-object) -## Callbacks +## Write Plugins + +GORM itself is powered by `Callbacks`, so you could fully customize GORM as you want ### Register a new callback @@ -55,16 +61,28 @@ There are four kinds of callbacks corresponds to sql's CURD: create callbacks, u 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) -### Callback API +### Pre-Defined Callbacks -Gorm is powered by callbacks, so you could refer below links to learn how to write 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) +- [Create callbacks](https://github.com/jinzhu/gorm/blob/master/callback_create.go) -[Update callbacks](https://github.com/jinzhu/gorm/blob/master/callback_update.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) +- [Query callbacks](https://github.com/jinzhu/gorm/blob/master/callback_query.go) -[Delete callbacks](https://github.com/jinzhu/gorm/blob/master/callback_delete.go) +- [Delete callbacks](https://github.com/jinzhu/gorm/blob/master/callback_delete.go) -View [https://github.com/jinzhu/gorm/blob/master/scope.go](https://github.com/jinzhu/gorm/blob/master/scope.go) for all available API +- 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