From 1fbfb00bae75025529d90c0af51093af58fca25c Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Mon, 29 Feb 2016 21:52:18 +0800 Subject: [PATCH] Rebuild documents --- advanced.html | 160 ++--- associations.html | 180 ++--- callbacks.html | 56 +- curd.html | 694 +++++++++---------- database.html | 124 ++-- development.html | 6 +- documents/book.json | 5 +- gitbook/gitbook-plugin-highlight/ebook.css | 131 ++++ gitbook/gitbook-plugin-highlight/website.css | 426 ++++++++++++ gitbook/gitbook-plugin-livereload/plugin.js | 11 + index.html | 42 +- models.html | 116 ++-- 12 files changed, 1259 insertions(+), 692 deletions(-) create mode 100644 gitbook/gitbook-plugin-highlight/ebook.css create mode 100644 gitbook/gitbook-plugin-highlight/website.css create mode 100644 gitbook/gitbook-plugin-livereload/plugin.js diff --git a/advanced.html b/advanced.html index 5301ef58..00bfddaa 100644 --- a/advanced.html +++ b/advanced.html @@ -17,7 +17,7 @@ The database handle returned from db.Begin() should be used for all oper"> - + @@ -71,7 +71,7 @@ The database handle returned from db.Begin() should be used for all oper"> data-chapter-title="Advanced Usage" data-filepath="advanced.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -602,119 +602,119 @@ The database handle returned from db.Begin() should be used for all oper">

Error Handling

-
query := db.Where("name = ?", "jinzhu").First(&user)
-query := db.First(&user).Limit(10).Find(&users)
-// query.Error will return the last happened error
+
query := db.Where("name = ?", "jinzhu").First(&user)
+query := db.First(&user).Limit(10).Find(&users)
+// query.Error will return the last happened error
 
-// So you could do error handing in your application like this:
-if err := db.Where("name = ?", "jinzhu").First(&user).Error; err != nil {
-    // error handling...
-}
+// So you could do error handing in your application like this:
+if err := db.Where("name = ?", "jinzhu").First(&user).Error; err != nil {
+    // error handling...
+}
 
-// RecordNotFound
-// If no record found when you query data, gorm will return RecordNotFound error, you could check it like this:
-db.Where("name = ?", "hello world").First(&User{}).Error == gorm.RecordNotFound
-// Or use the shortcut method
-db.Where("name = ?", "hello world").First(&user).RecordNotFound()
+// RecordNotFound
+// If no record found when you query data, gorm will return RecordNotFound error, you could check it like this:
+db.Where("name = ?", "hello world").First(&User{}).Error == gorm.RecordNotFound
+// Or use the shortcut method
+db.Where("name = ?", "hello world").First(&user).RecordNotFound()
 
-if db.Model(&user).Related(&credit_card).RecordNotFound() {
-    // no credit card found error handling
-}
+if db.Model(&user).Related(&credit_card).RecordNotFound() {
+    // no credit card found error handling
+}
 

Transactions

To perform a set of operations within a transaction, the general flow is as below. The database handle returned from db.Begin() should be used for all operations within the transaction. (Note that all individual save and delete operations are run in a transaction by default.)

-
// begin
-tx := db.Begin()
+
// begin
+tx := db.Begin()
 
-// do some database operations (use 'tx' from this point, not 'db')
-tx.Create(...)
-...
+// do some database operations (use 'tx' from this point, not 'db')
+tx.Create(...)
+...
 
-// rollback in case of error
-tx.Rollback()
+// rollback in case of error
+tx.Rollback()
 
-// Or commit if all is ok
-tx.Commit()
+// Or commit if all is ok
+tx.Commit()
 

A Specific Example

-
func CreateAnimals(db *gorm.DB) err {
-  tx := db.Begin()
-  // Note the use of tx as the database handle once you are within a transaction
+
func CreateAnimals(db *gorm.DB) err {
+  tx := db.Begin()
+  // Note the use of tx as the database handle once you are within a transaction
 
-  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
-     tx.Rollback()
-     return err
-  }
+  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
+     tx.Rollback()
+     return err
+  }
 
-  if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
-     tx.Rollback()
-     return err
-  }
+  if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
+     tx.Rollback()
+     return err
+  }
 
-  tx.Commit()
-  return nil
-}
+  tx.Commit()
+  return nil
+}
 

Raw SQL

-
db.Exec("DROP TABLE users;")
-db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})
+
db.Exec("DROP TABLE users;")
+db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})
 

Row & Rows

It is even possible to get query result as *sql.Row or *sql.Rows

-
row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row)
-row.Scan(&name, &age)
+
row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row)
+row.Scan(&name, &age)
 
-rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
-defer rows.Close()
-for rows.Next() {
-    ...
-    rows.Scan(&name, &age, &email)
-    ...
-}
+rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
+defer rows.Close()
+for rows.Next() {
+    ...
+    rows.Scan(&name, &age, &email)
+    ...
+}
 
-// Raw SQL
-rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows() // (*sql.Rows, error)
-defer rows.Close()
-for rows.Next() {
-    ...
-    rows.Scan(&name, &age, &email)
-    ...
-}
+// Raw SQL
+rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows() // (*sql.Rows, error)
+defer rows.Close()
+for rows.Next() {
+    ...
+    rows.Scan(&name, &age, &email)
+    ...
+}
 

Scan Rows

-
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
-defer rows.Close()
+
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
+defer rows.Close()
 
-for rows.Next() {
-  var user User
-  db.ScanRows(rows, &user)
-  // do something
-}
+for rows.Next() {
+  var user User
+  db.ScanRows(rows, &user)
+  // do something
+}
 

Composite Primary Key

-
type Product struct {
-    ID           string `gorm:"primary_key"`
-    LanguageCode string `gorm:"primary_key"`
-}
+
type Product struct {
+    ID           string `gorm:"primary_key"`
+    LanguageCode string `gorm:"primary_key"`
+}
 

Logger

Gorm has built-in logger support

-
// Enable Logger
-db.LogMode(true)
+
// Enable Logger
+db.LogMode(true)
 
-// Diable Logger
-db.LogMode(false)
+// Diable Logger
+db.LogMode(false)
 
-// Debug a single operation
-db.Debug().Where("name = ?", "jinzhu").First(&User{})
+// Debug a single operation
+db.Debug().Where("name = ?", "jinzhu").First(&User{})
 

logger

Customize Logger

-
// 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))
+
// 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))
 
@@ -773,7 +773,7 @@ db.SetLogger require(["gitbook"], function(gitbook) { - gitbook.start({"fontsettings":{"theme":"night","family":"sans","size":4},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"prism":{},"anker-enable":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); + gitbook.start({"fontsettings":{"theme":"night","size":2,"family":"sans"},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"anker-enable":{},"highlight":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); }); diff --git a/associations.html b/associations.html index 631f8948..6f1c8634 100644 --- a/associations.html +++ b/associations.html @@ -16,7 +16,7 @@ - + @@ -70,7 +70,7 @@ data-chapter-title="Associations" data-filepath="associations.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -592,130 +592,130 @@

Belongs To

-
// User belongs to a profile, ProfileID is the foreign key
-type User struct {
-  gorm.Model
+
// User belongs to a profile, ProfileID is the foreign key
+type User struct {
+  gorm.Model
   Profile   Profile
-  ProfileID int
-}
+  ProfileID int
+}
 
-type Profile struct {
-  gorm.Model
-  Name   string
-}
+type Profile struct {
+  gorm.Model
+  Name   string
+}
 
-db.Model(&user).Related(&profile)
-//// SELECT * FROM profiles WHERE id = 111; // 111 is user's foreign key ProfileID
+db.Model(&user).Related(&profile)
+//// SELECT * FROM profiles WHERE id = 111; // 111 is user's foreign key ProfileID
 

Has One

-
// User has one CreditCard, UserID is the foreign key
-type User struct {
-    gorm.Model
+
// User has one CreditCard, UserID is the foreign key
+type User struct {
+    gorm.Model
     CreditCard   CreditCard
-}
+}
 
-type CreditCard struct {
-    gorm.Model
-    UserID   uint
-    Number   string
-}
+type CreditCard struct {
+    gorm.Model
+    UserID   uint
+    Number   string
+}
 
-var card CreditCard
-db.Model(&user).Related(&card, "CreditCard")
-//// SELECT * FROM credit_cards WHERE user_id = 123; // 123 is user's primary key
-// CreditCard is user's field name, it means get user's CreditCard relations and fill it into variable card
-// If the field name is same as the variable's type name, like above example, it could be omitted, like:
-db.Model(&user).Related(&card)
+var card CreditCard
+db.Model(&user).Related(&card, "CreditCard")
+//// SELECT * FROM credit_cards WHERE user_id = 123; // 123 is user's primary key
+// CreditCard is user's field name, it means get user's CreditCard relations and fill it into variable card
+// If the field name is same as the variable's type name, like above example, it could be omitted, like:
+db.Model(&user).Related(&card)
 

Has Many

-
// User has many emails, UserID is the foreign key
-type User struct {
-    gorm.Model
-    Emails   []Email
-}
+
// User has many emails, UserID is the foreign key
+type User struct {
+    gorm.Model
+    Emails   []Email
+}
 
-type Email struct {
-    gorm.Model
-    Email   string
-    UserID  uint
-}
+type Email struct {
+    gorm.Model
+    Email   string
+    UserID  uint
+}
 
-db.Model(&user).Related(&emails)
-//// SELECT * FROM emails WHERE user_id = 111; // 111 is user's primary key
+db.Model(&user).Related(&emails)
+//// SELECT * FROM emails WHERE user_id = 111; // 111 is user's primary key
 

Many To Many

-
// User has and belongs to many languages, use `user_languages` as join table
-type User struct {
-    gorm.Model
-    Languages         []Language `gorm:"many2many:user_languages;"`
-}
+
// User has and belongs to many languages, use `user_languages` as join table
+type User struct {
+    gorm.Model
+    Languages         []Language `gorm:"many2many:user_languages;"`
+}
 
-type Language struct {
-    gorm.Model
-    Name string
-}
+type Language struct {
+    gorm.Model
+    Name string
+}
 
-db.Model(&user).Related(&languages)
-//// SELECT * FROM "languages" INNER JOIN "user_languages" ON "user_languages"."language_id" = "languages"."id" WHERE "user_languages"."user_id" = 111
+db.Model(&user).Related(&languages)
+//// SELECT * FROM "languages" INNER JOIN "user_languages" ON "user_languages"."language_id" = "languages"."id" WHERE "user_languages"."user_id" = 111
 

Polymorphism

Supports polymorphic has-many and has-one associations.

-
  type Cat struct {
-    Id    int
-    Name  string
-    Toy   Toy `gorm:"polymorphic:Owner;"`
-  }
+
  type Cat struct {
+    Id    int
+    Name  string
+    Toy   Toy `gorm:"polymorphic:Owner;"`
+  }
 
-  type Dog struct {
-    Id   int
-    Name string
-    Toy  Toy `gorm:"polymorphic:Owner;"`
-  }
+  type Dog struct {
+    Id   int
+    Name string
+    Toy  Toy `gorm:"polymorphic:Owner;"`
+  }
 
-  type Toy struct {
-    Id        int
-    Name      string
-    OwnerId   int
-    OwnerType string
-  }
+  type Toy struct {
+    Id        int
+    Name      string
+    OwnerId   int
+    OwnerType string
+  }
 

Note: polymorphic belongs-to and many-to-many are explicitly NOT supported, and will throw errors.

Association Mode

Association Mode contains some helper methods to handle relationship things easily.

-
// Start Association Mode
-var user User
-db.Model(&user).Association("Languages")
-// `user` is the source, it need to be a valid record (contains primary key)
-// `Languages` is source's field name for a relationship.
-// If those conditions not matched, will return an error, check it with:
-// db.Model(&user).Association("Languages").Error
+
// Start Association Mode
+var user User
+db.Model(&user).Association("Languages")
+// `user` is the source, it need to be a valid record (contains primary key)
+// `Languages` is source's field name for a relationship.
+// If those conditions not matched, will return an error, check it with:
+// db.Model(&user).Association("Languages").Error
 
 
-// Query - Find out all related associations
-db.Model(&user).Association("Languages").Find(&languages)
+// Query - Find out all related associations
+db.Model(&user).Association("Languages").Find(&languages)
 
 
-// Append - Append new associations for many2many, has_many, will replace current association for has_one, belongs_to
-db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN})
-db.Model(&user).Association("Languages").Append(Language{Name: "DE"})
+// Append - Append new associations for many2many, has_many, will replace current association for has_one, belongs_to
+db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN})
+db.Model(&user).Association("Languages").Append(Language{Name: "DE"})
 
 
-// Delete - Remove relationship between source & passed arguments, won't delete those arguments
-db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN})
-db.Model(&user).Association("Languages").Delete(languageZH, languageEN)
+// Delete - Remove relationship between source & passed arguments, won't delete those arguments
+db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN})
+db.Model(&user).Association("Languages").Delete(languageZH, languageEN)
 
 
-// Replace - Replace current associations with new one
-db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN})
-db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)
+// Replace - Replace current associations with new one
+db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN})
+db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)
 
 
-// Count - Return the count of current associations
-db.Model(&user).Association("Languages").Count()
+// Count - Return the count of current associations
+db.Model(&user).Association("Languages").Count()
 
 
-// Clear - Remove relationship between source & current associations, won't delete those associations
-db.Model(&user).Association("Languages").Clear()
+// Clear - Remove relationship between source & current associations, won't delete those associations
+db.Model(&user).Association("Languages").Clear()
 
@@ -774,7 +774,7 @@ db.Model require(["gitbook"], function(gitbook) { - gitbook.start({"fontsettings":{"theme":"night","family":"sans","size":4},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"prism":{},"anker-enable":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); + gitbook.start({"fontsettings":{"theme":"night","size":2,"family":"sans"},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"anker-enable":{},"highlight":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); }); diff --git a/callbacks.html b/callbacks.html index d706a9a5..a0be69dc 100644 --- a/callbacks.html +++ b/callbacks.html @@ -17,7 +17,7 @@ If any callback returns an error, gorm will stop future operations and rollback - + @@ -71,7 +71,7 @@ If any callback returns an error, gorm will stop future operations and rollback data-chapter-title="Callbacks" data-filepath="callbacks.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -598,54 +598,54 @@ If any callback returns an error, gorm will stop future operations and rollback

Creating An Object

BeforeSave
 BeforeCreate
-// save before associations
-// save self
-// save after associations
+// save before associations
+// save self
+// save after associations
 AfterCreate
 AfterSave
 

Updating An Object

BeforeSave
 BeforeUpdate
-// save before associations
-// save self
-// save after associations
+// save before associations
+// save self
+// save after associations
 AfterUpdate
 AfterSave
 

Destroying An Object

BeforeDelete
-// delete self
+// delete self
 AfterDelete
 

After Find

-
// load data from database
+
// load data from database
 AfterFind
 

Example

-
func (u *User) BeforeUpdate() (err error) {
-    if u.readonly() {
-        err = errors.New("read only user")
-    }
-    return
-}
+
func (u *User) BeforeUpdate() (err error) {
+    if u.readonly() {
+        err = errors.New("read only user")
+    }
+    return
+}
 
-// Rollback the insertion if user's id greater than 1000
-func (u *User) AfterCreate() (err error) {
-    if (u.Id > 1000) {
-        err = errors.New("user id is already greater than 1000")
-    }
-    return
-}
+// Rollback the insertion if user's id greater than 1000
+func (u *User) AfterCreate() (err error) {
+    if (u.Id > 1000) {
+        err = errors.New("user id is already greater than 1000")
+    }
+    return
+}
 

Save/delete operations in gorm are running in a transaction. Changes made in that transaction are not visible unless it is commited. So if you want to use those changes in your callbacks, you need to run your SQL in the same transaction. For this Gorm supports passing transactions to callbacks like this:

-
func (u *User) AfterCreate(tx *gorm.DB) (err error) {
-    tx.Model(u).Update("role", "admin")
-    return
-}
+
func (u *User) AfterCreate(tx *gorm.DB) (err error) {
+    tx.Model(u).Update("role", "admin")
+    return
+}
 
@@ -704,7 +704,7 @@ For this Gorm supports passing transactions to callbacks like this:

diff --git a/curd.html b/curd.html index 96b4a468..61e2a588 100644 --- a/curd.html +++ b/curd.html @@ -16,7 +16,7 @@ - + @@ -70,7 +70,7 @@ data-chapter-title="CRUD: Reading and Writing Data" data-filepath="curd.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -642,531 +642,531 @@

Create

Create Record

-
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
+
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
 
-db.NewRecord(user) // => returns `true` as primary key is blank
+db.NewRecord(user) // => returns `true` as primary key is blank
 
-db.Create(&user)
+db.Create(&user)
 
-db.NewRecord(user) // => return `false` after `user` created
+db.NewRecord(user) // => return `false` after `user` created
 
-// Associations will be inserted automatically when save the record
-user := User{
-    Name:            "jinzhu",
-    BillingAddress:  Address{Address1: "Billing Address - Address 1"},
-    ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
-    Emails:          []Email{{Email: "jinzhu@example.com"}, {Email: "jinzhu-2@example@example.com"}},
-    Languages:       []Language{{Name: "ZH"}, {Name: "EN"}},
-}
+// Associations will be inserted automatically when save the record
+user := User{
+    Name:            "jinzhu",
+    BillingAddress:  Address{Address1: "Billing Address - Address 1"},
+    ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
+    Emails:          []Email{{Email: "jinzhu@example.com"}, {Email: "jinzhu-2@example@example.com"}},
+    Languages:       []Language{{Name: "ZH"}, {Name: "EN"}},
+}
 
-db.Create(&user)
-//// BEGIN TRANSACTION;
-//// INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1");
-//// INSERT INTO "addresses" (address1) VALUES ("Shipping Address - Address 1");
-//// INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2);
-//// INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu@example.com");
-//// INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu-2@example.com");
-//// INSERT INTO "languages" ("name") VALUES ('ZH');
-//// INSERT INTO user_languages ("user_id","language_id") VALUES (111, 1);
-//// INSERT INTO "languages" ("name") VALUES ('EN');
-//// INSERT INTO user_languages ("user_id","language_id") VALUES (111, 2);
-//// COMMIT;
+db.Create(&user)
+//// BEGIN TRANSACTION;
+//// INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1");
+//// INSERT INTO "addresses" (address1) VALUES ("Shipping Address - Address 1");
+//// INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2);
+//// INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu@example.com");
+//// INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu-2@example.com");
+//// INSERT INTO "languages" ("name") VALUES ('ZH');
+//// INSERT INTO user_languages ("user_id","language_id") VALUES (111, 1);
+//// INSERT INTO "languages" ("name") VALUES ('EN');
+//// INSERT INTO user_languages ("user_id","language_id") VALUES (111, 2);
+//// COMMIT;
 

Create With Associations

Refer Associations for more details

Default Values

You could defined default value in the sql tag, then the generated creating SQL will ignore these fields that including default value and its value is blank, and after inserted the record into databae, gorm will load those fields's value from database.

-
type Animal struct {
-    ID   int64
-    Name string `sql:"default:'galeone'"`
-    Age  int64
-}
+
type Animal struct {
+    ID   int64
+    Name string `sql:"default:'galeone'"`
+    Age  int64
+}
 
-var animal = Animal{Age: 99, Name: ""}
-db.Create(&animal)
-// INSERT INTO animals("age") values('99');
-// SELECT name from animals WHERE ID=111; // the returning primary key is 111
-// animal.Name => 'galeone'
+var animal = Animal{Age: 99, Name: ""}
+db.Create(&animal)
+// INSERT INTO animals("age") values('99');
+// SELECT name from animals WHERE ID=111; // the returning primary key is 111
+// animal.Name => 'galeone'
 

Setting Primary Key In Callbacks

If you want to set primary key in BeforeCreate callback, you could use scope.SetColumn, for example:

-
func (user *User) BeforeCreate(scope *gorm.Scope) error {
-  scope.SetColumn("ID", uuid.New())
-  return nil
-}
+
func (user *User) BeforeCreate(scope *gorm.Scope) error {
+  scope.SetColumn("ID", uuid.New())
+  return nil
+}
 

Extra Creating option

-
// Add extra SQL option for inserting SQL
-db.Set("gorm:insert_option", "ON CONFLICT").Create(&product)
-// INSERT INTO products (name, code) VALUES ("name", "code") ON CONFLICT;
+
// Add extra SQL option for inserting SQL
+db.Set("gorm:insert_option", "ON CONFLICT").Create(&product)
+// INSERT INTO products (name, code) VALUES ("name", "code") ON CONFLICT;
 

Query

-
// Get the first record
-db.First(&user)
-//// SELECT * FROM users ORDER BY id LIMIT 1;
+
// Get the first record
+db.First(&user)
+//// SELECT * FROM users ORDER BY id LIMIT 1;
 
-// Get the last record
-db.Last(&user)
-//// SELECT * FROM users ORDER BY id DESC LIMIT 1;
+// Get the last record
+db.Last(&user)
+//// SELECT * FROM users ORDER BY id DESC LIMIT 1;
 
-// Get all records
-db.Find(&users)
-//// SELECT * FROM users;
+// Get all records
+db.Find(&users)
+//// SELECT * FROM users;
 
-// Get record with primary key
-db.First(&user, 10)
-//// SELECT * FROM users WHERE id = 10;
+// Get record with primary key
+db.First(&user, 10)
+//// SELECT * FROM users WHERE id = 10;
 

Query With Where (Plain SQL)

-
// Get the first matched record
-db.Where("name = ?", "jinzhu").First(&user)
-//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;
+
// Get the first matched record
+db.Where("name = ?", "jinzhu").First(&user)
+//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;
 
-// Get all matched records
-db.Where("name = ?", "jinzhu").Find(&users)
-//// SELECT * FROM users WHERE name = 'jinzhu';
+// Get all matched records
+db.Where("name = ?", "jinzhu").Find(&users)
+//// SELECT * FROM users WHERE name = 'jinzhu';
 
-db.Where("name <> ?", "jinzhu").Find(&users)
+db.Where("name <> ?", "jinzhu").Find(&users)
 
-// IN
-db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)
+// IN
+db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)
 
-// LIKE
-db.Where("name LIKE ?", "%jin%").Find(&users)
+// LIKE
+db.Where("name LIKE ?", "%jin%").Find(&users)
 
-// AND
-db.Where("name = ? and age >= ?", "jinzhu", "22").Find(&users)
+// AND
+db.Where("name = ? and age >= ?", "jinzhu", "22").Find(&users)
 
-// Time
-db.Where("updated_at > ?", lastWeek).Find(&users)
+// Time
+db.Where("updated_at > ?", lastWeek).Find(&users)
 
-db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
+db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
 

Query With Where (Struct & Map)

-
// Struct
-db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
-//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;
+
// Struct
+db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
+//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;
 
-// Map
-db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
-//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
+// Map
+db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
+//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
 
-// Slice of primary keys
-db.Where([]int64{20, 21, 22}).Find(&users)
-//// SELECT * FROM users WHERE id IN (20, 21, 22);
+// Slice of primary keys
+db.Where([]int64{20, 21, 22}).Find(&users)
+//// SELECT * FROM users WHERE id IN (20, 21, 22);
 

Query With Not

-
db.Not("name", "jinzhu").First(&user)
-//// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;
+
db.Not("name", "jinzhu").First(&user)
+//// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;
 
-// Not In
-db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)
-//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");
+// Not In
+db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)
+//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");
 
-// Not In slice of primary keys
-db.Not([]int64{1,2,3}).First(&user)
-//// SELECT * FROM users WHERE id NOT IN (1,2,3);
+// Not In slice of primary keys
+db.Not([]int64{1,2,3}).First(&user)
+//// SELECT * FROM users WHERE id NOT IN (1,2,3);
 
-db.Not([]int64{}).First(&user)
-//// SELECT * FROM users;
+db.Not([]int64{}).First(&user)
+//// SELECT * FROM users;
 
-// Plain SQL
-db.Not("name = ?", "jinzhu").First(&user)
-//// SELECT * FROM users WHERE NOT(name = "jinzhu");
+// Plain SQL
+db.Not("name = ?", "jinzhu").First(&user)
+//// SELECT * FROM users WHERE NOT(name = "jinzhu");
 
-// Struct
-db.Not(User{Name: "jinzhu"}).First(&user)
-//// SELECT * FROM users WHERE name <> "jinzhu";
+// Struct
+db.Not(User{Name: "jinzhu"}).First(&user)
+//// SELECT * FROM users WHERE name <> "jinzhu";
 

Query With Inline Condition

-
// Get by primary key
-db.First(&user, 23)
-//// SELECT * FROM users WHERE id = 23 LIMIT 1;
+
// Get by primary key
+db.First(&user, 23)
+//// SELECT * FROM users WHERE id = 23 LIMIT 1;
 
-// Plain SQL
-db.Find(&user, "name = ?", "jinzhu")
-//// SELECT * FROM users WHERE name = "jinzhu";
+// Plain SQL
+db.Find(&user, "name = ?", "jinzhu")
+//// SELECT * FROM users WHERE name = "jinzhu";
 
-db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20)
-//// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;
+db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20)
+//// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;
 
-// Struct
-db.Find(&users, User{Age: 20})
-//// SELECT * FROM users WHERE age = 20;
+// Struct
+db.Find(&users, User{Age: 20})
+//// SELECT * FROM users WHERE age = 20;
 
-// Map
-db.Find(&users, map[string]interface{}{"age": 20})
-//// SELECT * FROM users WHERE age = 20;
+// Map
+db.Find(&users, map[string]interface{}{"age": 20})
+//// SELECT * FROM users WHERE age = 20;
 

Query With Or

-
db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)
-//// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';
+
db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)
+//// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';
 
-// Struct
-db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users)
-//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';
+// Struct
+db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users)
+//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';
 
-// Map
-db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2"}).Find(&users)
+// Map
+db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2"}).Find(&users)
 

Query Chains

Gorm has a chainable API, you could use it like this

-
db.Where("name <> ?","jinzhu").Where("age >= ? and role <> ?",20,"admin").Find(&users)
-//// SELECT * FROM users WHERE name <> 'jinzhu' AND age >= 20 AND role <> 'admin';
+
db.Where("name <> ?","jinzhu").Where("age >= ? and role <> ?",20,"admin").Find(&users)
+//// SELECT * FROM users WHERE name <> 'jinzhu' AND age >= 20 AND role <> 'admin';
 
-db.Where("role = ?", "admin").Or("role = ?", "super_admin").Not("name = ?", "jinzhu").Find(&users)
+db.Where("role = ?", "admin").Or("role = ?", "super_admin").Not("name = ?", "jinzhu").Find(&users)
 

Extra Querying option

-
// Add extra SQL option for selecting SQL
-db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
-//// SELECT * FROM users WHERE id = 10 FOR UPDATE;
+
// Add extra SQL option for selecting SQL
+db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
+//// SELECT * FROM users WHERE id = 10 FOR UPDATE;
 

FirstOrInit

Get the first matched record, or initialize a record with search conditions.

-
// Unfound
-db.FirstOrInit(&user, User{Name: "non_existing"})
-//// user -> User{Name: "non_existing"}
+
// Unfound
+db.FirstOrInit(&user, User{Name: "non_existing"})
+//// user -> User{Name: "non_existing"}
 
-// Found
-db.Where(User{Name: "Jinzhu"}).FirstOrInit(&user)
-//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
-db.FirstOrInit(&user, map[string]interface{}{"name": "jinzhu"})
-//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
+// Found
+db.Where(User{Name: "Jinzhu"}).FirstOrInit(&user)
+//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
+db.FirstOrInit(&user, map[string]interface{}{"name": "jinzhu"})
+//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
 

Attrs

Ignore some values when searching, but use them to initialize the struct if record is not found.

-
// Unfound
-db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrInit(&user)
-//// SELECT * FROM USERS WHERE name = 'non_existing';
-//// user -> User{Name: "non_existing", Age: 20}
+
// Unfound
+db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrInit(&user)
+//// SELECT * FROM USERS WHERE name = 'non_existing';
+//// user -> User{Name: "non_existing", Age: 20}
 
-db.Where(User{Name: "noexisting_user"}).Attrs("age", 20).FirstOrInit(&user)
-//// SELECT * FROM USERS WHERE name = 'non_existing';
-//// user -> User{Name: "non_existing", Age: 20}
+db.Where(User{Name: "noexisting_user"}).Attrs("age", 20).FirstOrInit(&user)
+//// SELECT * FROM USERS WHERE name = 'non_existing';
+//// user -> User{Name: "non_existing", Age: 20}
 
-// Found
-db.Where(User{Name: "Jinzhu"}).Attrs(User{Age: 30}).FirstOrInit(&user)
-//// SELECT * FROM USERS WHERE name = jinzhu';
-//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
+// Found
+db.Where(User{Name: "Jinzhu"}).Attrs(User{Age: 30}).FirstOrInit(&user)
+//// SELECT * FROM USERS WHERE name = jinzhu';
+//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
 

Assign

Ignore some values when searching, but assign it to the result regardless it is found or not.

-
// Unfound
-db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrInit(&user)
-//// user -> User{Name: "non_existing", Age: 20}
+
// Unfound
+db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrInit(&user)
+//// user -> User{Name: "non_existing", Age: 20}
 
-// Found
-db.Where(User{Name: "Jinzhu"}).Assign(User{Age: 30}).FirstOrInit(&user)
-//// SELECT * FROM USERS WHERE name = jinzhu';
-//// user -> User{Id: 111, Name: "Jinzhu", Age: 30}
+// Found
+db.Where(User{Name: "Jinzhu"}).Assign(User{Age: 30}).FirstOrInit(&user)
+//// SELECT * FROM USERS WHERE name = jinzhu';
+//// user -> User{Id: 111, Name: "Jinzhu", Age: 30}
 

FirstOrCreate

Get the first matched record, or create with search conditions.

-
// Unfound
-db.FirstOrCreate(&user, User{Name: "non_existing"})
-//// INSERT INTO "users" (name) VALUES ("non_existing");
-//// user -> User{Id: 112, Name: "non_existing"}
+
// Unfound
+db.FirstOrCreate(&user, User{Name: "non_existing"})
+//// INSERT INTO "users" (name) VALUES ("non_existing");
+//// user -> User{Id: 112, Name: "non_existing"}
 
-// Found
-db.Where(User{Name: "Jinzhu"}).FirstOrCreate(&user)
-//// user -> User{Id: 111, Name: "Jinzhu"}
+// Found
+db.Where(User{Name: "Jinzhu"}).FirstOrCreate(&user)
+//// user -> User{Id: 111, Name: "Jinzhu"}
 

Attrs

Ignore some values when searching, but use them to create the struct if record is not found. like FirstOrInit

-
// Unfound
-db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrCreate(&user)
-//// SELECT * FROM users WHERE name = 'non_existing';
-//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);
-//// user -> User{Id: 112, Name: "non_existing", Age: 20}
+
// Unfound
+db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrCreate(&user)
+//// SELECT * FROM users WHERE name = 'non_existing';
+//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);
+//// user -> User{Id: 112, Name: "non_existing", Age: 20}
 
-// Found
-db.Where(User{Name: "jinzhu"}).Attrs(User{Age: 30}).FirstOrCreate(&user)
-//// SELECT * FROM users WHERE name = 'jinzhu';
-//// user -> User{Id: 111, Name: "jinzhu", Age: 20}
+// Found
+db.Where(User{Name: "jinzhu"}).Attrs(User{Age: 30}).FirstOrCreate(&user)
+//// SELECT * FROM users WHERE name = 'jinzhu';
+//// user -> User{Id: 111, Name: "jinzhu", Age: 20}
 

Assign

Ignore some values when searching, but assign it to the record regardless it is found or not, then save back to database. like FirstOrInit

-
// Unfound
-db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrCreate(&user)
-//// SELECT * FROM users WHERE name = 'non_existing';
-//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);
-//// user -> User{Id: 112, Name: "non_existing", Age: 20}
+
// Unfound
+db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrCreate(&user)
+//// SELECT * FROM users WHERE name = 'non_existing';
+//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);
+//// user -> User{Id: 112, Name: "non_existing", Age: 20}
 
-// Found
-db.Where(User{Name: "jinzhu"}).Assign(User{Age: 30}).FirstOrCreate(&user)
-//// SELECT * FROM users WHERE name = 'jinzhu';
-//// UPDATE users SET age=30 WHERE id = 111;
-//// user -> User{Id: 111, Name: "jinzhu", Age: 30}
+// Found
+db.Where(User{Name: "jinzhu"}).Assign(User{Age: 30}).FirstOrCreate(&user)
+//// SELECT * FROM users WHERE name = 'jinzhu';
+//// UPDATE users SET age=30 WHERE id = 111;
+//// user -> User{Id: 111, Name: "jinzhu", Age: 30}
 

Select

-
db.Select("name, age").Find(&users)
-//// SELECT name, age FROM users;
+
db.Select("name, age").Find(&users)
+//// SELECT name, age FROM users;
 
-db.Select([]string{"name", "age"}).Find(&users)
-//// SELECT name, age FROM users;
+db.Select([]string{"name", "age"}).Find(&users)
+//// SELECT name, age FROM users;
 
-db.Table("users").Select("COALESCE(age,?)", 42).Rows()
-//// SELECT COALESCE(age,'42') FROM users;
+db.Table("users").Select("COALESCE(age,?)", 42).Rows()
+//// SELECT COALESCE(age,'42') FROM users;
 

Order

-
db.Order("age desc, name").Find(&users)
-//// SELECT * FROM users ORDER BY age desc, name;
+
db.Order("age desc, name").Find(&users)
+//// SELECT * FROM users ORDER BY age desc, name;
 
-// Multiple orders
-db.Order("age desc").Order("name").Find(&users)
-//// SELECT * FROM users ORDER BY age desc, name;
+// Multiple orders
+db.Order("age desc").Order("name").Find(&users)
+//// SELECT * FROM users ORDER BY age desc, name;
 
-// ReOrder
-db.Order("age desc").Find(&users1).Order("age", true).Find(&users2)
-//// SELECT * FROM users ORDER BY age desc; (users1)
-//// SELECT * FROM users ORDER BY age; (users2)
+// ReOrder
+db.Order("age desc").Find(&users1).Order("age", true).Find(&users2)
+//// SELECT * FROM users ORDER BY age desc; (users1)
+//// SELECT * FROM users ORDER BY age; (users2)
 

Limit

-
db.Limit(3).Find(&users)
-//// SELECT * FROM users LIMIT 3;
+
db.Limit(3).Find(&users)
+//// SELECT * FROM users LIMIT 3;
 
-// Cancel limit condition with -1
-db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
-//// SELECT * FROM users LIMIT 10; (users1)
-//// SELECT * FROM users; (users2)
+// Cancel limit condition with -1
+db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
+//// SELECT * FROM users LIMIT 10; (users1)
+//// SELECT * FROM users; (users2)
 

Offset

-
db.Offset(3).Find(&users)
-//// SELECT * FROM users OFFSET 3;
+
db.Offset(3).Find(&users)
+//// SELECT * FROM users OFFSET 3;
 
-// Cancel offset condition with -1
-db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
-//// SELECT * FROM users OFFSET 10; (users1)
-//// SELECT * FROM users; (users2)
+// Cancel offset condition with -1
+db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
+//// SELECT * FROM users OFFSET 10; (users1)
+//// SELECT * FROM users; (users2)
 

Count

-
db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count)
-//// SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)
-//// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count)
+
db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count)
+//// SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)
+//// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count)
 
-db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count)
-//// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)
+db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count)
+//// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)
 
-db.Table("deleted_users").Count(&count)
-//// SELECT count(*) FROM deleted_users;
+db.Table("deleted_users").Count(&count)
+//// SELECT count(*) FROM deleted_users;
 

Group & Having

-
rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Rows()
-for rows.Next() {
-    ...
-}
+
rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Rows()
+for rows.Next() {
+    ...
+}
 
-rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Rows()
-for rows.Next() {
-    ...
-}
+rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Rows()
+for rows.Next() {
+    ...
+}
 
-type Result struct {
-    Date  time.Time
-    Total int64
-}
-db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Scan(&results)
+type Result struct {
+    Date  time.Time
+    Total int64
+}
+db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Scan(&results)
 

Joins

-
rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
-for rows.Next() {
-    ...
-}
+
rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
+for rows.Next() {
+    ...
+}
 
-db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)
+db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)
 
-// multiple joins with parameter
-db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user)
+// multiple joins with parameter
+db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user)
 

Pluck

Get selected attributes as map

-
var ages []int64
-db.Find(&users).Pluck("age", &ages)
+
var ages []int64
+db.Find(&users).Pluck("age", &ages)
 
-var names []string
-db.Model(&User{}).Pluck("name", &names)
+var names []string
+db.Model(&User{}).Pluck("name", &names)
 
-db.Table("deleted_users").Pluck("name", &names)
+db.Table("deleted_users").Pluck("name", &names)
 
-// Requesting more than one column? Do it like this:
-db.Select("name, age").Find(&users)
+// Requesting more than one column? Do it like this:
+db.Select("name, age").Find(&users)
 

Scan

Scan results into another struct.

-
type Result struct {
-    Name string
-    Age  int
-}
+
type Result struct {
+    Name string
+    Age  int
+}
 
-var result Result
-db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&result)
+var result Result
+db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&result)
 
-// Raw SQL
-db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)
+// Raw SQL
+db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)
 

Scopes

-
func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
-    return db.Where("amount > ?", 1000)
-}
+
func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
+    return db.Where("amount > ?", 1000)
+}
 
-func PaidWithCreditCard(db *gorm.DB) *gorm.DB {
-    return db.Where("pay_mode_sign = ?", "C")
-}
+func PaidWithCreditCard(db *gorm.DB) *gorm.DB {
+    return db.Where("pay_mode_sign = ?", "C")
+}
 
-func PaidWithCod(db *gorm.DB) *gorm.DB {
-    return db.Where("pay_mode_sign = ?", "C")
-}
+func PaidWithCod(db *gorm.DB) *gorm.DB {
+    return db.Where("pay_mode_sign = ?", "C")
+}
 
-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)
-    }
-}
+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, PaidWithCreditCard).Find(&orders)
-// Find all credit card orders and amount greater than 1000
+db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders)
+// Find all credit card orders and amount greater than 1000
 
-db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders)
-// Find all COD orders and amount greater than 1000
+db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders)
+// Find all COD orders and amount greater than 1000
 
-db.Scopes(OrderStatus([]string{"paid", "shipped"})).Find(&orders)
-// Find all paid, shipped orders
+db.Scopes(OrderStatus([]string{"paid", "shipped"})).Find(&orders)
+// Find all paid, shipped orders
 

Specifying The Table Name

-
// Create `deleted_users` table with struct User's definition
-db.Table("deleted_users").CreateTable(&User{})
+
// Create `deleted_users` table with struct User's definition
+db.Table("deleted_users").CreateTable(&User{})
 
-var deleted_users []User
-db.Table("deleted_users").Find(&deleted_users)
-//// SELECT * FROM deleted_users;
+var deleted_users []User
+db.Table("deleted_users").Find(&deleted_users)
+//// SELECT * FROM deleted_users;
 
-db.Table("deleted_users").Where("name = ?", "jinzhu").Delete()
-//// DELETE FROM deleted_users WHERE name = 'jinzhu';
+db.Table("deleted_users").Where("name = ?", "jinzhu").Delete()
+//// DELETE FROM deleted_users WHERE name = 'jinzhu';
 

Update

Update All Fields

Save will include all fields when perform the Updating SQL, even it is not changed

-
db.First(&user)
+
db.First(&user)
 
-user.Name = "jinzhu 2"
-user.Age = 100
-db.Save(&user)
+user.Name = "jinzhu 2"
+user.Age = 100
+db.Save(&user)
 
-//// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
+//// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
 

Update Changed Fields

If you only want to update changed Fields, you could use Update, Updates

-
// Update single attribute if it is changed
-db.Model(&user).Update("name", "hello")
-//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
+
// Update single attribute if it is changed
+db.Model(&user).Update("name", "hello")
+//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
 
-// Update single attribute with combined conditions
-db.Model(&user).Where("active = ?", true).Update("name", "hello")
-//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
+// Update single attribute with combined conditions
+db.Model(&user).Where("active = ?", true).Update("name", "hello")
+//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
 
 
-// Update multiple attributes with `map`, will only update those changed fields
-db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
-//// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
+// Update multiple attributes with `map`, will only update those changed fields
+db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
+//// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
 
-// Update multiple attributes with `struct`, will only update those changed & non blank fields
-db.Model(&user).Updates(User{Name: "hello", Age: 18})
-//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
+// Update multiple attributes with `struct`, will only update those changed & non blank fields
+db.Model(&user).Updates(User{Name: "hello", Age: 18})
+//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
 
-// WARNING when update with struct, GORM will only update those fields that with non blank value
-// For below Update, nothing will be updated as "", 0, false are blank values of their types
-db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
+// WARNING when update with struct, GORM will only update those fields that with non blank value
+// For below Update, nothing will be updated as "", 0, false are blank values of their types
+db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
 

Update Selected Fields

If you only want to update or ignore some fields when updating, you could use Select, Omit

-
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
-//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
+
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
+//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
 
-db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
-//// UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
+db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
+//// UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
 

Update Changed Fields Without Callbacks

Updating operations above will invoke BeforeUpdate, AfterUpdate, Update UpdatedAt timestamp, Save Associations callbacks, if you don't call them, you could use UpdateColumn, UpdateColumns

-
// Update single attribute, similar with `Update`
-db.Model(&user).UpdateColumn("name", "hello")
-//// UPDATE users SET name='hello' WHERE id = 111;
+
// Update single attribute, similar with `Update`
+db.Model(&user).UpdateColumn("name", "hello")
+//// UPDATE users SET name='hello' WHERE id = 111;
 
-// Update multiple attributes, similar with `Updates`
-db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
-//// UPDATE users SET name='hello', age=18 WHERE id = 111;
+// Update multiple attributes, similar with `Updates`
+db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
+//// UPDATE users SET name='hello', age=18 WHERE id = 111;
 

Batch Updates

Callbacks won't run when do batch updates

-
db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})
-//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);
+
db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})
+//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);
 
-// Update with struct only works with none zero values, or use map[string]interface{}
-db.Model(User{}).Updates(User{Name: "hello", Age: 18})
-//// UPDATE users SET name='hello', age=18;
+// Update with struct only works with none zero values, or use map[string]interface{}
+db.Model(User{}).Updates(User{Name: "hello", Age: 18})
+//// UPDATE users SET name='hello', age=18;
 
-// Get updated records count with `RowsAffected`
-db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
+// Get updated records count with `RowsAffected`
+db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
 

Update with SQL Expression

-
DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
-//// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
+
DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
+//// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
 
-DB.Model(&product).Updates(map[string]interface{}{"price": gorm.Expr("price * ? + ?", 2, 100)})
-//// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
+DB.Model(&product).Updates(map[string]interface{}{"price": gorm.Expr("price * ? + ?", 2, 100)})
+//// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
 
-DB.Model(&product).UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
-//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2';
+DB.Model(&product).UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
+//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2';
 
-DB.Model(&product).Where("quantity > 1").UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
-//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2' AND quantity > 1;
+DB.Model(&product).Where("quantity > 1").UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
+//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2' AND quantity > 1;
 

Change Updating Values In Callbacks

If you want to change updating values in callbacks using BeforeUpdate, BeforeSave, you could use scope.SetColumn, for example:

-
func (user *User) BeforeSave(scope *gorm.Scope) (err error) {
-  if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil {
-    scope.SetColumn("EncryptedPassword", pw)
-  }
-}
+
func (user *User) BeforeSave(scope *gorm.Scope) (err error) {
+  if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil {
+    scope.SetColumn("EncryptedPassword", pw)
+  }
+}
 

Extra Updating option

-
// Add extra SQL option for updating SQL
-db.Model(&user).Set("gorm:update_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Update("name, "hello")
-//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111 OPTION (OPTIMIZE FOR UNKNOWN);
+
// Add extra SQL option for updating SQL
+db.Model(&user).Set("gorm:update_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Update("name, "hello")
+//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111 OPTION (OPTIMIZE FOR UNKNOWN);
 

Delete

-
// Delete an existing record
-db.Delete(&email)
-//// DELETE from emails where id=10;
+
// Delete an existing record
+db.Delete(&email)
+//// DELETE from emails where id=10;
 
-// Add extra SQL option for deleting SQL
-db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)
-//// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);
+// Add extra SQL option for deleting SQL
+db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)
+//// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);
 

Batch Delete

-
db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
-//// DELETE from emails where email LIKE "%jinhu%";
+
db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
+//// DELETE from emails where email LIKE "%jinhu%";
 

Soft Delete

If struct has DeletedAt field, it will get soft delete ability automatically! Then it won't be deleted from database permanently when call Delete.

-
db.Delete(&user)
-//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
+
db.Delete(&user)
+//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
 
-// Batch Delete
-db.Where("age = ?", 20).Delete(&User{})
-//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
+// Batch Delete
+db.Where("age = ?", 20).Delete(&User{})
+//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
 
-// Soft deleted records will be ignored when query them
-db.Where("age = 20").Find(&user)
-//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
+// Soft deleted records will be ignored when query them
+db.Where("age = 20").Find(&user)
+//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
 
-// Find soft deleted records with Unscoped
-db.Unscoped().Where("age = 20").Find(&users)
-//// SELECT * FROM users WHERE age = 20;
+// Find soft deleted records with Unscoped
+db.Unscoped().Where("age = 20").Find(&users)
+//// SELECT * FROM users WHERE age = 20;
 
-// Delete record permanently with Unscoped
-db.Unscoped().Delete(&order)
-//// DELETE FROM orders WHERE id=10;
+// Delete record permanently with Unscoped
+db.Unscoped().Delete(&order)
+//// DELETE FROM orders WHERE id=10;
 
@@ -1225,7 +1225,7 @@ db.Unscoped require(["gitbook"], function(gitbook) { - gitbook.start({"fontsettings":{"theme":"night","family":"sans","size":4},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"prism":{},"anker-enable":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); + gitbook.start({"fontsettings":{"theme":"night","size":2,"family":"sans"},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"anker-enable":{},"highlight":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); }); diff --git a/database.html b/database.html index 5836a567..50a9d40a 100644 --- a/database.html +++ b/database.html @@ -16,7 +16,7 @@ - + @@ -70,7 +70,7 @@ data-chapter-title="Database" data-filepath="database.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -607,46 +607,46 @@

Connecting to a database

MySQL

NOTE don't forgot params parseTime to handle data type time.Time, more support parameters

-
import (
-    "github.com/jinzhu/gorm"
-    _ "github.com/go-sql-driver/mysql"
-)
-func main() {
-  db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
-}
+
import (
+    "github.com/jinzhu/gorm"
+    _ "github.com/go-sql-driver/mysql"
+)
+func main() {
+  db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
+}
 

PostgreSQL

-
import (
-    "github.com/jinzhu/gorm"
-    _ "github.com/lib/pq"
-)
-func main() {
-  db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")
-}
+
import (
+    "github.com/jinzhu/gorm"
+    _ "github.com/lib/pq"
+)
+func main() {
+  db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")
+}
 

Sqlite3

-
import (
-    "github.com/jinzhu/gorm"
-    _ "github.com/mattn/go-sqlite3"
-)
-func main() {
-  db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
-}
+
import (
+    "github.com/jinzhu/gorm"
+    _ "github.com/mattn/go-sqlite3"
+)
+func main() {
+  db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
+}
 

Write Dialect for unsupported databases

GORM officially support above databases, for unsupported databaes, you could write a dialect for that.

Refer: https://github.com/jinzhu/gorm/blob/master/dialect.go

Generic database object *sql.DB

*sql.DB

-
// Get generic database object *sql.DB to use its functions
-db.DB()
+
// Get generic database object *sql.DB to use its functions
+db.DB()
 
-// Connection Pool
-db.DB().SetMaxIdleConns(10)
-db.DB().SetMaxOpenConns(100)
+// Connection Pool
+db.DB().SetMaxIdleConns(10)
+db.DB().SetMaxOpenConns(100)
 
-  // Ping
-db.DB().Ping()
+  // Ping
+db.DB().Ping()
 

Migration

@@ -654,60 +654,60 @@ db.DBAutomatically migrate your schema, to keep your schema update to date

WARNING AutoMigrate will ONLY create tables, columns and indexes if doesn't exist, WON'T change existing column's type or delete unused columns to protect your data

-
db.AutoMigrate(&User{})
+
db.AutoMigrate(&User{})
 
-db.AutoMigrate(&User{}, &Product{}, &Order{})
+db.AutoMigrate(&User{}, &Product{}, &Order{})
 
-// Add table suffix when create tables
-db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
+// Add table suffix when create tables
+db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
 

Has Table

-
// Check if model `User`'s table has been created or not
-db.HasTable(&User{})
+
// Check if model `User`'s table has been created or not
+db.HasTable(&User{})
 
-// Check table `users` exists or not
-db.HasTable("users")
+// Check table `users` exists or not
+db.HasTable("users")
 

Create Table

-
db.CreateTable(&User{})
+
db.CreateTable(&User{})
 
-db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
-// will append "ENGINE=InnoDB" to the SQL statement when creating table `users`
+db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
+// will append "ENGINE=InnoDB" to the SQL statement when creating table `users`
 

Drop table

-
db.DropTable(&User{})
+
db.DropTable(&User{})
 

ModifyColumn

Change column's type

-
// change column description's data type to `text` for model `User`'s table
-db.Model(&User{}).ModifyColumn("description", "text")
+
// change column description's data type to `text` for model `User`'s table
+db.Model(&User{}).ModifyColumn("description", "text")
 

DropColumn

-
db.Model(&User{}).DropColumn("description")
+
db.Model(&User{}).DropColumn("description")
 

Add Foreign Key

-
// Add foreign key
-// 1st param : foreignkey field
-// 2nd param : destination table(id)
-// 3rd param : ONDELETE
-// 4th param : ONUPDATE
-db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
+
// Add foreign key
+// 1st param : foreignkey field
+// 2nd param : destination table(id)
+// 3rd param : ONDELETE
+// 4th param : ONUPDATE
+db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
 

Indexes

-
// Add index
-db.Model(&User{}).AddIndex("idx_user_name", "name")
+
// Add index
+db.Model(&User{}).AddIndex("idx_user_name", "name")
 
-// Multiple column index
-db.Model(&User{}).AddIndex("idx_user_name_age", "name", "age")
+// Multiple column index
+db.Model(&User{}).AddIndex("idx_user_name_age", "name", "age")
 
-// Add unique index
-db.Model(&User{}).AddUniqueIndex("idx_user_name", "name")
+// Add unique index
+db.Model(&User{}).AddUniqueIndex("idx_user_name", "name")
 
-// Multiple column unique index
-db.Model(&User{}).AddUniqueIndex("idx_user_name_age", "name", "age")
+// Multiple column unique index
+db.Model(&User{}).AddUniqueIndex("idx_user_name_age", "name", "age")
 
-// Remove index
-db.Model(&User{}).RemoveIndex("idx_user_name")
+// Remove index
+db.Model(&User{}).RemoveIndex("idx_user_name")
 
@@ -766,7 +766,7 @@ db.Model require(["gitbook"], function(gitbook) { - gitbook.start({"fontsettings":{"theme":"night","family":"sans","size":4},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"prism":{},"anker-enable":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); + gitbook.start({"fontsettings":{"theme":"night","size":2,"family":"sans"},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"anker-enable":{},"highlight":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); }); diff --git a/development.html b/development.html index 13024618..3876f30d 100644 --- a/development.html +++ b/development.html @@ -16,7 +16,7 @@ - + @@ -70,7 +70,7 @@ data-chapter-title="Development" data-filepath="development.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -694,7 +694,7 @@ db.Callback().Create().Before("gorm:create").After("gorm:before_c diff --git a/documents/book.json b/documents/book.json index aa6871f8..a319a3ea 100644 --- a/documents/book.json +++ b/documents/book.json @@ -1,13 +1,12 @@ { "title": "GORM Guide", "plugins": [ - "-highlight", "prism", "toc", "github", "edit-link", "anker-enable" + "toc", "github", "edit-link", "anker-enable" ], "pluginsConfig": { "fontsettings": { "theme": "night", - "family": "sans", - "size": 4 + "size": 2 }, "toc": { "addClass": true, diff --git a/gitbook/gitbook-plugin-highlight/ebook.css b/gitbook/gitbook-plugin-highlight/ebook.css new file mode 100644 index 00000000..3779bae6 --- /dev/null +++ b/gitbook/gitbook-plugin-highlight/ebook.css @@ -0,0 +1,131 @@ +pre, +code { + /* http://jmblog.github.io/color-themes-for-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +pre .hljs-comment, +code .hljs-comment, +pre .hljs-title, +code .hljs-title { + color: #8e908c; +} +pre .hljs-variable, +code .hljs-variable, +pre .hljs-attribute, +code .hljs-attribute, +pre .hljs-tag, +code .hljs-tag, +pre .hljs-regexp, +code .hljs-regexp, +pre .ruby .hljs-constant, +code .ruby .hljs-constant, +pre .xml .hljs-tag .hljs-title, +code .xml .hljs-tag .hljs-title, +pre .xml .hljs-pi, +code .xml .hljs-pi, +pre .xml .hljs-doctype, +code .xml .hljs-doctype, +pre .html .hljs-doctype, +code .html .hljs-doctype, +pre .css .hljs-id, +code .css .hljs-id, +pre .css .hljs-class, +code .css .hljs-class, +pre .css .hljs-pseudo, +code .css .hljs-pseudo { + color: #c82829; +} +pre .hljs-number, +code .hljs-number, +pre .hljs-preprocessor, +code .hljs-preprocessor, +pre .hljs-pragma, +code .hljs-pragma, +pre .hljs-built_in, +code .hljs-built_in, +pre .hljs-literal, +code .hljs-literal, +pre .hljs-params, +code .hljs-params, +pre .hljs-constant, +code .hljs-constant { + color: #f5871f; +} +pre .ruby .hljs-class .hljs-title, +code .ruby .hljs-class .hljs-title, +pre .css .hljs-rules .hljs-attribute, +code .css .hljs-rules .hljs-attribute { + color: #eab700; +} +pre .hljs-string, +code .hljs-string, +pre .hljs-value, +code .hljs-value, +pre .hljs-inheritance, +code .hljs-inheritance, +pre .hljs-header, +code .hljs-header, +pre .ruby .hljs-symbol, +code .ruby .hljs-symbol, +pre .xml .hljs-cdata, +code .xml .hljs-cdata { + color: #718c00; +} +pre .css .hljs-hexcolor, +code .css .hljs-hexcolor { + color: #3e999f; +} +pre .hljs-function, +code .hljs-function, +pre .python .hljs-decorator, +code .python .hljs-decorator, +pre .python .hljs-title, +code .python .hljs-title, +pre .ruby .hljs-function .hljs-title, +code .ruby .hljs-function .hljs-title, +pre .ruby .hljs-title .hljs-keyword, +code .ruby .hljs-title .hljs-keyword, +pre .perl .hljs-sub, +code .perl .hljs-sub, +pre .javascript .hljs-title, +code .javascript .hljs-title, +pre .coffeescript .hljs-title, +code .coffeescript .hljs-title { + color: #4271ae; +} +pre .hljs-keyword, +code .hljs-keyword, +pre .javascript .hljs-function, +code .javascript .hljs-function { + color: #8959a8; +} +pre .hljs, +code .hljs { + display: block; + background: white; + color: #4d4d4c; + padding: 0.5em; +} +pre .coffeescript .javascript, +code .coffeescript .javascript, +pre .javascript .xml, +code .javascript .xml, +pre .tex .hljs-formula, +code .tex .hljs-formula, +pre .xml .javascript, +code .xml .javascript, +pre .xml .vbscript, +code .xml .vbscript, +pre .xml .css, +code .xml .css, +pre .xml .hljs-cdata, +code .xml .hljs-cdata { + opacity: 0.5; +} diff --git a/gitbook/gitbook-plugin-highlight/website.css b/gitbook/gitbook-plugin-highlight/website.css new file mode 100644 index 00000000..2aabd3de --- /dev/null +++ b/gitbook/gitbook-plugin-highlight/website.css @@ -0,0 +1,426 @@ +.book .book-body .page-wrapper .page-inner section.normal pre, +.book .book-body .page-wrapper .page-inner section.normal code { + /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-title { + color: #8e908c; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-tag, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-tag, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-id, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-class, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo { + color: #c82829; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-literal, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-literal, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-params, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-params, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-constant { + color: #f5871f; +} +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute { + color: #eab700; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-value, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-value, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-header, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + color: #718c00; +} +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor { + color: #3e999f; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator, +.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator, +.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub, +.book .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title { + color: #4271ae; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function { + color: #8959a8; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + background: white; + color: #4d4d4c; + padding: 0.5em; +} +.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript, +.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .xml, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .xml, +.book .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .javascript, +.book .book-body .page-wrapper .page-inner section.normal code .xml .javascript, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript, +.book .book-body .page-wrapper .page-inner section.normal code .xml .vbscript, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .css, +.book .book-body .page-wrapper .page-inner section.normal code .xml .css, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + opacity: 0.5; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { + /* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + /* Solarized Green */ + /* Solarized Cyan */ + /* Solarized Blue */ + /* Solarized Yellow */ + /* Solarized Orange */ + /* Solarized Red */ + /* Solarized Violet */ +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-template_comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-template_comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-doctype, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-doctype, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pi, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pi, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-javadoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-javadoc { + color: #93a1a1; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-winutils, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-winutils, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .method, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .method, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-tag, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-tag, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-request, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-request, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-status, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-status, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .nginx .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .nginx .hljs-title { + color: #859900; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-command, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-command, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-tag .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-rules .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-rules .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-phpdoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-phpdoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-hexcolor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-hexcolor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_url, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_url { + color: #2aa198; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-localvars, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-localvars, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-chunk, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-chunk, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-decorator, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-decorator, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-identifier, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-identifier, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .vhdl .hljs-literal, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .vhdl .hljs-literal, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-id, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-id, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-function, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-function { + color: #268bd2; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-body, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-body, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .smalltalk .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .smalltalk .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-constant, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-class .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-class .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-parent, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-parent, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .haskell .hljs-type, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .haskell .hljs-type, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_reference, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_reference { + color: #b58900; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-shebang, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-shebang, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-change, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-change, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-special, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-special, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attr_selector, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attr_selector, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-subst, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-subst, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-cdata, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-cdata, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .clojure .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .clojure .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-header { + color: #cb4b16; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-important, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-important { + color: #dc322f; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_label, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_label { + color: #6c71c4; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula { + background: #eee8d5; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { + /* Tomorrow Night Bright Theme */ + /* Original theme - https://github.com/chriskempson/tomorrow-theme */ + /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-title { + color: #969896; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-tag, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-id, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-class, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo { + color: #d54e53; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-literal, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-literal, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-params, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-params, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-constant { + color: #e78c45; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute { + color: #e7c547; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-value, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-value, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-header, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + color: #b9ca4a; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor { + color: #70c0b1; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title { + color: #7aa6da; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function { + color: #c397d8; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + background: black; + color: #eaeaea; + padding: 0.5em; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .xml, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .xml, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .vbscript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .css, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .css, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + opacity: 0.5; +} diff --git a/gitbook/gitbook-plugin-livereload/plugin.js b/gitbook/gitbook-plugin-livereload/plugin.js new file mode 100644 index 00000000..923b3aed --- /dev/null +++ b/gitbook/gitbook-plugin-livereload/plugin.js @@ -0,0 +1,11 @@ +(function() { + var newEl = document.createElement('script'), + firstScriptTag = document.getElementsByTagName('script')[0]; + + if (firstScriptTag) { + newEl.async = 1; + newEl.src = '//' + window.location.hostname + ':35729/livereload.js'; + firstScriptTag.parentNode.insertBefore(newEl, firstScriptTag); + } + +})(); diff --git a/index.html b/index.html index cae15a31..e97a2c2d 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@ - + @@ -68,7 +68,7 @@ data-chapter-title="Getting Started with GORM" data-filepath="README.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -602,30 +602,30 @@

Install

go get -u github.com/jinzhu/gorm
 

Basic Usage

-
type Product struct {
-  gorm.Model
-  Code string
-  Price uint
-}
+
type Product struct {
+  gorm.Model
+  Code string
+  Price uint
+}
 
-var db *gorm.DB
+var db *gorm.DB
 
-func init() {
-  var err error
-  db, err = gorm.Open("sqlite", "test.db")
-}
+func init() {
+  var err error
+  db, err = gorm.Open("sqlite", "test.db")
+}
 
-func main() {
-  db.Create(&Product{Code: "L1212", Price: 1000})
+func main() {
+  db.Create(&Product{Code: "L1212", Price: 1000})
 
-  var product Product
-  db.First(&product, 1) // find product with id 1
-  db.First(&product, "code = ?", "L1212") // find product with code l1212
+  var product Product
+  db.First(&product, 1) // find product with id 1
+  db.First(&product, "code = ?", "L1212") // find product with code l1212
 
-  db.Model(&product).Update("Price", 2000) // update product's price to 2000
+  db.Model(&product).Update("Price", 2000) // update product's price to 2000
 
-  db.Delete(&product) // delete product
-}
+  db.Delete(&product) // delete product
+}
 

Author

jinzhu

@@ -691,7 +691,7 @@ diff --git a/models.html b/models.html index 874847e7..326e9e7c 100644 --- a/models.html +++ b/models.html @@ -16,7 +16,7 @@ - + @@ -70,7 +70,7 @@ data-chapter-title="Models" data-filepath="models.md" data-basepath="" - data-revision="Mon Feb 29 2016 21:35:06 GMT+0800 (CST)" + data-revision="Mon Feb 29 2016 21:51:55 GMT+0800 (CST)" data-innerlanguage=""> @@ -597,83 +597,83 @@

Model Defination

-
type User struct {
-  gorm.Model
-    Birthday     time.Time
-    Age          int
-    Name         string  `sql:"size:255"` // Default size for string is 255, you could reset it with this tag
-    Num          int     `sql:"AUTO_INCREMENT"`
-    IgnoreMe     int `sql:"-"`   // Ignore this field
-}
+
type User struct {
+  gorm.Model
+    Birthday     time.Time
+    Age          int
+    Name         string  `sql:"size:255"` // Default size for string is 255, you could reset it with this tag
+    Num          int     `sql:"AUTO_INCREMENT"`
+    IgnoreMe     int `sql:"-"`   // Ignore this field
+}
 

Conventions & Overriding Conventions

gorm.Model struct

Gorm has defined struct gorm.Model, which could be embeded in your models, it will add fields ID, CreatedAt, UpdatedAt, DeletedAt to your model

-
// Model's definition
-type Model struct {
-  ID        uint `gorm:"primary_key"`
-  CreatedAt time.Time
-  UpdatedAt time.Time
-  DeletedAt *time.Time
-}
+
// Model's definition
+type Model struct {
+  ID        uint `gorm:"primary_key"`
+  CreatedAt time.Time
+  UpdatedAt time.Time
+  DeletedAt *time.Time
+}
 

Table name is the pluralized version of struct name

-
type User struct {} // default table name is `users`
+
type User struct {} // default table name is `users`
 
-// set User's table name to be `profiles
-type (User) TableName() string {
-  return "profiles"
-}
+// set User's table name to be `profiles
+type (User) TableName() string {
+  return "profiles"
+}
 
-func (u User) TableName() string {
-    if u.Role == "admin" {
-        return "admin_users"
-    } else {
-        return "users"
-    }
-}
+func (u User) TableName() string {
+    if u.Role == "admin" {
+        return "admin_users"
+    } else {
+        return "users"
+    }
+}
 
-// Disable table name's pluralization globally
-db.SingularTable(true) // if set this to true, `User`'s default table name will be `user`, table name setted with `TableName` won't be affected
+// Disable table name's pluralization globally
+db.SingularTable(true) // if set this to true, `User`'s default table name will be `user`, table name setted with `TableName` won't be affected
 

Column name is the snake case of field's name

-
type User struct {
-  ID uint             // column name will be `id`
-  Name string         // column name will be `name`
-  Birthday time.Time  // column name will be `birthday`
-  CreatedAt time.Time // column name will be `created_at`
-}
+
type User struct {
+  ID uint             // column name will be `id`
+  Name string         // column name will be `name`
+  Birthday time.Time  // column name will be `birthday`
+  CreatedAt time.Time // column name will be `created_at`
+}
 
-type Animal struct {
-    AnimalId    int64     `gorm:"column:beast_id"`         // set column name to `beast_id`
-    Birthday    time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
-    Age         int64     `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
-}
+type Animal struct {
+    AnimalId    int64     `gorm:"column:beast_id"`         // set column name to `beast_id`
+    Birthday    time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
+    Age         int64     `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
+}
 

Field ID as primary key

-
type User struct {
-  ID uint  // field named `ID` is the default primary key for `User`
-  Name string
-}
+
type User struct {
+  ID uint  // field named `ID` is the default primary key for `User`
+  Name string
+}
 
-// your could also use tag `primary_key` to set other field as primary key
-type Animal struct {
-  AnimalId int64 `gorm:"primary_key"` // set AnimalId to be primary key
-  Name     string
-  Age      int64
-}
+// your could also use tag `primary_key` to set other field as primary key
+type Animal struct {
+  AnimalId int64 `gorm:"primary_key"` // set AnimalId to be primary key
+  Name     string
+  Age      int64
+}
 

Field CreatedAt used to store record's created time

Create records having CreatedAt field will set it to current time.

-
db.Create(&user) // will set `CreatedAt` to current time
+
db.Create(&user) // will set `CreatedAt` to current time
 
-// To change its value, you could use `Update`
-db.Model(&user).Update("CreatedAt", time.Now())
+// To change its value, you could use `Update`
+db.Model(&user).Update("CreatedAt", time.Now())
 

Use UpdatedAt used to store record's updated time

Save records having UpdatedAt field will set it to current time.

-
db.Save(&user) // will set `UpdatedAt` to current time
-db.Model(&user).Update("name", "jinzhu") // will set `UpdatedAt` to current time
+
db.Save(&user) // will set `UpdatedAt` to current time
+db.Model(&user).Update("name", "jinzhu") // will set `UpdatedAt` to current time
 

Use DeletedAt to store record's deleted time if field exists

Delete records having DeletedAt field, it won't delete the record from database, but will set field DeletedAt's value to current time.

@@ -734,7 +734,7 @@ db.Model require(["gitbook"], function(gitbook) { - gitbook.start({"fontsettings":{"theme":"night","family":"sans","size":4},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"prism":{},"anker-enable":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); + gitbook.start({"fontsettings":{"theme":"night","size":2,"family":"sans"},"toc":{"addClass":true,"className":"toc"},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"base":"https://github.com/jinzhu/gorm/edit/gh-pages","label":"Edit This Page"},"anker-enable":{},"highlight":{},"search":{"maxIndexSize":1000000},"sharing":{"all":["facebook","google","instapaper","twitter","weibo"],"facebook":true,"google":false,"instapaper":false,"twitter":true,"vk":false,"weibo":false},"theme-default":{"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}}); });