diff --git a/db_service.go b/db_service.go
deleted file mode 100644
index bfb7318..0000000
--- a/db_service.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package main
-
-import (
- "context"
- gm "db_service/gorm_models"
- "db_service/models"
- helper "db_service/pkg"
- "encoding/json"
- "fmt"
- "log"
- "os"
- "sync"
- "time"
-)
-
-func dbService() error {
- fmt.Println("dbService started")
-
- tayyarla()
-
- start := time.Now()
-
- var resultingChannel = make(chan gm.Category)
- var producer_wg sync.WaitGroup
- var consumer_wg sync.WaitGroup
-
- // consumer
- for c := 0; c < len(mainCategories); c++ {
- producer_wg.Add(1)
- go func() {
- defer consumer_wg.Done()
-
- // WaitGroup for iterate functions
- const max = 20
- var wg sync.WaitGroup
-
- responses := make(chan bool, max)
-
- for item := range resultingChannel {
-
- wg.Add(1)
-
- db := "ty_db_" + item.Translations[0].Slug
-
- dbExists := helper.CheckDBExists("http://admin:adminadmin@localhost:5984/" + db)
-
- if dbExists {
- go iterate(db, responses, func() { wg.Done() })
- }
- }
-
- // close iterate function responses
- go func() {
- defer close(responses)
- wg.Wait()
- }()
-
- for response := range responses {
- fmt.Println("response", response)
- }
- }()
- }
-
- // producer
- for _, cat := range mainCategories {
- consumer_wg.Add(1)
- go func(category gm.Category) {
- defer producer_wg.Done()
- resultingChannel <- category
- }(cat)
- }
-
- producer_wg.Wait()
-
- close(resultingChannel)
-
- consumer_wg.Wait()
-
- elapsed := time.Since(start)
- log.Println("DB Time Elapsed:", elapsed)
-
- return nil
-}
-
-// func init() {
-// panic("unimplemented")
-// }
-
-// iterate categories
-func iterate(db string, finished chan<- bool, onExit func()) {
-
- _, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- defer onExit()
-
- // start := time.Now()
-
- // get total product count from couch database
- totalDocCount := getTotalDocumentCount(db)
-
- if totalDocCount == 0 {
- cancel()
- return
- }
-
- // total document counter
- i := 0
-
- for i < totalDocCount {
-
- cdbTime := time.Now()
- product, err := getDataFromCouchDb(i, db)
- i++
- if err != nil {
- fmt.Println(err)
- cancel()
- return
- }
-
- //TODO: insert product to mysql
- fmt.Println("product: ", product.Name, " db: ", db)
-
- log.Println("Couch DB. Time elapsed:", time.Since(cdbTime), " DB: ", db)
-
- // gorm.AutoMigrate(&product)
-
- // // if there is an error inserting, handle it
- // if err != nil {
- // gorm.Close()
- // panic(err.Error())
- // }
- // be careful deferring Queries if you are using transactions
- // gorm.Close()
-
- }
-
- finished <- true
-}
-
-// getTotalDocumentCount gets the total number of documents and returns
-func getTotalDocumentCount(db string) int {
-
- var response models.DBDocCountResponse
-
- url := os.Getenv("couch_db_source") + db
-
- body, err := helper.SendRequest("GET", url, nil, "", true)
-
- if err != nil {
- log.Println(err.Error())
- return 0
- }
-
- err = json.Unmarshal(body, &response)
- if err != nil {
- log.Println(err.Error())
- return 0
- }
-
- return response.DocCount
-}
-
-// getDataFromCouchDb gets data from local couch db
-func getDataFromCouchDb(i int, db string) (models.Product, error) {
- var model models.Product
- var response models.BagistoModelResponse
-
- url := os.Getenv("couch_db_source") + db + fmt.Sprintf("/_all_docs?include_docs=true&limit=1&skip=%v", i)
-
- body, err := helper.SendRequest("GET", url, nil, "", true)
- if err != nil {
- return model, err
- }
-
- err = json.Unmarshal(body, &response)
- if err != nil {
- log.Println(err.Error())
- return model, err
- }
-
- return response.Rows[0].Doc, nil
-}
-
-//https://gorm.io/docs/query.html
diff --git a/go.mod b/go.mod
index 42648b3..9b0a8ed 100644
--- a/go.mod
+++ b/go.mod
@@ -3,8 +3,8 @@ module db_service
go 1.19
require (
+ github.com/gorilla/mux v1.8.0
github.com/gosimple/slug v1.12.0
- github.com/jinzhu/gorm v1.9.16
github.com/joho/godotenv v1.4.0
gorm.io/driver/mysql v1.3.5
gorm.io/gorm v1.23.8
diff --git a/go.sum b/go.sum
index c2a62cd..323b508 100644
--- a/go.sum
+++ b/go.sum
@@ -1,44 +1,18 @@
-github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
-github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
-github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
-github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
-github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
-github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
-github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gosimple/slug v1.12.0 h1:xzuhj7G7cGtd34NXnW/yF0l+AGNfWqwgh/IXgFy7dnc=
github.com/gosimple/slug v1.12.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=
github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=
github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=
-github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
-github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
-github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
-github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
-github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
-golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gorm.io/driver/mysql v1.3.5 h1:iWBTVW/8Ij5AG4e0G/zqzaJblYkBI1VIL1LG2HUGsvY=
gorm.io/driver/mysql v1.3.5/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE=
diff --git a/inserter.go b/inserter.go
deleted file mode 100644
index dfb3b21..0000000
--- a/inserter.go
+++ /dev/null
@@ -1,210 +0,0 @@
-package main
-
-import (
- "context"
- gm "db_service/gorm_models"
- cb "db_service/models"
- helper "db_service/pkg"
- "fmt"
- "log"
- "os"
- "sync"
- "time"
-
- "gorm.io/gorm"
-)
-
-var mainCategories []gm.Category
-var baza *gorm.DB
-var resultingChannel = make(chan gm.Category)
-var producer_wg sync.WaitGroup
-var consumer_wg sync.WaitGroup
-
-func insertToBaza(product cb.Product) bool {
-
- return true
-}
-
-func tayyarla() {
-
- // baza, err := gorm.Open("mysql", os.Getenv("database_url"))
-
- // if err != nil {
- // panic(err)
- // }
-
- // mainCategories = gm.GetMainCategories(baza)
-
-}
-
-func bashlat() error {
-
- fmt.Println("Insert service starts")
- start := time.Now()
- tayyarla()
-
- fmt.Println("consuming")
- for c := 0; c < len(mainCategories); c++ {
- producer_wg.Add(1)
- go func() {
- defer consumer_wg.Done()
-
- // WaitGroup for iterate functions
- const max = 20
- var wg sync.WaitGroup
-
- responses := make(chan bool, max)
-
- for item := range resultingChannel {
-
- wg.Add(1)
-
- db := "ty_db_" + item.Translations[0].Slug
-
- dbExists := helper.CheckDBExists(os.Getenv("couchdb_url") + db)
-
- if dbExists {
- go iterateCategories(db, responses, func() { wg.Done() })
- }
- }
-
- // close iterate function responses
- go func() {
- defer close(responses)
- wg.Wait()
- }()
-
- for response := range responses {
- fmt.Println("response", response)
- }
- }()
- }
-
- fmt.Println("producing")
- for _, cat := range mainCategories {
- consumer_wg.Add(1)
- go func(category gm.Category) {
- defer producer_wg.Done()
- resultingChannel <- category
- }(cat)
- }
- producer_wg.Wait()
-
- close(resultingChannel)
-
- consumer_wg.Wait()
-
- elapsed := time.Since(start)
-
- log.Println("DB Time Elapsed:", elapsed)
-
- return nil
-
-}
-
-// func consumer() {
-// fmt.Println("consuming")
-// for c := 0; c < len(mainCategories); c++ {
-// producer_wg.Add(1)
-// go func() {
-// defer consumer_wg.Done()
-
-// // WaitGroup for iterate functions
-// const max = 20
-// var wg sync.WaitGroup
-
-// responses := make(chan bool, max)
-
-// for item := range resultingChannel {
-
-// wg.Add(1)
-
-// db := "ty_db_" + item.Translations[0].Slug
-
-// dbExists := helper.CheckDBExists(os.Getenv("couchdb_url") + db)
-
-// if dbExists {
-// go iterateCategories(db, responses, func() { wg.Done() })
-// }
-// }
-
-// // close iterate function responses
-// go func() {
-// defer close(responses)
-// wg.Wait()
-// }()
-
-// for response := range responses {
-// fmt.Println("response", response)
-// }
-// }()
-// }
-// }
-
-// func producer() {
-// fmt.Println("producing")
-// for _, cat := range mainCategories {
-// consumer_wg.Add(1)
-// go func(category gm.Category) {
-// defer producer_wg.Done()
-// resultingChannel <- category
-// }(cat)
-// }
-// producer_wg.Wait()
-
-// close(resultingChannel)
-
-// consumer_wg.Wait()
-// }
-
-// iterate categories
-func iterateCategories(db string, finished chan<- bool, onExit func()) {
-
- _, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- defer onExit()
-
- // start := time.Now()
-
- // get total product count from couch database
- totalDocCount := getTotalDocumentCount(db)
-
- if totalDocCount == 0 {
- cancel()
- return
- }
-
- // total document counter
- i := 0
-
- for i < totalDocCount {
-
- cdbTime := time.Now()
- product, err := getDataFromCouchDb(i, db)
- i++
- if err != nil {
- fmt.Println(err)
- cancel()
- return
- }
-
- //TODO: insert product to mysql
- fmt.Println("product: ", product.Name, " db: ", db)
-
- log.Println("Couch DB. Time elapsed:", time.Since(cdbTime), " DB: ", db)
-
- // gorm.AutoMigrate(&product)
-
- // // if there is an error inserting, handle it
- // if err != nil {
- // gorm.Close()
- // panic(err.Error())
- // }
- // be careful deferring Queries if you are using transactions
- // gorm.Close()
-
- }
-
- finished <- true
-}
diff --git a/main.go b/main.go
index afadddb..592f5b9 100644
--- a/main.go
+++ b/main.go
@@ -1,13 +1,11 @@
package main
import (
- "db_service/test"
- "fmt"
- "log"
- "math/big"
- "time"
-
+ importer "db_service/controllers"
+ "github.com/gorilla/mux"
"github.com/joho/godotenv"
+ "log"
+ "net/http"
)
func init() {
@@ -23,19 +21,18 @@ func init() {
func main() {
- // err := bashlat()
- start := time.Now()
+ route := mux.NewRouter()
+ route.HandleFunc("/init-importer", importer.Start)
+ err := http.ListenAndServe(":444", route)
- r := new(big.Int)
- fmt.Println("start import", r.Binomial(1000, 10))
-
- err := test.StartTest()
if err != nil {
- fmt.Println("err: ", err.Error())
+ log.Fatal("error: ", err)
}
+ //err := importer.Start()
+ //if err != nil {
+ // fmt.Println("err: ", err.Error())
+ //}
- elapsed := time.Since(start)
- log.Printf("end import took %s", elapsed)
// dene()
}
diff --git a/test/testit.go b/test/testit.go
deleted file mode 100644
index edfeaef..0000000
--- a/test/testit.go
+++ /dev/null
@@ -1,673 +0,0 @@
-package test
-
-import (
- gm "db_service/gorm_models"
- "db_service/models"
- helper "db_service/pkg"
- "encoding/json"
- "fmt"
- "log"
- "os"
- "strconv"
- "sync"
-
- "gorm.io/driver/mysql"
- "gorm.io/gorm"
-)
-
-var mainCategories []gm.Category
-var baza *gorm.DB
-var mainImportWG, famAndSellerWG sync.WaitGroup
-var families []gm.AttributeFamily
-var sellers = make(map[string]gm.MarketplaceSeller)
-var attributesMap = make(map[string]gm.Attribute)
-
-func StartTest() error {
- baza, err := gorm.Open(mysql.Open(os.Getenv("database_url")), &gorm.Config{})
-
- if err != nil {
- return err
- }
-
- //get categories from mysql on main thread
- mainCategories = gm.GetMainCategories(baza)
-
- famAndSellerWG.Add(3)
- //get attribute families from mysql with gorutine
- go func() {
- defer famAndSellerWG.Done()
- families = gm.GetFamilies(baza)
- }()
-
- //get sellers families from mysql with gorutine
- go func() {
- defer famAndSellerWG.Done()
- for _, vendor := range gm.GetSellers(baza) {
- sellers[vendor.Url] = vendor
- }
- }()
-
- go func() {
- defer famAndSellerWG.Done()
- var attributes = gm.GetAttributes(baza)
- for _, atrattribute := range attributes {
- attributesMap[atrattribute.Code] = atrattribute
- }
- }()
-
- mainImportWG.Add(len(mainCategories))
-
- for _, element := range mainCategories {
- slug := element.Translations[0].Slug
-
- go startImport("ty_db_"+slug, baza)
-
- // fmt.Println(<-result)
- }
-
- mainImportWG.Wait()
- fmt.Println("Terminating Program")
-
- return nil
-}
-
-func startImport(dbName string, db *gorm.DB) {
- defer mainImportWG.Done()
-
- dbExists := helper.CheckDBExists(os.Getenv("couch_db_source") + dbName)
- fmt.Println(dbName)
-
- if dbExists {
-
- totalDocCount := getTotalDocumentCount(dbName)
- skip := 0
- limit := 100
-
- for skip < totalDocCount {
-
- var response models.BagistoModelResponse
-
- url := fmt.Sprintf("%s%s/_all_docs?include_docs=true&limit=%v&skip=%v", os.Getenv("couch_db_source"), dbName, limit, skip)
-
- fmt.Println(url)
-
- skip += limit
-
- body, err := helper.SendRequest("GET", url, nil, "", true)
-
- if err != nil {
- fmt.Println(err.Error())
- continue
- }
-
- err = json.Unmarshal(body, &response)
-
- if err != nil {
- log.Println(err.Error())
- continue
- }
-
- //itearate 100 row products
- for _, element := range response.Rows {
- importProduct(element.Doc, db)
- }
- }
- } else {
- fmt.Println(dbName + "+doesnt exist")
- }
-
-}
-
-func getTotalDocumentCount(db string) int {
-
- var response models.DBDocCountResponse
-
- url := os.Getenv("couch_db_source") + db
-
- body, err := helper.SendRequest("GET", url, nil, "", true)
-
- if err != nil {
- log.Println(err.Error())
- return 0
- }
-
- err = json.Unmarshal(body, &response)
- if err != nil {
- log.Println(err.Error())
- return 0
- }
-
- return response.DocCount
-}
-
-// todo defailt variant
-// productflat
-
-func getCats(db *gorm.DB, catIDs []int) ([]gm.Category, string, error) {
- var categories []gm.Category
- var keywords string
-
- errCat := db.Preload("Translations").Find(&categories, catIDs).Error
-
- if errCat != nil {
- return categories, keywords, errCat
- }
-
- for _, cat := range categories {
- if len(cat.Translations) > 0 && cat.Translations[0].MetaKeywords != "" {
- translation := cat.Translations[0]
-
- keywords += "," + translation.MetaKeywords
- }
-
- }
-
- return categories, keywords, nil
-}
-
-func importProduct(product models.Product, db *gorm.DB) {
-
- famAndSellerWG.Wait() //wait until attribute families and sellers are not get from mysql
-
- categories, keywords, errCat := getCats(db, product.Categories)
-
- if errCat != nil {
- log.Println(errCat)
- return
- }
-
- var brand gm.Brand
-
- if product.Brand != "" {
- brand = gm.FindOrCreateBrand(db, product.Brand, categories)
- }
-
- attributes, mainProductFlat := prepearAttributesWithFlat(&product)
-
- attributes = append(attributes, gm.ProductAttributeValue{AttributeID: attributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"})
-
- iproduct := gm.Product{
- Sku: product.ProductGroupID,
- Type: "simple",
- AttributeFamilyID: families[0].ID,
- BrandID: brand.ID,
- Categories: categories,
- AttributeValues: attributes,
- }
-
- for _, element := range product.Images {
- iproduct.Images = append(iproduct.Images, gm.ProductImage{Type: "cdn", Path: element})
- }
-
- if product.ColorVariantCount > 0 {
- iproduct.SuperAttributes = append(iproduct.SuperAttributes, attributesMap["color"])
- }
-
- if len(product.SizeVariants) > 0 {
- iproduct.SuperAttributes = append(iproduct.SuperAttributes, attributesMap["size"])
- }
-
- if len(iproduct.SuperAttributes) > 0 {
- iproduct.Type = "configurable"
- iproduct.AttributeFamilyID = families[1].ID
- }
-
- errMainProduct := db.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&iproduct).Error
- if errMainProduct != nil {
- log.Println(errMainProduct)
- return
- }
-
- mainProductFlat.ProductID = iproduct.ID
- mainProductFlat.BrandID = brand.ID
- mainProductFlat.MetaKeywords = keywords
-
- errProductMainFlat := db.Create(&mainProductFlat).Error
-
- if errProductMainFlat != nil {
- log.Println(errProductMainFlat)
- return
- }
-
- if iproduct.Type == "configurable" {
-
- var productFlatVariants []gm.ProductFlat
-
- if len(product.ColorVariants) > 0 {
-
- var description string
- for _, colorVariant := range product.ColorVariants {
- weight, _ := strconv.ParseFloat(colorVariant.Weight, 64)
-
- for _, desc := range colorVariant.Descriptions {
- description += "
" + desc.Description + "
"
- }
-
- colorOption := gm.GetAttributeOption(db, attributesMap["color"].ID, colorVariant.Color)
-
- if len(colorVariant.SizeVariants) > 0 {
-
- for _, sizeVariant := range colorVariant.SizeVariants {
-
- if sizeVariant.Sellable {
- sku := fmt.Sprintf("%s-%s-%d-col-size", colorVariant.ProductGroupID, colorVariant.ProductNumber, sizeVariant.ItemNumber)
- sizeOption := gm.GetAttributeOption(db, attributesMap["size"].ID, sizeVariant.AttributeValue)
- productNumber := fmt.Sprintf("%s-%d", colorVariant.ProductNumber, sizeVariant.ItemNumber)
- attributes := []gm.ProductAttributeValue{
- {AttributeID: attributesMap["source"].ID, TextValue: colorVariant.URLKey, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["favoritesCount"].ID, IntegerValue: colorVariant.FavoriteCount, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["sku"].ID, TextValue: sku, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["product_number"].ID, TextValue: productNumber, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["name"].ID, TextValue: colorVariant.Name, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["weight"].ID, FloatValue: weight, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["status"].ID, BooleanValue: true, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["visible_individually"].ID, BooleanValue: true, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["url_key"].ID, TextValue: sku, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"},
- // {AttributeID: attributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"},
- {
- AttributeID: attributesMap["color"].ID,
- IntegerValue: int(colorOption.ID),
- Channel: "default",
- Locale: "tm",
- }, {
- AttributeID: attributesMap["size"].ID,
- IntegerValue: int(sizeOption.ID),
- Channel: "default",
- Locale: "tm",
- },
- }
-
- productVariant := gm.Product{
- ParentID: mainProductFlat.ProductID,
- Type: "simple",
- AttributeFamilyID: iproduct.AttributeFamilyID,
- Sku: sku,
- BrandID: mainProductFlat.BrandID,
- AttributeValues: attributes,
- Categories: categories,
- }
-
- for _, element := range colorVariant.Images {
- productVariant.Images = append(productVariant.Images, gm.ProductImage{Type: "cdn", Path: element})
- }
-
- errProdVariant := db.Omit("Categories.*").Create(&productVariant).Error
-
- if errProdVariant != nil {
- log.Println(errProdVariant)
- return
- }
-
- //todo assign images
- flatVariant := gm.ProductFlat{
- ProductID: productVariant.ID,
- BrandID: mainProductFlat.BrandID,
- Status: true,
- VisibleIndividually: true,
- Name: colorVariant.Name,
- Sku: sku,
- ProductNumber: productNumber,
- Description: description,
- UrlKey: sku,
- Weight: weight,
- // Source: colorVariant.URLKey,
- FavoritesCount: uint(colorVariant.FavoriteCount),
- Color: int(colorOption.ID),
- Size: int(sizeOption.ID),
- ColorLabel: colorOption.AdminName,
- SizeLabel: sizeOption.AdminName,
- MetaKeywords: keywords,
- ParentID: &mainProductFlat.ID,
- }
-
- if sizeVariant.Price.OriginalPrice.Value > sizeVariant.Price.DiscountedPrice.Value {
- attributes = append(attributes, []gm.ProductAttributeValue{
- {AttributeID: attributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["special_price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value, Channel: "default", Locale: "tm"},
- }...)
-
- flatVariant.Price = sizeVariant.Price.OriginalPrice.Value
- flatVariant.SpecialPrice = sizeVariant.Price.DiscountedPrice.Value
- flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value
- flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value
-
- } else {
- attributes = append(attributes, gm.ProductAttributeValue{AttributeID: attributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value, Channel: "default", Locale: "tm"})
-
- flatVariant.Price = sizeVariant.Price.OriginalPrice.Value
- flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value
- flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value
- }
-
- if mainProductFlat.MinPrice > flatVariant.MinPrice {
- mainProductFlat.MinPrice = flatVariant.MinPrice
- }
-
- if mainProductFlat.MaxPrice < flatVariant.MaxPrice {
- mainProductFlat.MaxPrice = flatVariant.MaxPrice
- }
-
- errVariant := db.Create(&flatVariant).Error
-
- if errVariant != nil {
- log.Println(errVariant)
- return
- }
-
- productFlatVariants = append(productFlatVariants, flatVariant)
- }
-
- }
- } else if colorVariant.IsSellable {
-
- colorOption := gm.GetAttributeOption(db, attributesMap["color"].ID, colorVariant.Color)
- attributes, variantFlat := collectAttributes(&colorVariant, &colorOption)
- attributes = append(attributes, gm.ProductAttributeValue{AttributeID: attributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"})
-
- if mainProductFlat.MinPrice > variantFlat.MinPrice {
- mainProductFlat.MinPrice = variantFlat.MinPrice
- }
-
- if mainProductFlat.MaxPrice < variantFlat.MaxPrice {
- mainProductFlat.MaxPrice = variantFlat.MaxPrice
- }
-
- sku := fmt.Sprintf("%s-%s-%s", iproduct.Sku, colorVariant.ProductNumber, colorVariant.ProductCode)
-
- productVariant := gm.Product{
- ParentID: mainProductFlat.ProductID,
- Type: "simple",
- Sku: sku,
- BrandID: mainProductFlat.BrandID,
- AttributeValues: attributes,
- AttributeFamilyID: iproduct.AttributeFamilyID,
- Categories: categories,
- }
-
- for _, element := range colorVariant.Images {
- productVariant.Images = append(productVariant.Images, gm.ProductImage{Type: "cdn", Path: element})
- }
-
- errProdVariant := db.Omit("Categories.*").Create(&productVariant).Error
-
- if errProdVariant != nil {
- log.Println(errProdVariant)
- return
- }
-
- variantFlat.ProductID = productVariant.ID
- variantFlat.Color = int(colorOption.ID)
- variantFlat.ColorLabel = colorOption.AdminName
- variantFlat.MetaKeywords = keywords
- variantFlat.ParentID = &mainProductFlat.ID
-
- errVariant := db.Create(&variantFlat).Error
-
- if errVariant != nil {
- log.Println(errVariant)
- return
- }
-
- productFlatVariants = append(productFlatVariants, variantFlat)
-
- }
- }
- }
-
- if len(product.SizeVariants) > 0 {
-
- var description string
- for _, desc := range product.Descriptions {
- description += "" + desc.Description + "
"
- }
- weight, _ := strconv.ParseFloat(product.Weight, 64)
-
- for _, sizeVariant := range product.SizeVariants {
-
- if sizeVariant.Sellable {
- sku := fmt.Sprintf("%s-%s-%d-size", iproduct.Sku, product.ProductNumber, sizeVariant.ItemNumber)
- sizeOption := gm.GetAttributeOption(db, attributesMap["size"].ID, sizeVariant.AttributeValue)
-
- attributes := []gm.ProductAttributeValue{
- {AttributeID: attributesMap["source"].ID, TextValue: product.URLKey},
- {AttributeID: attributesMap["favoritesCount"].ID, IntegerValue: product.FavoriteCount},
- {AttributeID: attributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["sku"].ID, TextValue: sku},
- {AttributeID: attributesMap["product_number"].ID, TextValue: fmt.Sprint(sizeVariant.ItemNumber)},
- {AttributeID: attributesMap["name"].ID, TextValue: product.Name, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["weight"].ID, FloatValue: weight},
- {AttributeID: attributesMap["status"].ID, BooleanValue: true},
- {AttributeID: attributesMap["visible_individually"].ID, BooleanValue: true},
- {AttributeID: attributesMap["url_key"].ID, TextValue: sku},
- {AttributeID: attributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["size"].ID, IntegerValue: int(sizeOption.ID)},
- // {AttributeID: attributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"},
- }
-
- flatVariant := gm.ProductFlat{
-
- Status: true,
- VisibleIndividually: true,
- Name: product.Name,
- Sku: sku,
- ProductNumber: fmt.Sprint(sizeVariant.ItemNumber),
- UrlKey: sku,
- Weight: weight,
- Size: int(sizeOption.ID),
- SizeLabel: sizeOption.AdminName,
- MetaKeywords: keywords,
- Product: gm.Product{
- ParentID: mainProductFlat.ProductID,
- Type: "simple",
- Sku: sku,
- BrandID: mainProductFlat.BrandID,
- AttributeValues: attributes,
- AttributeFamilyID: iproduct.AttributeFamilyID,
- Categories: categories,
- },
- // Source: product.URLKey,
- FavoritesCount: uint(product.FavoriteCount),
- ParentID: &mainProductFlat.ID,
- }
-
- if sizeVariant.Price.OriginalPrice.Value > sizeVariant.Price.DiscountedPrice.Value {
- attributes = append(attributes, []gm.ProductAttributeValue{
- {AttributeID: attributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value},
- {AttributeID: attributesMap["special_price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value},
- }...)
-
- flatVariant.Price = sizeVariant.Price.OriginalPrice.Value
- flatVariant.SpecialPrice = sizeVariant.Price.DiscountedPrice.Value
- flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value
- flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value
-
- } else {
- attributes = append(attributes, gm.ProductAttributeValue{AttributeID: attributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value})
-
- flatVariant.Price = sizeVariant.Price.OriginalPrice.Value
- flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value
- flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value
- }
-
- if mainProductFlat.MinPrice > flatVariant.MinPrice {
- mainProductFlat.MinPrice = flatVariant.MinPrice
- }
-
- if mainProductFlat.MaxPrice < flatVariant.MaxPrice {
- mainProductFlat.MaxPrice = flatVariant.MaxPrice
- }
- errVariant := db.Omit("Product.Categories.*").Create(&flatVariant).Error
-
- if errVariant != nil {
- log.Println(errVariant)
- return
- }
-
- productFlatVariants = append(productFlatVariants, flatVariant)
- }
- }
-
- }
-
- errFlat := db.Omit("Product.ParentID", "Product.SuperAttributes.*", "Product.Categories.*", "Source", "FavoritesCount", "CreatedAt").Save(&mainProductFlat)
-
- if errFlat != nil {
- log.Println(errFlat)
-
- }
- mainProductFlat.Variants = productFlatVariants
- }
-
- sProduct := createSellerProduct(&mainProductFlat, product.Vendor)
- //todo seller product, meta keys
- errSProduct := db.Create(&sProduct).Error
-
- if errSProduct != nil {
- log.Println(errSProduct)
- }
-}
-
-func createSellerProduct(flat *gm.ProductFlat, sellerURL string) gm.MarketplaceProduct {
- sellerProduct := gm.MarketplaceProduct{
- MarketplaceSeller: sellers[sellerURL],
- IsApproved: true,
- Condition: "new",
- Description: "scraped",
- IsOwner: true,
- ProductID: flat.ProductID,
- }
-
- for _, variant := range flat.Variants {
- sellerProduct.Variants = append(sellerProduct.Variants, gm.MarketplaceProduct{
- ProductID: variant.ProductID,
- IsOwner: true,
- IsApproved: true,
- MarketplaceSeller: sellers[sellerURL],
- Condition: "new",
- })
- }
-
- return sellerProduct
-
-}
-
-func collectAttributes(variant *models.Product, option *gm.AttributeOption) ([]gm.ProductAttributeValue, gm.ProductFlat) {
- sku := fmt.Sprintf("%s-%s", variant.ProductGroupID, variant.ProductNumber)
- weight, _ := strconv.ParseFloat(variant.Weight, 64)
- // var description string
-
- // for _, desc := range variant.Descriptions {
- // description += "" + desc.Description + "
"
- // }
- flat := gm.ProductFlat{
-
- Status: true,
- VisibleIndividually: true,
- Name: variant.Name,
- Sku: sku,
- ProductNumber: variant.ProductNumber,
- UrlKey: sku,
- Weight: weight,
- // Source: variant.URLKey,
- // FavoritesCount: uint(variant.FavoriteCount),
- }
-
- attributes := []gm.ProductAttributeValue{
- {AttributeID: attributesMap["favoritesCount"].ID, IntegerValue: variant.FavoriteCount},
- {AttributeID: attributesMap["source"].ID, TextValue: variant.URLKey},
- {AttributeID: attributesMap["sku"].ID, TextValue: sku},
- {AttributeID: attributesMap["product_number"].ID, TextValue: variant.ProductNumber},
- {AttributeID: attributesMap["name"].ID, TextValue: variant.Name, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["weight"].ID, FloatValue: weight},
- {AttributeID: attributesMap["status"].ID, BooleanValue: true},
- {AttributeID: attributesMap["visible_individually"].ID, BooleanValue: true},
- {AttributeID: attributesMap["url_key"].ID, TextValue: sku},
- {AttributeID: option.AttributeID, IntegerValue: int(option.ID)},
- // {AttributeID: attributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"},
- }
-
- if variant.Price.OriginalPrice.Value > variant.Price.DiscountedPrice.Value {
- attributes = append(attributes, []gm.ProductAttributeValue{
- {AttributeID: attributesMap["price"].ID, FloatValue: variant.Price.OriginalPrice.Value},
- {AttributeID: attributesMap["special_price"].ID, FloatValue: variant.Price.DiscountedPrice.Value},
- }...)
-
- flat.Price = variant.Price.OriginalPrice.Value
- flat.SpecialPrice = variant.Price.DiscountedPrice.Value
- flat.MinPrice = variant.Price.DiscountedPrice.Value
- flat.MaxPrice = variant.Price.OriginalPrice.Value
-
- } else {
- attributes = append(attributes, gm.ProductAttributeValue{AttributeID: attributesMap["price"].ID, FloatValue: variant.Price.OriginalPrice.Value})
- flat.Price = variant.Price.OriginalPrice.Value
- flat.MinPrice = variant.Price.DiscountedPrice.Value
- flat.MaxPrice = variant.Price.OriginalPrice.Value
- }
-
- return attributes, flat
-}
-
-func prepearAttributesWithFlat(data *models.Product) ([]gm.ProductAttributeValue, gm.ProductFlat) {
-
- weight, _ := strconv.ParseFloat(data.Weight, 64)
-
- var description string
-
- for _, desc := range data.Descriptions {
- description += "" + desc.Description + "
"
- }
- //$desc = implode(array_map(fn($value): string => '' . $value['description'] . '
', $data['descriptions']));
-
- var productAttributeValues = []gm.ProductAttributeValue{
- {AttributeID: attributesMap["source"].ID, TextValue: data.URLKey},
- {AttributeID: attributesMap["favoritesCount"].ID, IntegerValue: data.FavoriteCount},
- {AttributeID: attributesMap["sku"].ID, TextValue: data.ProductGroupID},
- {AttributeID: attributesMap["product_number"].ID, TextValue: data.ProductNumber},
- {AttributeID: attributesMap["name"].ID, TextValue: data.Name, Channel: "default", Locale: "tm"},
- {AttributeID: attributesMap["weight"].ID, FloatValue: weight},
- {AttributeID: attributesMap["status"].ID, BooleanValue: true},
- {AttributeID: attributesMap["visible_individually"].ID, BooleanValue: true},
- {AttributeID: attributesMap["url_key"].ID, TextValue: data.ProductGroupID},
- {AttributeID: attributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"},
- }
-
- flat := gm.ProductFlat{
-
- Status: true,
- VisibleIndividually: true,
- Name: data.Name,
- Sku: data.ProductGroupID,
- ProductNumber: data.ProductNumber,
- Description: description,
- UrlKey: data.ProductGroupID,
- Weight: weight,
- // Source: data.URLKey,
- FavoritesCount: uint(data.FavoriteCount),
- }
- if data.Price.OriginalPrice.Value > data.Price.DiscountedPrice.Value {
- productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{
- {AttributeID: attributesMap["price"].ID, FloatValue: data.Price.OriginalPrice.Value},
- {AttributeID: attributesMap["special_price"].ID, FloatValue: data.Price.DiscountedPrice.Value},
- }...)
-
- flat.Price = data.Price.OriginalPrice.Value
- flat.SpecialPrice = data.Price.DiscountedPrice.Value
- flat.MinPrice = data.Price.DiscountedPrice.Value
- flat.MaxPrice = data.Price.OriginalPrice.Value
-
- } else {
- productAttributeValues = append(productAttributeValues, gm.ProductAttributeValue{AttributeID: attributesMap["price"].ID, FloatValue: data.Price.OriginalPrice.Value})
- flat.Price = data.Price.OriginalPrice.Value
- flat.MinPrice = data.Price.OriginalPrice.Value
- flat.MaxPrice = data.Price.OriginalPrice.Value
- }
-
- if data.ColorVariantCount != 0 || len(data.SizeVariants) != 0 {
- flat.Price = 0
- flat.SpecialPrice = 0
- }
-
- return productAttributeValues, flat
-}
diff --git a/vendor/github.com/jinzhu/gorm/.gitignore b/vendor/github.com/jinzhu/gorm/.gitignore
deleted file mode 100644
index 117f92f..0000000
--- a/vendor/github.com/jinzhu/gorm/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-documents
-coverage.txt
-_book
diff --git a/vendor/github.com/jinzhu/gorm/License b/vendor/github.com/jinzhu/gorm/License
deleted file mode 100644
index 037e165..0000000
--- a/vendor/github.com/jinzhu/gorm/License
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013-NOW Jinzhu
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/jinzhu/gorm/README.md b/vendor/github.com/jinzhu/gorm/README.md
deleted file mode 100644
index 85588a7..0000000
--- a/vendor/github.com/jinzhu/gorm/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# GORM
-
-GORM V2 moved to https://github.com/go-gorm/gorm
-
-GORM V1 Doc https://v1.gorm.io/
diff --git a/vendor/github.com/jinzhu/gorm/association.go b/vendor/github.com/jinzhu/gorm/association.go
deleted file mode 100644
index a73344f..0000000
--- a/vendor/github.com/jinzhu/gorm/association.go
+++ /dev/null
@@ -1,377 +0,0 @@
-package gorm
-
-import (
- "errors"
- "fmt"
- "reflect"
-)
-
-// Association Mode contains some helper methods to handle relationship things easily.
-type Association struct {
- Error error
- scope *Scope
- column string
- field *Field
-}
-
-// Find find out all related associations
-func (association *Association) Find(value interface{}) *Association {
- association.scope.related(value, association.column)
- return association.setErr(association.scope.db.Error)
-}
-
-// Append append new associations for many2many, has_many, replace current association for has_one, belongs_to
-func (association *Association) Append(values ...interface{}) *Association {
- if association.Error != nil {
- return association
- }
-
- if relationship := association.field.Relationship; relationship.Kind == "has_one" {
- return association.Replace(values...)
- }
- return association.saveAssociations(values...)
-}
-
-// Replace replace current associations with new one
-func (association *Association) Replace(values ...interface{}) *Association {
- if association.Error != nil {
- return association
- }
-
- var (
- relationship = association.field.Relationship
- scope = association.scope
- field = association.field.Field
- newDB = scope.NewDB()
- )
-
- // Append new values
- association.field.Set(reflect.Zero(association.field.Field.Type()))
- association.saveAssociations(values...)
-
- // Belongs To
- if relationship.Kind == "belongs_to" {
- // Set foreign key to be null when clearing value (length equals 0)
- if len(values) == 0 {
- // Set foreign key to be nil
- var foreignKeyMap = map[string]interface{}{}
- for _, foreignKey := range relationship.ForeignDBNames {
- foreignKeyMap[foreignKey] = nil
- }
- association.setErr(newDB.Model(scope.Value).UpdateColumn(foreignKeyMap).Error)
- }
- } else {
- // Polymorphic Relations
- if relationship.PolymorphicDBName != "" {
- newDB = newDB.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.PolymorphicDBName)), relationship.PolymorphicValue)
- }
-
- // Delete Relations except new created
- if len(values) > 0 {
- var associationForeignFieldNames, associationForeignDBNames []string
- if relationship.Kind == "many_to_many" {
- // if many to many relations, get association fields name from association foreign keys
- associationScope := scope.New(reflect.New(field.Type()).Interface())
- for idx, dbName := range relationship.AssociationForeignFieldNames {
- if field, ok := associationScope.FieldByName(dbName); ok {
- associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
- associationForeignDBNames = append(associationForeignDBNames, relationship.AssociationForeignDBNames[idx])
- }
- }
- } else {
- // If has one/many relations, use primary keys
- for _, field := range scope.New(reflect.New(field.Type()).Interface()).PrimaryFields() {
- associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
- associationForeignDBNames = append(associationForeignDBNames, field.DBName)
- }
- }
-
- newPrimaryKeys := scope.getColumnAsArray(associationForeignFieldNames, field.Interface())
-
- if len(newPrimaryKeys) > 0 {
- sql := fmt.Sprintf("%v NOT IN (%v)", toQueryCondition(scope, associationForeignDBNames), toQueryMarks(newPrimaryKeys))
- newDB = newDB.Where(sql, toQueryValues(newPrimaryKeys)...)
- }
- }
-
- if relationship.Kind == "many_to_many" {
- // if many to many relations, delete related relations from join table
- var sourceForeignFieldNames []string
-
- for _, dbName := range relationship.ForeignFieldNames {
- if field, ok := scope.FieldByName(dbName); ok {
- sourceForeignFieldNames = append(sourceForeignFieldNames, field.Name)
- }
- }
-
- if sourcePrimaryKeys := scope.getColumnAsArray(sourceForeignFieldNames, scope.Value); len(sourcePrimaryKeys) > 0 {
- newDB = newDB.Where(fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(sourcePrimaryKeys)), toQueryValues(sourcePrimaryKeys)...)
-
- association.setErr(relationship.JoinTableHandler.Delete(relationship.JoinTableHandler, newDB))
- }
- } else if relationship.Kind == "has_one" || relationship.Kind == "has_many" {
- // has_one or has_many relations, set foreign key to be nil (TODO or delete them?)
- var foreignKeyMap = map[string]interface{}{}
- for idx, foreignKey := range relationship.ForeignDBNames {
- foreignKeyMap[foreignKey] = nil
- if field, ok := scope.FieldByName(relationship.AssociationForeignFieldNames[idx]); ok {
- newDB = newDB.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
- }
- }
-
- fieldValue := reflect.New(association.field.Field.Type()).Interface()
- association.setErr(newDB.Model(fieldValue).UpdateColumn(foreignKeyMap).Error)
- }
- }
- return association
-}
-
-// Delete remove relationship between source & passed arguments, but won't delete those arguments
-func (association *Association) Delete(values ...interface{}) *Association {
- if association.Error != nil {
- return association
- }
-
- var (
- relationship = association.field.Relationship
- scope = association.scope
- field = association.field.Field
- newDB = scope.NewDB()
- )
-
- if len(values) == 0 {
- return association
- }
-
- var deletingResourcePrimaryFieldNames, deletingResourcePrimaryDBNames []string
- for _, field := range scope.New(reflect.New(field.Type()).Interface()).PrimaryFields() {
- deletingResourcePrimaryFieldNames = append(deletingResourcePrimaryFieldNames, field.Name)
- deletingResourcePrimaryDBNames = append(deletingResourcePrimaryDBNames, field.DBName)
- }
-
- deletingPrimaryKeys := scope.getColumnAsArray(deletingResourcePrimaryFieldNames, values...)
-
- if relationship.Kind == "many_to_many" {
- // source value's foreign keys
- for idx, foreignKey := range relationship.ForeignDBNames {
- if field, ok := scope.FieldByName(relationship.ForeignFieldNames[idx]); ok {
- newDB = newDB.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
- }
- }
-
- // get association's foreign fields name
- var associationScope = scope.New(reflect.New(field.Type()).Interface())
- var associationForeignFieldNames []string
- for _, associationDBName := range relationship.AssociationForeignFieldNames {
- if field, ok := associationScope.FieldByName(associationDBName); ok {
- associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
- }
- }
-
- // association value's foreign keys
- deletingPrimaryKeys := scope.getColumnAsArray(associationForeignFieldNames, values...)
- sql := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(deletingPrimaryKeys))
- newDB = newDB.Where(sql, toQueryValues(deletingPrimaryKeys)...)
-
- association.setErr(relationship.JoinTableHandler.Delete(relationship.JoinTableHandler, newDB))
- } else {
- var foreignKeyMap = map[string]interface{}{}
- for _, foreignKey := range relationship.ForeignDBNames {
- foreignKeyMap[foreignKey] = nil
- }
-
- if relationship.Kind == "belongs_to" {
- // find with deleting relation's foreign keys
- primaryKeys := scope.getColumnAsArray(relationship.AssociationForeignFieldNames, values...)
- newDB = newDB.Where(
- fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)),
- toQueryValues(primaryKeys)...,
- )
-
- // set foreign key to be null if there are some records affected
- modelValue := reflect.New(scope.GetModelStruct().ModelType).Interface()
- if results := newDB.Model(modelValue).UpdateColumn(foreignKeyMap); results.Error == nil {
- if results.RowsAffected > 0 {
- scope.updatedAttrsWithValues(foreignKeyMap)
- }
- } else {
- association.setErr(results.Error)
- }
- } else if relationship.Kind == "has_one" || relationship.Kind == "has_many" {
- // find all relations
- primaryKeys := scope.getColumnAsArray(relationship.AssociationForeignFieldNames, scope.Value)
- newDB = newDB.Where(
- fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)),
- toQueryValues(primaryKeys)...,
- )
-
- // only include those deleting relations
- newDB = newDB.Where(
- fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, deletingResourcePrimaryDBNames), toQueryMarks(deletingPrimaryKeys)),
- toQueryValues(deletingPrimaryKeys)...,
- )
-
- // set matched relation's foreign key to be null
- fieldValue := reflect.New(association.field.Field.Type()).Interface()
- association.setErr(newDB.Model(fieldValue).UpdateColumn(foreignKeyMap).Error)
- }
- }
-
- // Remove deleted records from source's field
- if association.Error == nil {
- if field.Kind() == reflect.Slice {
- leftValues := reflect.Zero(field.Type())
-
- for i := 0; i < field.Len(); i++ {
- reflectValue := field.Index(i)
- primaryKey := scope.getColumnAsArray(deletingResourcePrimaryFieldNames, reflectValue.Interface())[0]
- var isDeleted = false
- for _, pk := range deletingPrimaryKeys {
- if equalAsString(primaryKey, pk) {
- isDeleted = true
- break
- }
- }
- if !isDeleted {
- leftValues = reflect.Append(leftValues, reflectValue)
- }
- }
-
- association.field.Set(leftValues)
- } else if field.Kind() == reflect.Struct {
- primaryKey := scope.getColumnAsArray(deletingResourcePrimaryFieldNames, field.Interface())[0]
- for _, pk := range deletingPrimaryKeys {
- if equalAsString(primaryKey, pk) {
- association.field.Set(reflect.Zero(field.Type()))
- break
- }
- }
- }
- }
-
- return association
-}
-
-// Clear remove relationship between source & current associations, won't delete those associations
-func (association *Association) Clear() *Association {
- return association.Replace()
-}
-
-// Count return the count of current associations
-func (association *Association) Count() int {
- var (
- count = 0
- relationship = association.field.Relationship
- scope = association.scope
- fieldValue = association.field.Field.Interface()
- query = scope.DB()
- )
-
- switch relationship.Kind {
- case "many_to_many":
- query = relationship.JoinTableHandler.JoinWith(relationship.JoinTableHandler, query, scope.Value)
- case "has_many", "has_one":
- primaryKeys := scope.getColumnAsArray(relationship.AssociationForeignFieldNames, scope.Value)
- query = query.Where(
- fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)),
- toQueryValues(primaryKeys)...,
- )
- case "belongs_to":
- primaryKeys := scope.getColumnAsArray(relationship.ForeignFieldNames, scope.Value)
- query = query.Where(
- fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(primaryKeys)),
- toQueryValues(primaryKeys)...,
- )
- }
-
- if relationship.PolymorphicType != "" {
- query = query.Where(
- fmt.Sprintf("%v.%v = ?", scope.New(fieldValue).QuotedTableName(), scope.Quote(relationship.PolymorphicDBName)),
- relationship.PolymorphicValue,
- )
- }
-
- if err := query.Model(fieldValue).Count(&count).Error; err != nil {
- association.Error = err
- }
- return count
-}
-
-// saveAssociations save passed values as associations
-func (association *Association) saveAssociations(values ...interface{}) *Association {
- var (
- scope = association.scope
- field = association.field
- relationship = field.Relationship
- )
-
- saveAssociation := func(reflectValue reflect.Value) {
- // value has to been pointer
- if reflectValue.Kind() != reflect.Ptr {
- reflectPtr := reflect.New(reflectValue.Type())
- reflectPtr.Elem().Set(reflectValue)
- reflectValue = reflectPtr
- }
-
- // value has to been saved for many2many
- if relationship.Kind == "many_to_many" {
- if scope.New(reflectValue.Interface()).PrimaryKeyZero() {
- association.setErr(scope.NewDB().Save(reflectValue.Interface()).Error)
- }
- }
-
- // Assign Fields
- var fieldType = field.Field.Type()
- var setFieldBackToValue, setSliceFieldBackToValue bool
- if reflectValue.Type().AssignableTo(fieldType) {
- field.Set(reflectValue)
- } else if reflectValue.Type().Elem().AssignableTo(fieldType) {
- // if field's type is struct, then need to set value back to argument after save
- setFieldBackToValue = true
- field.Set(reflectValue.Elem())
- } else if fieldType.Kind() == reflect.Slice {
- if reflectValue.Type().AssignableTo(fieldType.Elem()) {
- field.Set(reflect.Append(field.Field, reflectValue))
- } else if reflectValue.Type().Elem().AssignableTo(fieldType.Elem()) {
- // if field's type is slice of struct, then need to set value back to argument after save
- setSliceFieldBackToValue = true
- field.Set(reflect.Append(field.Field, reflectValue.Elem()))
- }
- }
-
- if relationship.Kind == "many_to_many" {
- association.setErr(relationship.JoinTableHandler.Add(relationship.JoinTableHandler, scope.NewDB(), scope.Value, reflectValue.Interface()))
- } else {
- association.setErr(scope.NewDB().Select(field.Name).Save(scope.Value).Error)
-
- if setFieldBackToValue {
- reflectValue.Elem().Set(field.Field)
- } else if setSliceFieldBackToValue {
- reflectValue.Elem().Set(field.Field.Index(field.Field.Len() - 1))
- }
- }
- }
-
- for _, value := range values {
- reflectValue := reflect.ValueOf(value)
- indirectReflectValue := reflect.Indirect(reflectValue)
- if indirectReflectValue.Kind() == reflect.Struct {
- saveAssociation(reflectValue)
- } else if indirectReflectValue.Kind() == reflect.Slice {
- for i := 0; i < indirectReflectValue.Len(); i++ {
- saveAssociation(indirectReflectValue.Index(i))
- }
- } else {
- association.setErr(errors.New("invalid value type"))
- }
- }
- return association
-}
-
-// setErr set error when the error is not nil. And return Association.
-func (association *Association) setErr(err error) *Association {
- if err != nil {
- association.Error = err
- }
- return association
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback.go b/vendor/github.com/jinzhu/gorm/callback.go
deleted file mode 100644
index 1f0e3c7..0000000
--- a/vendor/github.com/jinzhu/gorm/callback.go
+++ /dev/null
@@ -1,250 +0,0 @@
-package gorm
-
-import "fmt"
-
-// DefaultCallback default callbacks defined by gorm
-var DefaultCallback = &Callback{logger: nopLogger{}}
-
-// Callback is a struct that contains all CRUD callbacks
-// Field `creates` contains callbacks will be call when creating object
-// Field `updates` contains callbacks will be call when updating object
-// Field `deletes` contains callbacks will be call when deleting object
-// Field `queries` contains callbacks will be call when querying object with query methods like Find, First, Related, Association...
-// Field `rowQueries` contains callbacks will be call when querying object with Row, Rows...
-// Field `processors` contains all callback processors, will be used to generate above callbacks in order
-type Callback struct {
- logger logger
- creates []*func(scope *Scope)
- updates []*func(scope *Scope)
- deletes []*func(scope *Scope)
- queries []*func(scope *Scope)
- rowQueries []*func(scope *Scope)
- processors []*CallbackProcessor
-}
-
-// CallbackProcessor contains callback informations
-type CallbackProcessor struct {
- logger logger
- name string // current callback's name
- before string // register current callback before a callback
- after string // register current callback after a callback
- replace bool // replace callbacks with same name
- remove bool // delete callbacks with same name
- kind string // callback type: create, update, delete, query, row_query
- processor *func(scope *Scope) // callback handler
- parent *Callback
-}
-
-func (c *Callback) clone(logger logger) *Callback {
- return &Callback{
- logger: logger,
- creates: c.creates,
- updates: c.updates,
- deletes: c.deletes,
- queries: c.queries,
- rowQueries: c.rowQueries,
- processors: c.processors,
- }
-}
-
-// Create could be used to register callbacks for creating object
-// db.Callback().Create().After("gorm:create").Register("plugin:run_after_create", func(*Scope) {
-// // business logic
-// ...
-//
-// // set error if some thing wrong happened, will rollback the creating
-// scope.Err(errors.New("error"))
-// })
-func (c *Callback) Create() *CallbackProcessor {
- return &CallbackProcessor{logger: c.logger, kind: "create", parent: c}
-}
-
-// Update could be used to register callbacks for updating object, refer `Create` for usage
-func (c *Callback) Update() *CallbackProcessor {
- return &CallbackProcessor{logger: c.logger, kind: "update", parent: c}
-}
-
-// Delete could be used to register callbacks for deleting object, refer `Create` for usage
-func (c *Callback) Delete() *CallbackProcessor {
- return &CallbackProcessor{logger: c.logger, kind: "delete", parent: c}
-}
-
-// Query could be used to register callbacks for querying objects with query methods like `Find`, `First`, `Related`, `Association`...
-// Refer `Create` for usage
-func (c *Callback) Query() *CallbackProcessor {
- return &CallbackProcessor{logger: c.logger, kind: "query", parent: c}
-}
-
-// RowQuery could be used to register callbacks for querying objects with `Row`, `Rows`, refer `Create` for usage
-func (c *Callback) RowQuery() *CallbackProcessor {
- return &CallbackProcessor{logger: c.logger, kind: "row_query", parent: c}
-}
-
-// After insert a new callback after callback `callbackName`, refer `Callbacks.Create`
-func (cp *CallbackProcessor) After(callbackName string) *CallbackProcessor {
- cp.after = callbackName
- return cp
-}
-
-// Before insert a new callback before callback `callbackName`, refer `Callbacks.Create`
-func (cp *CallbackProcessor) Before(callbackName string) *CallbackProcessor {
- cp.before = callbackName
- return cp
-}
-
-// Register a new callback, refer `Callbacks.Create`
-func (cp *CallbackProcessor) Register(callbackName string, callback func(scope *Scope)) {
- if cp.kind == "row_query" {
- if cp.before == "" && cp.after == "" && callbackName != "gorm:row_query" {
- cp.logger.Print("info", fmt.Sprintf("Registering RowQuery callback %v without specify order with Before(), After(), applying Before('gorm:row_query') by default for compatibility...", callbackName))
- cp.before = "gorm:row_query"
- }
- }
-
- cp.logger.Print("info", fmt.Sprintf("[info] registering callback `%v` from %v", callbackName, fileWithLineNum()))
- cp.name = callbackName
- cp.processor = &callback
- cp.parent.processors = append(cp.parent.processors, cp)
- cp.parent.reorder()
-}
-
-// Remove a registered callback
-// db.Callback().Create().Remove("gorm:update_time_stamp_when_create")
-func (cp *CallbackProcessor) Remove(callbackName string) {
- cp.logger.Print("info", fmt.Sprintf("[info] removing callback `%v` from %v", callbackName, fileWithLineNum()))
- cp.name = callbackName
- cp.remove = true
- cp.parent.processors = append(cp.parent.processors, cp)
- cp.parent.reorder()
-}
-
-// Replace a registered callback with new callback
-// db.Callback().Create().Replace("gorm:update_time_stamp_when_create", func(*Scope) {
-// scope.SetColumn("CreatedAt", now)
-// scope.SetColumn("UpdatedAt", now)
-// })
-func (cp *CallbackProcessor) Replace(callbackName string, callback func(scope *Scope)) {
- cp.logger.Print("info", fmt.Sprintf("[info] replacing callback `%v` from %v", callbackName, fileWithLineNum()))
- cp.name = callbackName
- cp.processor = &callback
- cp.replace = true
- cp.parent.processors = append(cp.parent.processors, cp)
- cp.parent.reorder()
-}
-
-// Get registered callback
-// db.Callback().Create().Get("gorm:create")
-func (cp *CallbackProcessor) Get(callbackName string) (callback func(scope *Scope)) {
- for _, p := range cp.parent.processors {
- if p.name == callbackName && p.kind == cp.kind {
- if p.remove {
- callback = nil
- } else {
- callback = *p.processor
- }
- }
- }
- return
-}
-
-// getRIndex get right index from string slice
-func getRIndex(strs []string, str string) int {
- for i := len(strs) - 1; i >= 0; i-- {
- if strs[i] == str {
- return i
- }
- }
- return -1
-}
-
-// sortProcessors sort callback processors based on its before, after, remove, replace
-func sortProcessors(cps []*CallbackProcessor) []*func(scope *Scope) {
- var (
- allNames, sortedNames []string
- sortCallbackProcessor func(c *CallbackProcessor)
- )
-
- for _, cp := range cps {
- // show warning message the callback name already exists
- if index := getRIndex(allNames, cp.name); index > -1 && !cp.replace && !cp.remove {
- cp.logger.Print("warning", fmt.Sprintf("[warning] duplicated callback `%v` from %v", cp.name, fileWithLineNum()))
- }
- allNames = append(allNames, cp.name)
- }
-
- sortCallbackProcessor = func(c *CallbackProcessor) {
- if getRIndex(sortedNames, c.name) == -1 { // if not sorted
- if c.before != "" { // if defined before callback
- if index := getRIndex(sortedNames, c.before); index != -1 {
- // if before callback already sorted, append current callback just after it
- sortedNames = append(sortedNames[:index], append([]string{c.name}, sortedNames[index:]...)...)
- } else if index := getRIndex(allNames, c.before); index != -1 {
- // if before callback exists but haven't sorted, append current callback to last
- sortedNames = append(sortedNames, c.name)
- sortCallbackProcessor(cps[index])
- }
- }
-
- if c.after != "" { // if defined after callback
- if index := getRIndex(sortedNames, c.after); index != -1 {
- // if after callback already sorted, append current callback just before it
- sortedNames = append(sortedNames[:index+1], append([]string{c.name}, sortedNames[index+1:]...)...)
- } else if index := getRIndex(allNames, c.after); index != -1 {
- // if after callback exists but haven't sorted
- cp := cps[index]
- // set after callback's before callback to current callback
- if cp.before == "" {
- cp.before = c.name
- }
- sortCallbackProcessor(cp)
- }
- }
-
- // if current callback haven't been sorted, append it to last
- if getRIndex(sortedNames, c.name) == -1 {
- sortedNames = append(sortedNames, c.name)
- }
- }
- }
-
- for _, cp := range cps {
- sortCallbackProcessor(cp)
- }
-
- var sortedFuncs []*func(scope *Scope)
- for _, name := range sortedNames {
- if index := getRIndex(allNames, name); !cps[index].remove {
- sortedFuncs = append(sortedFuncs, cps[index].processor)
- }
- }
-
- return sortedFuncs
-}
-
-// reorder all registered processors, and reset CRUD callbacks
-func (c *Callback) reorder() {
- var creates, updates, deletes, queries, rowQueries []*CallbackProcessor
-
- for _, processor := range c.processors {
- if processor.name != "" {
- switch processor.kind {
- case "create":
- creates = append(creates, processor)
- case "update":
- updates = append(updates, processor)
- case "delete":
- deletes = append(deletes, processor)
- case "query":
- queries = append(queries, processor)
- case "row_query":
- rowQueries = append(rowQueries, processor)
- }
- }
- }
-
- c.creates = sortProcessors(creates)
- c.updates = sortProcessors(updates)
- c.deletes = sortProcessors(deletes)
- c.queries = sortProcessors(queries)
- c.rowQueries = sortProcessors(rowQueries)
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_create.go b/vendor/github.com/jinzhu/gorm/callback_create.go
deleted file mode 100644
index c4d25f3..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_create.go
+++ /dev/null
@@ -1,197 +0,0 @@
-package gorm
-
-import (
- "fmt"
- "strings"
-)
-
-// Define callbacks for creating
-func init() {
- DefaultCallback.Create().Register("gorm:begin_transaction", beginTransactionCallback)
- DefaultCallback.Create().Register("gorm:before_create", beforeCreateCallback)
- DefaultCallback.Create().Register("gorm:save_before_associations", saveBeforeAssociationsCallback)
- DefaultCallback.Create().Register("gorm:update_time_stamp", updateTimeStampForCreateCallback)
- DefaultCallback.Create().Register("gorm:create", createCallback)
- DefaultCallback.Create().Register("gorm:force_reload_after_create", forceReloadAfterCreateCallback)
- DefaultCallback.Create().Register("gorm:save_after_associations", saveAfterAssociationsCallback)
- DefaultCallback.Create().Register("gorm:after_create", afterCreateCallback)
- DefaultCallback.Create().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
-}
-
-// beforeCreateCallback will invoke `BeforeSave`, `BeforeCreate` method before creating
-func beforeCreateCallback(scope *Scope) {
- if !scope.HasError() {
- scope.CallMethod("BeforeSave")
- }
- if !scope.HasError() {
- scope.CallMethod("BeforeCreate")
- }
-}
-
-// updateTimeStampForCreateCallback will set `CreatedAt`, `UpdatedAt` when creating
-func updateTimeStampForCreateCallback(scope *Scope) {
- if !scope.HasError() {
- now := scope.db.nowFunc()
-
- if createdAtField, ok := scope.FieldByName("CreatedAt"); ok {
- if createdAtField.IsBlank {
- createdAtField.Set(now)
- }
- }
-
- if updatedAtField, ok := scope.FieldByName("UpdatedAt"); ok {
- if updatedAtField.IsBlank {
- updatedAtField.Set(now)
- }
- }
- }
-}
-
-// createCallback the callback used to insert data into database
-func createCallback(scope *Scope) {
- if !scope.HasError() {
- defer scope.trace(NowFunc())
-
- var (
- columns, placeholders []string
- blankColumnsWithDefaultValue []string
- )
-
- for _, field := range scope.Fields() {
- if scope.changeableField(field) {
- if field.IsNormal && !field.IsIgnored {
- if field.IsBlank && field.HasDefaultValue {
- blankColumnsWithDefaultValue = append(blankColumnsWithDefaultValue, scope.Quote(field.DBName))
- scope.InstanceSet("gorm:blank_columns_with_default_value", blankColumnsWithDefaultValue)
- } else if !field.IsPrimaryKey || !field.IsBlank {
- columns = append(columns, scope.Quote(field.DBName))
- placeholders = append(placeholders, scope.AddToVars(field.Field.Interface()))
- }
- } else if field.Relationship != nil && field.Relationship.Kind == "belongs_to" {
- for _, foreignKey := range field.Relationship.ForeignDBNames {
- if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) {
- columns = append(columns, scope.Quote(foreignField.DBName))
- placeholders = append(placeholders, scope.AddToVars(foreignField.Field.Interface()))
- }
- }
- }
- }
- }
-
- var (
- returningColumn = "*"
- quotedTableName = scope.QuotedTableName()
- primaryField = scope.PrimaryField()
- extraOption string
- insertModifier string
- )
-
- if str, ok := scope.Get("gorm:insert_option"); ok {
- extraOption = fmt.Sprint(str)
- }
- if str, ok := scope.Get("gorm:insert_modifier"); ok {
- insertModifier = strings.ToUpper(fmt.Sprint(str))
- if insertModifier == "INTO" {
- insertModifier = ""
- }
- }
-
- if primaryField != nil {
- returningColumn = scope.Quote(primaryField.DBName)
- }
-
- lastInsertIDOutputInterstitial := scope.Dialect().LastInsertIDOutputInterstitial(quotedTableName, returningColumn, columns)
- var lastInsertIDReturningSuffix string
- if lastInsertIDOutputInterstitial == "" {
- lastInsertIDReturningSuffix = scope.Dialect().LastInsertIDReturningSuffix(quotedTableName, returningColumn)
- }
-
- if len(columns) == 0 {
- scope.Raw(fmt.Sprintf(
- "INSERT%v INTO %v %v%v%v",
- addExtraSpaceIfExist(insertModifier),
- quotedTableName,
- scope.Dialect().DefaultValueStr(),
- addExtraSpaceIfExist(extraOption),
- addExtraSpaceIfExist(lastInsertIDReturningSuffix),
- ))
- } else {
- scope.Raw(fmt.Sprintf(
- "INSERT%v INTO %v (%v)%v VALUES (%v)%v%v",
- addExtraSpaceIfExist(insertModifier),
- scope.QuotedTableName(),
- strings.Join(columns, ","),
- addExtraSpaceIfExist(lastInsertIDOutputInterstitial),
- strings.Join(placeholders, ","),
- addExtraSpaceIfExist(extraOption),
- addExtraSpaceIfExist(lastInsertIDReturningSuffix),
- ))
- }
-
- // execute create sql: no primaryField
- if primaryField == nil {
- if result, err := scope.SQLDB().Exec(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
- // set rows affected count
- scope.db.RowsAffected, _ = result.RowsAffected()
-
- // set primary value to primary field
- if primaryField != nil && primaryField.IsBlank {
- if primaryValue, err := result.LastInsertId(); scope.Err(err) == nil {
- scope.Err(primaryField.Set(primaryValue))
- }
- }
- }
- return
- }
-
- // execute create sql: lastInsertID implemention for majority of dialects
- if lastInsertIDReturningSuffix == "" && lastInsertIDOutputInterstitial == "" {
- if result, err := scope.SQLDB().Exec(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
- // set rows affected count
- scope.db.RowsAffected, _ = result.RowsAffected()
-
- // set primary value to primary field
- if primaryField != nil && primaryField.IsBlank {
- if primaryValue, err := result.LastInsertId(); scope.Err(err) == nil {
- scope.Err(primaryField.Set(primaryValue))
- }
- }
- }
- return
- }
-
- // execute create sql: dialects with additional lastInsertID requirements (currently postgres & mssql)
- if primaryField.Field.CanAddr() {
- if err := scope.SQLDB().QueryRow(scope.SQL, scope.SQLVars...).Scan(primaryField.Field.Addr().Interface()); scope.Err(err) == nil {
- primaryField.IsBlank = false
- scope.db.RowsAffected = 1
- }
- } else {
- scope.Err(ErrUnaddressable)
- }
- return
- }
-}
-
-// forceReloadAfterCreateCallback will reload columns that having default value, and set it back to current object
-func forceReloadAfterCreateCallback(scope *Scope) {
- if blankColumnsWithDefaultValue, ok := scope.InstanceGet("gorm:blank_columns_with_default_value"); ok {
- db := scope.DB().New().Table(scope.TableName()).Select(blankColumnsWithDefaultValue.([]string))
- for _, field := range scope.Fields() {
- if field.IsPrimaryKey && !field.IsBlank {
- db = db.Where(fmt.Sprintf("%v = ?", field.DBName), field.Field.Interface())
- }
- }
- db.Scan(scope.Value)
- }
-}
-
-// afterCreateCallback will invoke `AfterCreate`, `AfterSave` method after creating
-func afterCreateCallback(scope *Scope) {
- if !scope.HasError() {
- scope.CallMethod("AfterCreate")
- }
- if !scope.HasError() {
- scope.CallMethod("AfterSave")
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_delete.go b/vendor/github.com/jinzhu/gorm/callback_delete.go
deleted file mode 100644
index 48b97ac..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_delete.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package gorm
-
-import (
- "errors"
- "fmt"
-)
-
-// Define callbacks for deleting
-func init() {
- DefaultCallback.Delete().Register("gorm:begin_transaction", beginTransactionCallback)
- DefaultCallback.Delete().Register("gorm:before_delete", beforeDeleteCallback)
- DefaultCallback.Delete().Register("gorm:delete", deleteCallback)
- DefaultCallback.Delete().Register("gorm:after_delete", afterDeleteCallback)
- DefaultCallback.Delete().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
-}
-
-// beforeDeleteCallback will invoke `BeforeDelete` method before deleting
-func beforeDeleteCallback(scope *Scope) {
- if scope.DB().HasBlockGlobalUpdate() && !scope.hasConditions() {
- scope.Err(errors.New("missing WHERE clause while deleting"))
- return
- }
- if !scope.HasError() {
- scope.CallMethod("BeforeDelete")
- }
-}
-
-// deleteCallback used to delete data from database or set deleted_at to current time (when using with soft delete)
-func deleteCallback(scope *Scope) {
- if !scope.HasError() {
- var extraOption string
- if str, ok := scope.Get("gorm:delete_option"); ok {
- extraOption = fmt.Sprint(str)
- }
-
- deletedAtField, hasDeletedAtField := scope.FieldByName("DeletedAt")
-
- if !scope.Search.Unscoped && hasDeletedAtField {
- scope.Raw(fmt.Sprintf(
- "UPDATE %v SET %v=%v%v%v",
- scope.QuotedTableName(),
- scope.Quote(deletedAtField.DBName),
- scope.AddToVars(scope.db.nowFunc()),
- addExtraSpaceIfExist(scope.CombinedConditionSql()),
- addExtraSpaceIfExist(extraOption),
- )).Exec()
- } else {
- scope.Raw(fmt.Sprintf(
- "DELETE FROM %v%v%v",
- scope.QuotedTableName(),
- addExtraSpaceIfExist(scope.CombinedConditionSql()),
- addExtraSpaceIfExist(extraOption),
- )).Exec()
- }
- }
-}
-
-// afterDeleteCallback will invoke `AfterDelete` method after deleting
-func afterDeleteCallback(scope *Scope) {
- if !scope.HasError() {
- scope.CallMethod("AfterDelete")
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_query.go b/vendor/github.com/jinzhu/gorm/callback_query.go
deleted file mode 100644
index 544afd6..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_query.go
+++ /dev/null
@@ -1,109 +0,0 @@
-package gorm
-
-import (
- "errors"
- "fmt"
- "reflect"
-)
-
-// Define callbacks for querying
-func init() {
- DefaultCallback.Query().Register("gorm:query", queryCallback)
- DefaultCallback.Query().Register("gorm:preload", preloadCallback)
- DefaultCallback.Query().Register("gorm:after_query", afterQueryCallback)
-}
-
-// queryCallback used to query data from database
-func queryCallback(scope *Scope) {
- if _, skip := scope.InstanceGet("gorm:skip_query_callback"); skip {
- return
- }
-
- //we are only preloading relations, dont touch base model
- if _, skip := scope.InstanceGet("gorm:only_preload"); skip {
- return
- }
-
- defer scope.trace(NowFunc())
-
- var (
- isSlice, isPtr bool
- resultType reflect.Type
- results = scope.IndirectValue()
- )
-
- if orderBy, ok := scope.Get("gorm:order_by_primary_key"); ok {
- if primaryField := scope.PrimaryField(); primaryField != nil {
- scope.Search.Order(fmt.Sprintf("%v.%v %v", scope.QuotedTableName(), scope.Quote(primaryField.DBName), orderBy))
- }
- }
-
- if value, ok := scope.Get("gorm:query_destination"); ok {
- results = indirect(reflect.ValueOf(value))
- }
-
- if kind := results.Kind(); kind == reflect.Slice {
- isSlice = true
- resultType = results.Type().Elem()
- results.Set(reflect.MakeSlice(results.Type(), 0, 0))
-
- if resultType.Kind() == reflect.Ptr {
- isPtr = true
- resultType = resultType.Elem()
- }
- } else if kind != reflect.Struct {
- scope.Err(errors.New("unsupported destination, should be slice or struct"))
- return
- }
-
- scope.prepareQuerySQL()
-
- if !scope.HasError() {
- scope.db.RowsAffected = 0
-
- if str, ok := scope.Get("gorm:query_hint"); ok {
- scope.SQL = fmt.Sprint(str) + scope.SQL
- }
-
- if str, ok := scope.Get("gorm:query_option"); ok {
- scope.SQL += addExtraSpaceIfExist(fmt.Sprint(str))
- }
-
- if rows, err := scope.SQLDB().Query(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
- defer rows.Close()
-
- columns, _ := rows.Columns()
- for rows.Next() {
- scope.db.RowsAffected++
-
- elem := results
- if isSlice {
- elem = reflect.New(resultType).Elem()
- }
-
- scope.scan(rows, columns, scope.New(elem.Addr().Interface()).Fields())
-
- if isSlice {
- if isPtr {
- results.Set(reflect.Append(results, elem.Addr()))
- } else {
- results.Set(reflect.Append(results, elem))
- }
- }
- }
-
- if err := rows.Err(); err != nil {
- scope.Err(err)
- } else if scope.db.RowsAffected == 0 && !isSlice {
- scope.Err(ErrRecordNotFound)
- }
- }
- }
-}
-
-// afterQueryCallback will invoke `AfterFind` method after querying
-func afterQueryCallback(scope *Scope) {
- if !scope.HasError() {
- scope.CallMethod("AfterFind")
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_query_preload.go b/vendor/github.com/jinzhu/gorm/callback_query_preload.go
deleted file mode 100644
index a936180..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_query_preload.go
+++ /dev/null
@@ -1,410 +0,0 @@
-package gorm
-
-import (
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "strings"
-)
-
-// preloadCallback used to preload associations
-func preloadCallback(scope *Scope) {
- if _, skip := scope.InstanceGet("gorm:skip_query_callback"); skip {
- return
- }
-
- if ap, ok := scope.Get("gorm:auto_preload"); ok {
- // If gorm:auto_preload IS NOT a bool then auto preload.
- // Else if it IS a bool, use the value
- if apb, ok := ap.(bool); !ok {
- autoPreload(scope)
- } else if apb {
- autoPreload(scope)
- }
- }
-
- if scope.Search.preload == nil || scope.HasError() {
- return
- }
-
- var (
- preloadedMap = map[string]bool{}
- fields = scope.Fields()
- )
-
- for _, preload := range scope.Search.preload {
- var (
- preloadFields = strings.Split(preload.schema, ".")
- currentScope = scope
- currentFields = fields
- )
-
- for idx, preloadField := range preloadFields {
- var currentPreloadConditions []interface{}
-
- if currentScope == nil {
- continue
- }
-
- // if not preloaded
- if preloadKey := strings.Join(preloadFields[:idx+1], "."); !preloadedMap[preloadKey] {
-
- // assign search conditions to last preload
- if idx == len(preloadFields)-1 {
- currentPreloadConditions = preload.conditions
- }
-
- for _, field := range currentFields {
- if field.Name != preloadField || field.Relationship == nil {
- continue
- }
-
- switch field.Relationship.Kind {
- case "has_one":
- currentScope.handleHasOnePreload(field, currentPreloadConditions)
- case "has_many":
- currentScope.handleHasManyPreload(field, currentPreloadConditions)
- case "belongs_to":
- currentScope.handleBelongsToPreload(field, currentPreloadConditions)
- case "many_to_many":
- currentScope.handleManyToManyPreload(field, currentPreloadConditions)
- default:
- scope.Err(errors.New("unsupported relation"))
- }
-
- preloadedMap[preloadKey] = true
- break
- }
-
- if !preloadedMap[preloadKey] {
- scope.Err(fmt.Errorf("can't preload field %s for %s", preloadField, currentScope.GetModelStruct().ModelType))
- return
- }
- }
-
- // preload next level
- if idx < len(preloadFields)-1 {
- currentScope = currentScope.getColumnAsScope(preloadField)
- if currentScope != nil {
- currentFields = currentScope.Fields()
- }
- }
- }
- }
-}
-
-func autoPreload(scope *Scope) {
- for _, field := range scope.Fields() {
- if field.Relationship == nil {
- continue
- }
-
- if val, ok := field.TagSettingsGet("PRELOAD"); ok {
- if preload, err := strconv.ParseBool(val); err != nil {
- scope.Err(errors.New("invalid preload option"))
- return
- } else if !preload {
- continue
- }
- }
-
- scope.Search.Preload(field.Name)
- }
-}
-
-func (scope *Scope) generatePreloadDBWithConditions(conditions []interface{}) (*DB, []interface{}) {
- var (
- preloadDB = scope.NewDB()
- preloadConditions []interface{}
- )
-
- for _, condition := range conditions {
- if scopes, ok := condition.(func(*DB) *DB); ok {
- preloadDB = scopes(preloadDB)
- } else {
- preloadConditions = append(preloadConditions, condition)
- }
- }
-
- return preloadDB, preloadConditions
-}
-
-// handleHasOnePreload used to preload has one associations
-func (scope *Scope) handleHasOnePreload(field *Field, conditions []interface{}) {
- relation := field.Relationship
-
- // get relations's primary keys
- primaryKeys := scope.getColumnAsArray(relation.AssociationForeignFieldNames, scope.Value)
- if len(primaryKeys) == 0 {
- return
- }
-
- // preload conditions
- preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
-
- // find relations
- query := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relation.ForeignDBNames), toQueryMarks(primaryKeys))
- values := toQueryValues(primaryKeys)
- if relation.PolymorphicType != "" {
- query += fmt.Sprintf(" AND %v = ?", scope.Quote(relation.PolymorphicDBName))
- values = append(values, relation.PolymorphicValue)
- }
-
- results := makeSlice(field.Struct.Type)
- scope.Err(preloadDB.Where(query, values...).Find(results, preloadConditions...).Error)
-
- // assign find results
- var (
- resultsValue = indirect(reflect.ValueOf(results))
- indirectScopeValue = scope.IndirectValue()
- )
-
- if indirectScopeValue.Kind() == reflect.Slice {
- foreignValuesToResults := make(map[string]reflect.Value)
- for i := 0; i < resultsValue.Len(); i++ {
- result := resultsValue.Index(i)
- foreignValues := toString(getValueFromFields(result, relation.ForeignFieldNames))
- foreignValuesToResults[foreignValues] = result
- }
- for j := 0; j < indirectScopeValue.Len(); j++ {
- indirectValue := indirect(indirectScopeValue.Index(j))
- valueString := toString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames))
- if result, found := foreignValuesToResults[valueString]; found {
- indirectValue.FieldByName(field.Name).Set(result)
- }
- }
- } else {
- for i := 0; i < resultsValue.Len(); i++ {
- result := resultsValue.Index(i)
- scope.Err(field.Set(result))
- }
- }
-}
-
-// handleHasManyPreload used to preload has many associations
-func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{}) {
- relation := field.Relationship
-
- // get relations's primary keys
- primaryKeys := scope.getColumnAsArray(relation.AssociationForeignFieldNames, scope.Value)
- if len(primaryKeys) == 0 {
- return
- }
-
- // preload conditions
- preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
-
- // find relations
- query := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relation.ForeignDBNames), toQueryMarks(primaryKeys))
- values := toQueryValues(primaryKeys)
- if relation.PolymorphicType != "" {
- query += fmt.Sprintf(" AND %v = ?", scope.Quote(relation.PolymorphicDBName))
- values = append(values, relation.PolymorphicValue)
- }
-
- results := makeSlice(field.Struct.Type)
- scope.Err(preloadDB.Where(query, values...).Find(results, preloadConditions...).Error)
-
- // assign find results
- var (
- resultsValue = indirect(reflect.ValueOf(results))
- indirectScopeValue = scope.IndirectValue()
- )
-
- if indirectScopeValue.Kind() == reflect.Slice {
- preloadMap := make(map[string][]reflect.Value)
- for i := 0; i < resultsValue.Len(); i++ {
- result := resultsValue.Index(i)
- foreignValues := getValueFromFields(result, relation.ForeignFieldNames)
- preloadMap[toString(foreignValues)] = append(preloadMap[toString(foreignValues)], result)
- }
-
- for j := 0; j < indirectScopeValue.Len(); j++ {
- object := indirect(indirectScopeValue.Index(j))
- objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames)
- f := object.FieldByName(field.Name)
- if results, ok := preloadMap[toString(objectRealValue)]; ok {
- f.Set(reflect.Append(f, results...))
- } else {
- f.Set(reflect.MakeSlice(f.Type(), 0, 0))
- }
- }
- } else {
- scope.Err(field.Set(resultsValue))
- }
-}
-
-// handleBelongsToPreload used to preload belongs to associations
-func (scope *Scope) handleBelongsToPreload(field *Field, conditions []interface{}) {
- relation := field.Relationship
-
- // preload conditions
- preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
-
- // get relations's primary keys
- primaryKeys := scope.getColumnAsArray(relation.ForeignFieldNames, scope.Value)
- if len(primaryKeys) == 0 {
- return
- }
-
- // find relations
- results := makeSlice(field.Struct.Type)
- scope.Err(preloadDB.Where(fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relation.AssociationForeignDBNames), toQueryMarks(primaryKeys)), toQueryValues(primaryKeys)...).Find(results, preloadConditions...).Error)
-
- // assign find results
- var (
- resultsValue = indirect(reflect.ValueOf(results))
- indirectScopeValue = scope.IndirectValue()
- )
-
- foreignFieldToObjects := make(map[string][]*reflect.Value)
- if indirectScopeValue.Kind() == reflect.Slice {
- for j := 0; j < indirectScopeValue.Len(); j++ {
- object := indirect(indirectScopeValue.Index(j))
- valueString := toString(getValueFromFields(object, relation.ForeignFieldNames))
- foreignFieldToObjects[valueString] = append(foreignFieldToObjects[valueString], &object)
- }
- }
-
- for i := 0; i < resultsValue.Len(); i++ {
- result := resultsValue.Index(i)
- if indirectScopeValue.Kind() == reflect.Slice {
- valueString := toString(getValueFromFields(result, relation.AssociationForeignFieldNames))
- if objects, found := foreignFieldToObjects[valueString]; found {
- for _, object := range objects {
- object.FieldByName(field.Name).Set(result)
- }
- }
- } else {
- scope.Err(field.Set(result))
- }
- }
-}
-
-// handleManyToManyPreload used to preload many to many associations
-func (scope *Scope) handleManyToManyPreload(field *Field, conditions []interface{}) {
- var (
- relation = field.Relationship
- joinTableHandler = relation.JoinTableHandler
- fieldType = field.Struct.Type.Elem()
- foreignKeyValue interface{}
- foreignKeyType = reflect.ValueOf(&foreignKeyValue).Type()
- linkHash = map[string][]reflect.Value{}
- isPtr bool
- )
-
- if fieldType.Kind() == reflect.Ptr {
- isPtr = true
- fieldType = fieldType.Elem()
- }
-
- var sourceKeys = []string{}
- for _, key := range joinTableHandler.SourceForeignKeys() {
- sourceKeys = append(sourceKeys, key.DBName)
- }
-
- // preload conditions
- preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
-
- // generate query with join table
- newScope := scope.New(reflect.New(fieldType).Interface())
- preloadDB = preloadDB.Table(newScope.TableName()).Model(newScope.Value)
-
- if len(preloadDB.search.selects) == 0 {
- preloadDB = preloadDB.Select("*")
- }
-
- preloadDB = joinTableHandler.JoinWith(joinTableHandler, preloadDB, scope.Value)
-
- // preload inline conditions
- if len(preloadConditions) > 0 {
- preloadDB = preloadDB.Where(preloadConditions[0], preloadConditions[1:]...)
- }
-
- rows, err := preloadDB.Rows()
-
- if scope.Err(err) != nil {
- return
- }
- defer rows.Close()
-
- columns, _ := rows.Columns()
- for rows.Next() {
- var (
- elem = reflect.New(fieldType).Elem()
- fields = scope.New(elem.Addr().Interface()).Fields()
- )
-
- // register foreign keys in join tables
- var joinTableFields []*Field
- for _, sourceKey := range sourceKeys {
- joinTableFields = append(joinTableFields, &Field{StructField: &StructField{DBName: sourceKey, IsNormal: true}, Field: reflect.New(foreignKeyType).Elem()})
- }
-
- scope.scan(rows, columns, append(fields, joinTableFields...))
-
- scope.New(elem.Addr().Interface()).
- InstanceSet("gorm:skip_query_callback", true).
- callCallbacks(scope.db.parent.callbacks.queries)
-
- var foreignKeys = make([]interface{}, len(sourceKeys))
- // generate hashed forkey keys in join table
- for idx, joinTableField := range joinTableFields {
- if !joinTableField.Field.IsNil() {
- foreignKeys[idx] = joinTableField.Field.Elem().Interface()
- }
- }
- hashedSourceKeys := toString(foreignKeys)
-
- if isPtr {
- linkHash[hashedSourceKeys] = append(linkHash[hashedSourceKeys], elem.Addr())
- } else {
- linkHash[hashedSourceKeys] = append(linkHash[hashedSourceKeys], elem)
- }
- }
-
- if err := rows.Err(); err != nil {
- scope.Err(err)
- }
-
- // assign find results
- var (
- indirectScopeValue = scope.IndirectValue()
- fieldsSourceMap = map[string][]reflect.Value{}
- foreignFieldNames = []string{}
- )
-
- for _, dbName := range relation.ForeignFieldNames {
- if field, ok := scope.FieldByName(dbName); ok {
- foreignFieldNames = append(foreignFieldNames, field.Name)
- }
- }
-
- if indirectScopeValue.Kind() == reflect.Slice {
- for j := 0; j < indirectScopeValue.Len(); j++ {
- object := indirect(indirectScopeValue.Index(j))
- key := toString(getValueFromFields(object, foreignFieldNames))
- fieldsSourceMap[key] = append(fieldsSourceMap[key], object.FieldByName(field.Name))
- }
- } else if indirectScopeValue.IsValid() {
- key := toString(getValueFromFields(indirectScopeValue, foreignFieldNames))
- fieldsSourceMap[key] = append(fieldsSourceMap[key], indirectScopeValue.FieldByName(field.Name))
- }
-
- for source, fields := range fieldsSourceMap {
- for _, f := range fields {
- //If not 0 this means Value is a pointer and we already added preloaded models to it
- if f.Len() != 0 {
- continue
- }
-
- v := reflect.MakeSlice(f.Type(), 0, 0)
- if len(linkHash[source]) > 0 {
- v = reflect.Append(f, linkHash[source]...)
- }
-
- f.Set(v)
- }
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_row_query.go b/vendor/github.com/jinzhu/gorm/callback_row_query.go
deleted file mode 100644
index 323b160..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_row_query.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package gorm
-
-import (
- "database/sql"
- "fmt"
-)
-
-// Define callbacks for row query
-func init() {
- DefaultCallback.RowQuery().Register("gorm:row_query", rowQueryCallback)
-}
-
-type RowQueryResult struct {
- Row *sql.Row
-}
-
-type RowsQueryResult struct {
- Rows *sql.Rows
- Error error
-}
-
-// queryCallback used to query data from database
-func rowQueryCallback(scope *Scope) {
- if result, ok := scope.InstanceGet("row_query_result"); ok {
- scope.prepareQuerySQL()
-
- if str, ok := scope.Get("gorm:query_hint"); ok {
- scope.SQL = fmt.Sprint(str) + scope.SQL
- }
-
- if str, ok := scope.Get("gorm:query_option"); ok {
- scope.SQL += addExtraSpaceIfExist(fmt.Sprint(str))
- }
-
- if rowResult, ok := result.(*RowQueryResult); ok {
- rowResult.Row = scope.SQLDB().QueryRow(scope.SQL, scope.SQLVars...)
- } else if rowsResult, ok := result.(*RowsQueryResult); ok {
- rowsResult.Rows, rowsResult.Error = scope.SQLDB().Query(scope.SQL, scope.SQLVars...)
- }
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_save.go b/vendor/github.com/jinzhu/gorm/callback_save.go
deleted file mode 100644
index 3b4e058..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_save.go
+++ /dev/null
@@ -1,170 +0,0 @@
-package gorm
-
-import (
- "reflect"
- "strings"
-)
-
-func beginTransactionCallback(scope *Scope) {
- scope.Begin()
-}
-
-func commitOrRollbackTransactionCallback(scope *Scope) {
- scope.CommitOrRollback()
-}
-
-func saveAssociationCheck(scope *Scope, field *Field) (autoUpdate bool, autoCreate bool, saveReference bool, r *Relationship) {
- checkTruth := func(value interface{}) bool {
- if v, ok := value.(bool); ok && !v {
- return false
- }
-
- if v, ok := value.(string); ok {
- v = strings.ToLower(v)
- return v == "true"
- }
-
- return true
- }
-
- if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
- if r = field.Relationship; r != nil {
- autoUpdate, autoCreate, saveReference = true, true, true
-
- if value, ok := scope.Get("gorm:save_associations"); ok {
- autoUpdate = checkTruth(value)
- autoCreate = autoUpdate
- saveReference = autoUpdate
- } else if value, ok := field.TagSettingsGet("SAVE_ASSOCIATIONS"); ok {
- autoUpdate = checkTruth(value)
- autoCreate = autoUpdate
- saveReference = autoUpdate
- }
-
- if value, ok := scope.Get("gorm:association_autoupdate"); ok {
- autoUpdate = checkTruth(value)
- } else if value, ok := field.TagSettingsGet("ASSOCIATION_AUTOUPDATE"); ok {
- autoUpdate = checkTruth(value)
- }
-
- if value, ok := scope.Get("gorm:association_autocreate"); ok {
- autoCreate = checkTruth(value)
- } else if value, ok := field.TagSettingsGet("ASSOCIATION_AUTOCREATE"); ok {
- autoCreate = checkTruth(value)
- }
-
- if value, ok := scope.Get("gorm:association_save_reference"); ok {
- saveReference = checkTruth(value)
- } else if value, ok := field.TagSettingsGet("ASSOCIATION_SAVE_REFERENCE"); ok {
- saveReference = checkTruth(value)
- }
- }
- }
-
- return
-}
-
-func saveBeforeAssociationsCallback(scope *Scope) {
- for _, field := range scope.Fields() {
- autoUpdate, autoCreate, saveReference, relationship := saveAssociationCheck(scope, field)
-
- if relationship != nil && relationship.Kind == "belongs_to" {
- fieldValue := field.Field.Addr().Interface()
- newScope := scope.New(fieldValue)
-
- if newScope.PrimaryKeyZero() {
- if autoCreate {
- scope.Err(scope.NewDB().Save(fieldValue).Error)
- }
- } else if autoUpdate {
- scope.Err(scope.NewDB().Save(fieldValue).Error)
- }
-
- if saveReference {
- if len(relationship.ForeignFieldNames) != 0 {
- // set value's foreign key
- for idx, fieldName := range relationship.ForeignFieldNames {
- associationForeignName := relationship.AssociationForeignDBNames[idx]
- if foreignField, ok := scope.New(fieldValue).FieldByName(associationForeignName); ok {
- scope.Err(scope.SetColumn(fieldName, foreignField.Field.Interface()))
- }
- }
- }
- }
- }
- }
-}
-
-func saveAfterAssociationsCallback(scope *Scope) {
- for _, field := range scope.Fields() {
- autoUpdate, autoCreate, saveReference, relationship := saveAssociationCheck(scope, field)
-
- if relationship != nil && (relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") {
- value := field.Field
-
- switch value.Kind() {
- case reflect.Slice:
- for i := 0; i < value.Len(); i++ {
- newDB := scope.NewDB()
- elem := value.Index(i).Addr().Interface()
- newScope := newDB.NewScope(elem)
-
- if saveReference {
- if relationship.JoinTableHandler == nil && len(relationship.ForeignFieldNames) != 0 {
- for idx, fieldName := range relationship.ForeignFieldNames {
- associationForeignName := relationship.AssociationForeignDBNames[idx]
- if f, ok := scope.FieldByName(associationForeignName); ok {
- scope.Err(newScope.SetColumn(fieldName, f.Field.Interface()))
- }
- }
- }
-
- if relationship.PolymorphicType != "" {
- scope.Err(newScope.SetColumn(relationship.PolymorphicType, relationship.PolymorphicValue))
- }
- }
-
- if newScope.PrimaryKeyZero() {
- if autoCreate {
- scope.Err(newDB.Save(elem).Error)
- }
- } else if autoUpdate {
- scope.Err(newDB.Save(elem).Error)
- }
-
- if !scope.New(newScope.Value).PrimaryKeyZero() && saveReference {
- if joinTableHandler := relationship.JoinTableHandler; joinTableHandler != nil {
- scope.Err(joinTableHandler.Add(joinTableHandler, newDB, scope.Value, newScope.Value))
- }
- }
- }
- default:
- elem := value.Addr().Interface()
- newScope := scope.New(elem)
-
- if saveReference {
- if len(relationship.ForeignFieldNames) != 0 {
- for idx, fieldName := range relationship.ForeignFieldNames {
- associationForeignName := relationship.AssociationForeignDBNames[idx]
- if f, ok := scope.FieldByName(associationForeignName); ok {
- scope.Err(newScope.SetColumn(fieldName, f.Field.Interface()))
- }
- }
- }
-
- if relationship.PolymorphicType != "" {
- scope.Err(newScope.SetColumn(relationship.PolymorphicType, relationship.PolymorphicValue))
- }
- }
-
- if newScope.PrimaryKeyZero() {
- if autoCreate {
- scope.Err(scope.NewDB().Save(elem).Error)
- }
- } else if autoUpdate {
- scope.Err(scope.NewDB().Save(elem).Error)
- }
- }
- }
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/callback_update.go b/vendor/github.com/jinzhu/gorm/callback_update.go
deleted file mode 100644
index 699e534..0000000
--- a/vendor/github.com/jinzhu/gorm/callback_update.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package gorm
-
-import (
- "errors"
- "fmt"
- "sort"
- "strings"
-)
-
-// Define callbacks for updating
-func init() {
- DefaultCallback.Update().Register("gorm:assign_updating_attributes", assignUpdatingAttributesCallback)
- DefaultCallback.Update().Register("gorm:begin_transaction", beginTransactionCallback)
- DefaultCallback.Update().Register("gorm:before_update", beforeUpdateCallback)
- DefaultCallback.Update().Register("gorm:save_before_associations", saveBeforeAssociationsCallback)
- DefaultCallback.Update().Register("gorm:update_time_stamp", updateTimeStampForUpdateCallback)
- DefaultCallback.Update().Register("gorm:update", updateCallback)
- DefaultCallback.Update().Register("gorm:save_after_associations", saveAfterAssociationsCallback)
- DefaultCallback.Update().Register("gorm:after_update", afterUpdateCallback)
- DefaultCallback.Update().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
-}
-
-// assignUpdatingAttributesCallback assign updating attributes to model
-func assignUpdatingAttributesCallback(scope *Scope) {
- if attrs, ok := scope.InstanceGet("gorm:update_interface"); ok {
- if updateMaps, hasUpdate := scope.updatedAttrsWithValues(attrs); hasUpdate {
- scope.InstanceSet("gorm:update_attrs", updateMaps)
- } else {
- scope.SkipLeft()
- }
- }
-}
-
-// beforeUpdateCallback will invoke `BeforeSave`, `BeforeUpdate` method before updating
-func beforeUpdateCallback(scope *Scope) {
- if scope.DB().HasBlockGlobalUpdate() && !scope.hasConditions() {
- scope.Err(errors.New("missing WHERE clause while updating"))
- return
- }
- if _, ok := scope.Get("gorm:update_column"); !ok {
- if !scope.HasError() {
- scope.CallMethod("BeforeSave")
- }
- if !scope.HasError() {
- scope.CallMethod("BeforeUpdate")
- }
- }
-}
-
-// updateTimeStampForUpdateCallback will set `UpdatedAt` when updating
-func updateTimeStampForUpdateCallback(scope *Scope) {
- if _, ok := scope.Get("gorm:update_column"); !ok {
- scope.SetColumn("UpdatedAt", scope.db.nowFunc())
- }
-}
-
-// updateCallback the callback used to update data to database
-func updateCallback(scope *Scope) {
- if !scope.HasError() {
- var sqls []string
-
- if updateAttrs, ok := scope.InstanceGet("gorm:update_attrs"); ok {
- // Sort the column names so that the generated SQL is the same every time.
- updateMap := updateAttrs.(map[string]interface{})
- var columns []string
- for c := range updateMap {
- columns = append(columns, c)
- }
- sort.Strings(columns)
-
- for _, column := range columns {
- value := updateMap[column]
- sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(column), scope.AddToVars(value)))
- }
- } else {
- for _, field := range scope.Fields() {
- if scope.changeableField(field) {
- if !field.IsPrimaryKey && field.IsNormal && (field.Name != "CreatedAt" || !field.IsBlank) {
- if !field.IsForeignKey || !field.IsBlank || !field.HasDefaultValue {
- sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface())))
- }
- } else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
- for _, foreignKey := range relationship.ForeignDBNames {
- if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) {
- sqls = append(sqls,
- fmt.Sprintf("%v = %v", scope.Quote(foreignField.DBName), scope.AddToVars(foreignField.Field.Interface())))
- }
- }
- }
- }
- }
- }
-
- var extraOption string
- if str, ok := scope.Get("gorm:update_option"); ok {
- extraOption = fmt.Sprint(str)
- }
-
- if len(sqls) > 0 {
- scope.Raw(fmt.Sprintf(
- "UPDATE %v SET %v%v%v",
- scope.QuotedTableName(),
- strings.Join(sqls, ", "),
- addExtraSpaceIfExist(scope.CombinedConditionSql()),
- addExtraSpaceIfExist(extraOption),
- )).Exec()
- }
- }
-}
-
-// afterUpdateCallback will invoke `AfterUpdate`, `AfterSave` method after updating
-func afterUpdateCallback(scope *Scope) {
- if _, ok := scope.Get("gorm:update_column"); !ok {
- if !scope.HasError() {
- scope.CallMethod("AfterUpdate")
- }
- if !scope.HasError() {
- scope.CallMethod("AfterSave")
- }
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/dialect.go b/vendor/github.com/jinzhu/gorm/dialect.go
deleted file mode 100644
index 749587f..0000000
--- a/vendor/github.com/jinzhu/gorm/dialect.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package gorm
-
-import (
- "database/sql"
- "fmt"
- "reflect"
- "strconv"
- "strings"
-)
-
-// Dialect interface contains behaviors that differ across SQL database
-type Dialect interface {
- // GetName get dialect's name
- GetName() string
-
- // SetDB set db for dialect
- SetDB(db SQLCommon)
-
- // BindVar return the placeholder for actual values in SQL statements, in many dbs it is "?", Postgres using $1
- BindVar(i int) string
- // Quote quotes field name to avoid SQL parsing exceptions by using a reserved word as a field name
- Quote(key string) string
- // DataTypeOf return data's sql type
- DataTypeOf(field *StructField) string
-
- // HasIndex check has index or not
- HasIndex(tableName string, indexName string) bool
- // HasForeignKey check has foreign key or not
- HasForeignKey(tableName string, foreignKeyName string) bool
- // RemoveIndex remove index
- RemoveIndex(tableName string, indexName string) error
- // HasTable check has table or not
- HasTable(tableName string) bool
- // HasColumn check has column or not
- HasColumn(tableName string, columnName string) bool
- // ModifyColumn modify column's type
- ModifyColumn(tableName string, columnName string, typ string) error
-
- // LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case
- LimitAndOffsetSQL(limit, offset interface{}) (string, error)
- // SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
- SelectFromDummyTable() string
- // LastInsertIDOutputInterstitial most dbs support LastInsertId, but mssql needs to use `OUTPUT`
- LastInsertIDOutputInterstitial(tableName, columnName string, columns []string) string
- // LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING`
- LastInsertIDReturningSuffix(tableName, columnName string) string
- // DefaultValueStr
- DefaultValueStr() string
-
- // BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference
- BuildKeyName(kind, tableName string, fields ...string) string
-
- // NormalizeIndexAndColumn returns valid index name and column name depending on each dialect
- NormalizeIndexAndColumn(indexName, columnName string) (string, string)
-
- // CurrentDatabase return current database name
- CurrentDatabase() string
-}
-
-var dialectsMap = map[string]Dialect{}
-
-func newDialect(name string, db SQLCommon) Dialect {
- if value, ok := dialectsMap[name]; ok {
- dialect := reflect.New(reflect.TypeOf(value).Elem()).Interface().(Dialect)
- dialect.SetDB(db)
- return dialect
- }
-
- fmt.Printf("`%v` is not officially supported, running under compatibility mode.\n", name)
- commontDialect := &commonDialect{}
- commontDialect.SetDB(db)
- return commontDialect
-}
-
-// RegisterDialect register new dialect
-func RegisterDialect(name string, dialect Dialect) {
- dialectsMap[name] = dialect
-}
-
-// GetDialect gets the dialect for the specified dialect name
-func GetDialect(name string) (dialect Dialect, ok bool) {
- dialect, ok = dialectsMap[name]
- return
-}
-
-// ParseFieldStructForDialect get field's sql data type
-var ParseFieldStructForDialect = func(field *StructField, dialect Dialect) (fieldValue reflect.Value, sqlType string, size int, additionalType string) {
- // Get redirected field type
- var (
- reflectType = field.Struct.Type
- dataType, _ = field.TagSettingsGet("TYPE")
- )
-
- for reflectType.Kind() == reflect.Ptr {
- reflectType = reflectType.Elem()
- }
-
- // Get redirected field value
- fieldValue = reflect.Indirect(reflect.New(reflectType))
-
- if gormDataType, ok := fieldValue.Interface().(interface {
- GormDataType(Dialect) string
- }); ok {
- dataType = gormDataType.GormDataType(dialect)
- }
-
- // Get scanner's real value
- if dataType == "" {
- var getScannerValue func(reflect.Value)
- getScannerValue = func(value reflect.Value) {
- fieldValue = value
- if _, isScanner := reflect.New(fieldValue.Type()).Interface().(sql.Scanner); isScanner && fieldValue.Kind() == reflect.Struct {
- getScannerValue(fieldValue.Field(0))
- }
- }
- getScannerValue(fieldValue)
- }
-
- // Default Size
- if num, ok := field.TagSettingsGet("SIZE"); ok {
- size, _ = strconv.Atoi(num)
- } else {
- size = 255
- }
-
- // Default type from tag setting
- notNull, _ := field.TagSettingsGet("NOT NULL")
- unique, _ := field.TagSettingsGet("UNIQUE")
- additionalType = notNull + " " + unique
- if value, ok := field.TagSettingsGet("DEFAULT"); ok {
- additionalType = additionalType + " DEFAULT " + value
- }
-
- if value, ok := field.TagSettingsGet("COMMENT"); ok {
- additionalType = additionalType + " COMMENT " + value
- }
-
- return fieldValue, dataType, size, strings.TrimSpace(additionalType)
-}
-
-func currentDatabaseAndTable(dialect Dialect, tableName string) (string, string) {
- if strings.Contains(tableName, ".") {
- splitStrings := strings.SplitN(tableName, ".", 2)
- return splitStrings[0], splitStrings[1]
- }
- return dialect.CurrentDatabase(), tableName
-}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_common.go b/vendor/github.com/jinzhu/gorm/dialect_common.go
deleted file mode 100644
index d549510..0000000
--- a/vendor/github.com/jinzhu/gorm/dialect_common.go
+++ /dev/null
@@ -1,196 +0,0 @@
-package gorm
-
-import (
- "fmt"
- "reflect"
- "regexp"
- "strconv"
- "strings"
- "time"
-)
-
-var keyNameRegex = regexp.MustCompile("[^a-zA-Z0-9]+")
-
-// DefaultForeignKeyNamer contains the default foreign key name generator method
-type DefaultForeignKeyNamer struct {
-}
-
-type commonDialect struct {
- db SQLCommon
- DefaultForeignKeyNamer
-}
-
-func init() {
- RegisterDialect("common", &commonDialect{})
-}
-
-func (commonDialect) GetName() string {
- return "common"
-}
-
-func (s *commonDialect) SetDB(db SQLCommon) {
- s.db = db
-}
-
-func (commonDialect) BindVar(i int) string {
- return "$$$" // ?
-}
-
-func (commonDialect) Quote(key string) string {
- return fmt.Sprintf(`"%s"`, key)
-}
-
-func (s *commonDialect) fieldCanAutoIncrement(field *StructField) bool {
- if value, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok {
- return strings.ToLower(value) != "false"
- }
- return field.IsPrimaryKey
-}
-
-func (s *commonDialect) DataTypeOf(field *StructField) string {
- var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
-
- if sqlType == "" {
- switch dataValue.Kind() {
- case reflect.Bool:
- sqlType = "BOOLEAN"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
- if s.fieldCanAutoIncrement(field) {
- sqlType = "INTEGER AUTO_INCREMENT"
- } else {
- sqlType = "INTEGER"
- }
- case reflect.Int64, reflect.Uint64:
- if s.fieldCanAutoIncrement(field) {
- sqlType = "BIGINT AUTO_INCREMENT"
- } else {
- sqlType = "BIGINT"
- }
- case reflect.Float32, reflect.Float64:
- sqlType = "FLOAT"
- case reflect.String:
- if size > 0 && size < 65532 {
- sqlType = fmt.Sprintf("VARCHAR(%d)", size)
- } else {
- sqlType = "VARCHAR(65532)"
- }
- case reflect.Struct:
- if _, ok := dataValue.Interface().(time.Time); ok {
- sqlType = "TIMESTAMP"
- }
- default:
- if _, ok := dataValue.Interface().([]byte); ok {
- if size > 0 && size < 65532 {
- sqlType = fmt.Sprintf("BINARY(%d)", size)
- } else {
- sqlType = "BINARY(65532)"
- }
- }
- }
- }
-
- if sqlType == "" {
- panic(fmt.Sprintf("invalid sql type %s (%s) for commonDialect", dataValue.Type().Name(), dataValue.Kind().String()))
- }
-
- if strings.TrimSpace(additionalType) == "" {
- return sqlType
- }
- return fmt.Sprintf("%v %v", sqlType, additionalType)
-}
-
-func (s commonDialect) HasIndex(tableName string, indexName string) bool {
- var count int
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = ? AND table_name = ? AND index_name = ?", currentDatabase, tableName, indexName).Scan(&count)
- return count > 0
-}
-
-func (s commonDialect) RemoveIndex(tableName string, indexName string) error {
- _, err := s.db.Exec(fmt.Sprintf("DROP INDEX %v", indexName))
- return err
-}
-
-func (s commonDialect) HasForeignKey(tableName string, foreignKeyName string) bool {
- return false
-}
-
-func (s commonDialect) HasTable(tableName string) bool {
- var count int
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?", currentDatabase, tableName).Scan(&count)
- return count > 0
-}
-
-func (s commonDialect) HasColumn(tableName string, columnName string) bool {
- var count int
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = ? AND table_name = ? AND column_name = ?", currentDatabase, tableName, columnName).Scan(&count)
- return count > 0
-}
-
-func (s commonDialect) ModifyColumn(tableName string, columnName string, typ string) error {
- _, err := s.db.Exec(fmt.Sprintf("ALTER TABLE %v ALTER COLUMN %v TYPE %v", tableName, columnName, typ))
- return err
-}
-
-func (s commonDialect) CurrentDatabase() (name string) {
- s.db.QueryRow("SELECT DATABASE()").Scan(&name)
- return
-}
-
-// LimitAndOffsetSQL return generated SQL with Limit and Offset
-func (s commonDialect) LimitAndOffsetSQL(limit, offset interface{}) (sql string, err error) {
- if limit != nil {
- if parsedLimit, err := s.parseInt(limit); err != nil {
- return "", err
- } else if parsedLimit >= 0 {
- sql += fmt.Sprintf(" LIMIT %d", parsedLimit)
- }
- }
- if offset != nil {
- if parsedOffset, err := s.parseInt(offset); err != nil {
- return "", err
- } else if parsedOffset >= 0 {
- sql += fmt.Sprintf(" OFFSET %d", parsedOffset)
- }
- }
- return
-}
-
-func (commonDialect) SelectFromDummyTable() string {
- return ""
-}
-
-func (commonDialect) LastInsertIDOutputInterstitial(tableName, columnName string, columns []string) string {
- return ""
-}
-
-func (commonDialect) LastInsertIDReturningSuffix(tableName, columnName string) string {
- return ""
-}
-
-func (commonDialect) DefaultValueStr() string {
- return "DEFAULT VALUES"
-}
-
-// BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference
-func (DefaultForeignKeyNamer) BuildKeyName(kind, tableName string, fields ...string) string {
- keyName := fmt.Sprintf("%s_%s_%s", kind, tableName, strings.Join(fields, "_"))
- keyName = keyNameRegex.ReplaceAllString(keyName, "_")
- return keyName
-}
-
-// NormalizeIndexAndColumn returns argument's index name and column name without doing anything
-func (commonDialect) NormalizeIndexAndColumn(indexName, columnName string) (string, string) {
- return indexName, columnName
-}
-
-func (commonDialect) parseInt(value interface{}) (int64, error) {
- return strconv.ParseInt(fmt.Sprint(value), 0, 0)
-}
-
-// IsByteArrayOrSlice returns true of the reflected value is an array or slice
-func IsByteArrayOrSlice(value reflect.Value) bool {
- return (value.Kind() == reflect.Array || value.Kind() == reflect.Slice) && value.Type().Elem() == reflect.TypeOf(uint8(0))
-}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_mysql.go b/vendor/github.com/jinzhu/gorm/dialect_mysql.go
deleted file mode 100644
index b4467ff..0000000
--- a/vendor/github.com/jinzhu/gorm/dialect_mysql.go
+++ /dev/null
@@ -1,246 +0,0 @@
-package gorm
-
-import (
- "crypto/sha1"
- "database/sql"
- "fmt"
- "reflect"
- "regexp"
- "strings"
- "time"
- "unicode/utf8"
-)
-
-var mysqlIndexRegex = regexp.MustCompile(`^(.+)\((\d+)\)$`)
-
-type mysql struct {
- commonDialect
-}
-
-func init() {
- RegisterDialect("mysql", &mysql{})
-}
-
-func (mysql) GetName() string {
- return "mysql"
-}
-
-func (mysql) Quote(key string) string {
- return fmt.Sprintf("`%s`", key)
-}
-
-// Get Data Type for MySQL Dialect
-func (s *mysql) DataTypeOf(field *StructField) string {
- var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
-
- // MySQL allows only one auto increment column per table, and it must
- // be a KEY column.
- if _, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok {
- if _, ok = field.TagSettingsGet("INDEX"); !ok && !field.IsPrimaryKey {
- field.TagSettingsDelete("AUTO_INCREMENT")
- }
- }
-
- if sqlType == "" {
- switch dataValue.Kind() {
- case reflect.Bool:
- sqlType = "boolean"
- case reflect.Int8:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "tinyint AUTO_INCREMENT"
- } else {
- sqlType = "tinyint"
- }
- case reflect.Int, reflect.Int16, reflect.Int32:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "int AUTO_INCREMENT"
- } else {
- sqlType = "int"
- }
- case reflect.Uint8:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "tinyint unsigned AUTO_INCREMENT"
- } else {
- sqlType = "tinyint unsigned"
- }
- case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "int unsigned AUTO_INCREMENT"
- } else {
- sqlType = "int unsigned"
- }
- case reflect.Int64:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "bigint AUTO_INCREMENT"
- } else {
- sqlType = "bigint"
- }
- case reflect.Uint64:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "bigint unsigned AUTO_INCREMENT"
- } else {
- sqlType = "bigint unsigned"
- }
- case reflect.Float32, reflect.Float64:
- sqlType = "double"
- case reflect.String:
- if size > 0 && size < 65532 {
- sqlType = fmt.Sprintf("varchar(%d)", size)
- } else {
- sqlType = "longtext"
- }
- case reflect.Struct:
- if _, ok := dataValue.Interface().(time.Time); ok {
- precision := ""
- if p, ok := field.TagSettingsGet("PRECISION"); ok {
- precision = fmt.Sprintf("(%s)", p)
- }
-
- if _, ok := field.TagSettings["NOT NULL"]; ok || field.IsPrimaryKey {
- sqlType = fmt.Sprintf("DATETIME%v", precision)
- } else {
- sqlType = fmt.Sprintf("DATETIME%v NULL", precision)
- }
- }
- default:
- if IsByteArrayOrSlice(dataValue) {
- if size > 0 && size < 65532 {
- sqlType = fmt.Sprintf("varbinary(%d)", size)
- } else {
- sqlType = "longblob"
- }
- }
- }
- }
-
- if sqlType == "" {
- panic(fmt.Sprintf("invalid sql type %s (%s) in field %s for mysql", dataValue.Type().Name(), dataValue.Kind().String(), field.Name))
- }
-
- if strings.TrimSpace(additionalType) == "" {
- return sqlType
- }
- return fmt.Sprintf("%v %v", sqlType, additionalType)
-}
-
-func (s mysql) RemoveIndex(tableName string, indexName string) error {
- _, err := s.db.Exec(fmt.Sprintf("DROP INDEX %v ON %v", indexName, s.Quote(tableName)))
- return err
-}
-
-func (s mysql) ModifyColumn(tableName string, columnName string, typ string) error {
- _, err := s.db.Exec(fmt.Sprintf("ALTER TABLE %v MODIFY COLUMN %v %v", tableName, columnName, typ))
- return err
-}
-
-func (s mysql) LimitAndOffsetSQL(limit, offset interface{}) (sql string, err error) {
- if limit != nil {
- parsedLimit, err := s.parseInt(limit)
- if err != nil {
- return "", err
- }
- if parsedLimit >= 0 {
- sql += fmt.Sprintf(" LIMIT %d", parsedLimit)
-
- if offset != nil {
- parsedOffset, err := s.parseInt(offset)
- if err != nil {
- return "", err
- }
- if parsedOffset >= 0 {
- sql += fmt.Sprintf(" OFFSET %d", parsedOffset)
- }
- }
- }
- }
- return
-}
-
-func (s mysql) HasForeignKey(tableName string, foreignKeyName string) bool {
- var count int
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA=? AND TABLE_NAME=? AND CONSTRAINT_NAME=? AND CONSTRAINT_TYPE='FOREIGN KEY'", currentDatabase, tableName, foreignKeyName).Scan(&count)
- return count > 0
-}
-
-func (s mysql) HasTable(tableName string) bool {
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- var name string
- // allow mysql database name with '-' character
- if err := s.db.QueryRow(fmt.Sprintf("SHOW TABLES FROM `%s` WHERE `Tables_in_%s` = ?", currentDatabase, currentDatabase), tableName).Scan(&name); err != nil {
- if err == sql.ErrNoRows {
- return false
- }
- panic(err)
- } else {
- return true
- }
-}
-
-func (s mysql) HasIndex(tableName string, indexName string) bool {
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- if rows, err := s.db.Query(fmt.Sprintf("SHOW INDEXES FROM `%s` FROM `%s` WHERE Key_name = ?", tableName, currentDatabase), indexName); err != nil {
- panic(err)
- } else {
- defer rows.Close()
- return rows.Next()
- }
-}
-
-func (s mysql) HasColumn(tableName string, columnName string) bool {
- currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
- if rows, err := s.db.Query(fmt.Sprintf("SHOW COLUMNS FROM `%s` FROM `%s` WHERE Field = ?", tableName, currentDatabase), columnName); err != nil {
- panic(err)
- } else {
- defer rows.Close()
- return rows.Next()
- }
-}
-
-func (s mysql) CurrentDatabase() (name string) {
- s.db.QueryRow("SELECT DATABASE()").Scan(&name)
- return
-}
-
-func (mysql) SelectFromDummyTable() string {
- return "FROM DUAL"
-}
-
-func (s mysql) BuildKeyName(kind, tableName string, fields ...string) string {
- keyName := s.commonDialect.BuildKeyName(kind, tableName, fields...)
- if utf8.RuneCountInString(keyName) <= 64 {
- return keyName
- }
- h := sha1.New()
- h.Write([]byte(keyName))
- bs := h.Sum(nil)
-
- // sha1 is 40 characters, keep first 24 characters of destination
- destRunes := []rune(keyNameRegex.ReplaceAllString(fields[0], "_"))
- if len(destRunes) > 24 {
- destRunes = destRunes[:24]
- }
-
- return fmt.Sprintf("%s%x", string(destRunes), bs)
-}
-
-// NormalizeIndexAndColumn returns index name and column name for specify an index prefix length if needed
-func (mysql) NormalizeIndexAndColumn(indexName, columnName string) (string, string) {
- submatch := mysqlIndexRegex.FindStringSubmatch(indexName)
- if len(submatch) != 3 {
- return indexName, columnName
- }
- indexName = submatch[1]
- columnName = fmt.Sprintf("%s(%s)", columnName, submatch[2])
- return indexName, columnName
-}
-
-func (mysql) DefaultValueStr() string {
- return "VALUES()"
-}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_postgres.go b/vendor/github.com/jinzhu/gorm/dialect_postgres.go
deleted file mode 100644
index d2df313..0000000
--- a/vendor/github.com/jinzhu/gorm/dialect_postgres.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package gorm
-
-import (
- "encoding/json"
- "fmt"
- "reflect"
- "strings"
- "time"
-)
-
-type postgres struct {
- commonDialect
-}
-
-func init() {
- RegisterDialect("postgres", &postgres{})
- RegisterDialect("cloudsqlpostgres", &postgres{})
-}
-
-func (postgres) GetName() string {
- return "postgres"
-}
-
-func (postgres) BindVar(i int) string {
- return fmt.Sprintf("$%v", i)
-}
-
-func (s *postgres) DataTypeOf(field *StructField) string {
- var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
-
- if sqlType == "" {
- switch dataValue.Kind() {
- case reflect.Bool:
- sqlType = "boolean"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uintptr:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "serial"
- } else {
- sqlType = "integer"
- }
- case reflect.Int64, reflect.Uint32, reflect.Uint64:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "bigserial"
- } else {
- sqlType = "bigint"
- }
- case reflect.Float32, reflect.Float64:
- sqlType = "numeric"
- case reflect.String:
- if _, ok := field.TagSettingsGet("SIZE"); !ok {
- size = 0 // if SIZE haven't been set, use `text` as the default type, as there are no performance different
- }
-
- if size > 0 && size < 65532 {
- sqlType = fmt.Sprintf("varchar(%d)", size)
- } else {
- sqlType = "text"
- }
- case reflect.Struct:
- if _, ok := dataValue.Interface().(time.Time); ok {
- sqlType = "timestamp with time zone"
- }
- case reflect.Map:
- if dataValue.Type().Name() == "Hstore" {
- sqlType = "hstore"
- }
- default:
- if IsByteArrayOrSlice(dataValue) {
- sqlType = "bytea"
-
- if isUUID(dataValue) {
- sqlType = "uuid"
- }
-
- if isJSON(dataValue) {
- sqlType = "jsonb"
- }
- }
- }
- }
-
- if sqlType == "" {
- panic(fmt.Sprintf("invalid sql type %s (%s) for postgres", dataValue.Type().Name(), dataValue.Kind().String()))
- }
-
- if strings.TrimSpace(additionalType) == "" {
- return sqlType
- }
- return fmt.Sprintf("%v %v", sqlType, additionalType)
-}
-
-func (s postgres) HasIndex(tableName string, indexName string) bool {
- var count int
- s.db.QueryRow("SELECT count(*) FROM pg_indexes WHERE tablename = $1 AND indexname = $2 AND schemaname = CURRENT_SCHEMA()", tableName, indexName).Scan(&count)
- return count > 0
-}
-
-func (s postgres) HasForeignKey(tableName string, foreignKeyName string) bool {
- var count int
- s.db.QueryRow("SELECT count(con.conname) FROM pg_constraint con WHERE $1::regclass::oid = con.conrelid AND con.conname = $2 AND con.contype='f'", tableName, foreignKeyName).Scan(&count)
- return count > 0
-}
-
-func (s postgres) HasTable(tableName string) bool {
- var count int
- s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE table_name = $1 AND table_type = 'BASE TABLE' AND table_schema = CURRENT_SCHEMA()", tableName).Scan(&count)
- return count > 0
-}
-
-func (s postgres) HasColumn(tableName string, columnName string) bool {
- var count int
- s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = CURRENT_SCHEMA()", tableName, columnName).Scan(&count)
- return count > 0
-}
-
-func (s postgres) CurrentDatabase() (name string) {
- s.db.QueryRow("SELECT CURRENT_DATABASE()").Scan(&name)
- return
-}
-
-func (s postgres) LastInsertIDOutputInterstitial(tableName, key string, columns []string) string {
- return ""
-}
-
-func (s postgres) LastInsertIDReturningSuffix(tableName, key string) string {
- return fmt.Sprintf("RETURNING %v.%v", tableName, key)
-}
-
-func (postgres) SupportLastInsertID() bool {
- return false
-}
-
-func isUUID(value reflect.Value) bool {
- if value.Kind() != reflect.Array || value.Type().Len() != 16 {
- return false
- }
- typename := value.Type().Name()
- lower := strings.ToLower(typename)
- return "uuid" == lower || "guid" == lower
-}
-
-func isJSON(value reflect.Value) bool {
- _, ok := value.Interface().(json.RawMessage)
- return ok
-}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_sqlite3.go b/vendor/github.com/jinzhu/gorm/dialect_sqlite3.go
deleted file mode 100644
index 5f96c36..0000000
--- a/vendor/github.com/jinzhu/gorm/dialect_sqlite3.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package gorm
-
-import (
- "fmt"
- "reflect"
- "strings"
- "time"
-)
-
-type sqlite3 struct {
- commonDialect
-}
-
-func init() {
- RegisterDialect("sqlite3", &sqlite3{})
-}
-
-func (sqlite3) GetName() string {
- return "sqlite3"
-}
-
-// Get Data Type for Sqlite Dialect
-func (s *sqlite3) DataTypeOf(field *StructField) string {
- var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
-
- if sqlType == "" {
- switch dataValue.Kind() {
- case reflect.Bool:
- sqlType = "bool"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "integer primary key autoincrement"
- } else {
- sqlType = "integer"
- }
- case reflect.Int64, reflect.Uint64:
- if s.fieldCanAutoIncrement(field) {
- field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
- sqlType = "integer primary key autoincrement"
- } else {
- sqlType = "bigint"
- }
- case reflect.Float32, reflect.Float64:
- sqlType = "real"
- case reflect.String:
- if size > 0 && size < 65532 {
- sqlType = fmt.Sprintf("varchar(%d)", size)
- } else {
- sqlType = "text"
- }
- case reflect.Struct:
- if _, ok := dataValue.Interface().(time.Time); ok {
- sqlType = "datetime"
- }
- default:
- if IsByteArrayOrSlice(dataValue) {
- sqlType = "blob"
- }
- }
- }
-
- if sqlType == "" {
- panic(fmt.Sprintf("invalid sql type %s (%s) for sqlite3", dataValue.Type().Name(), dataValue.Kind().String()))
- }
-
- if strings.TrimSpace(additionalType) == "" {
- return sqlType
- }
- return fmt.Sprintf("%v %v", sqlType, additionalType)
-}
-
-func (s sqlite3) HasIndex(tableName string, indexName string) bool {
- var count int
- s.db.QueryRow(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND sql LIKE '%%INDEX %v ON%%'", indexName), tableName).Scan(&count)
- return count > 0
-}
-
-func (s sqlite3) HasTable(tableName string) bool {
- var count int
- s.db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?", tableName).Scan(&count)
- return count > 0
-}
-
-func (s sqlite3) HasColumn(tableName string, columnName string) bool {
- var count int
- s.db.QueryRow(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND (sql LIKE '%%\"%v\" %%' OR sql LIKE '%%%v %%');\n", columnName, columnName), tableName).Scan(&count)
- return count > 0
-}
-
-func (s sqlite3) CurrentDatabase() (name string) {
- var (
- ifaces = make([]interface{}, 3)
- pointers = make([]*string, 3)
- i int
- )
- for i = 0; i < 3; i++ {
- ifaces[i] = &pointers[i]
- }
- if err := s.db.QueryRow("PRAGMA database_list").Scan(ifaces...); err != nil {
- return
- }
- if pointers[1] != nil {
- name = *pointers[1]
- }
- return
-}
diff --git a/vendor/github.com/jinzhu/gorm/dialects/mysql/mysql.go b/vendor/github.com/jinzhu/gorm/dialects/mysql/mysql.go
deleted file mode 100644
index 9deba48..0000000
--- a/vendor/github.com/jinzhu/gorm/dialects/mysql/mysql.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package mysql
-
-import _ "github.com/go-sql-driver/mysql"
diff --git a/vendor/github.com/jinzhu/gorm/docker-compose.yml b/vendor/github.com/jinzhu/gorm/docker-compose.yml
deleted file mode 100644
index 79bf5fc..0000000
--- a/vendor/github.com/jinzhu/gorm/docker-compose.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-version: '3'
-
-services:
- mysql:
- image: 'mysql:latest'
- ports:
- - 9910:3306
- environment:
- - MYSQL_DATABASE=gorm
- - MYSQL_USER=gorm
- - MYSQL_PASSWORD=gorm
- - MYSQL_RANDOM_ROOT_PASSWORD="yes"
- postgres:
- image: 'postgres:latest'
- ports:
- - 9920:5432
- environment:
- - POSTGRES_USER=gorm
- - POSTGRES_DB=gorm
- - POSTGRES_PASSWORD=gorm
- mssql:
- image: 'mcmoe/mssqldocker:latest'
- ports:
- - 9930:1433
- environment:
- - ACCEPT_EULA=Y
- - SA_PASSWORD=LoremIpsum86
- - MSSQL_DB=gorm
- - MSSQL_USER=gorm
- - MSSQL_PASSWORD=LoremIpsum86
diff --git a/vendor/github.com/jinzhu/gorm/errors.go b/vendor/github.com/jinzhu/gorm/errors.go
deleted file mode 100644
index d5ef8d5..0000000
--- a/vendor/github.com/jinzhu/gorm/errors.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package gorm
-
-import (
- "errors"
- "strings"
-)
-
-var (
- // ErrRecordNotFound returns a "record not found error". Occurs only when attempting to query the database with a struct; querying with a slice won't return this error
- ErrRecordNotFound = errors.New("record not found")
- // ErrInvalidSQL occurs when you attempt a query with invalid SQL
- ErrInvalidSQL = errors.New("invalid SQL")
- // ErrInvalidTransaction occurs when you are trying to `Commit` or `Rollback`
- ErrInvalidTransaction = errors.New("no valid transaction")
- // ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin`
- ErrCantStartTransaction = errors.New("can't start transaction")
- // ErrUnaddressable unaddressable value
- ErrUnaddressable = errors.New("using unaddressable value")
-)
-
-// Errors contains all happened errors
-type Errors []error
-
-// IsRecordNotFoundError returns true if error contains a RecordNotFound error
-func IsRecordNotFoundError(err error) bool {
- if errs, ok := err.(Errors); ok {
- for _, err := range errs {
- if err == ErrRecordNotFound {
- return true
- }
- }
- }
- return err == ErrRecordNotFound
-}
-
-// GetErrors gets all errors that have occurred and returns a slice of errors (Error type)
-func (errs Errors) GetErrors() []error {
- return errs
-}
-
-// Add adds an error to a given slice of errors
-func (errs Errors) Add(newErrors ...error) Errors {
- for _, err := range newErrors {
- if err == nil {
- continue
- }
-
- if errors, ok := err.(Errors); ok {
- errs = errs.Add(errors...)
- } else {
- ok = true
- for _, e := range errs {
- if err == e {
- ok = false
- }
- }
- if ok {
- errs = append(errs, err)
- }
- }
- }
- return errs
-}
-
-// Error takes a slice of all errors that have occurred and returns it as a formatted string
-func (errs Errors) Error() string {
- var errors = []string{}
- for _, e := range errs {
- errors = append(errors, e.Error())
- }
- return strings.Join(errors, "; ")
-}
diff --git a/vendor/github.com/jinzhu/gorm/field.go b/vendor/github.com/jinzhu/gorm/field.go
deleted file mode 100644
index acd06e2..0000000
--- a/vendor/github.com/jinzhu/gorm/field.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package gorm
-
-import (
- "database/sql"
- "database/sql/driver"
- "errors"
- "fmt"
- "reflect"
-)
-
-// Field model field definition
-type Field struct {
- *StructField
- IsBlank bool
- Field reflect.Value
-}
-
-// Set set a value to the field
-func (field *Field) Set(value interface{}) (err error) {
- if !field.Field.IsValid() {
- return errors.New("field value not valid")
- }
-
- if !field.Field.CanAddr() {
- return ErrUnaddressable
- }
-
- reflectValue, ok := value.(reflect.Value)
- if !ok {
- reflectValue = reflect.ValueOf(value)
- }
-
- fieldValue := field.Field
- if reflectValue.IsValid() {
- if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
- fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
- } else {
- if fieldValue.Kind() == reflect.Ptr {
- if fieldValue.IsNil() {
- fieldValue.Set(reflect.New(field.Struct.Type.Elem()))
- }
- fieldValue = fieldValue.Elem()
- }
-
- if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
- fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
- } else if scanner, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
- v := reflectValue.Interface()
- if valuer, ok := v.(driver.Valuer); ok {
- if v, err = valuer.Value(); err == nil {
- err = scanner.Scan(v)
- }
- } else {
- err = scanner.Scan(v)
- }
- } else {
- err = fmt.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type())
- }
- }
- } else {
- field.Field.Set(reflect.Zero(field.Field.Type()))
- }
-
- field.IsBlank = isBlank(field.Field)
- return err
-}
diff --git a/vendor/github.com/jinzhu/gorm/interface.go b/vendor/github.com/jinzhu/gorm/interface.go
deleted file mode 100644
index fe64923..0000000
--- a/vendor/github.com/jinzhu/gorm/interface.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package gorm
-
-import (
- "context"
- "database/sql"
-)
-
-// SQLCommon is the minimal database connection functionality gorm requires. Implemented by *sql.DB.
-type SQLCommon interface {
- Exec(query string, args ...interface{}) (sql.Result, error)
- Prepare(query string) (*sql.Stmt, error)
- Query(query string, args ...interface{}) (*sql.Rows, error)
- QueryRow(query string, args ...interface{}) *sql.Row
-}
-
-type sqlDb interface {
- Begin() (*sql.Tx, error)
- BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
-}
-
-type sqlTx interface {
- Commit() error
- Rollback() error
-}
diff --git a/vendor/github.com/jinzhu/gorm/join_table_handler.go b/vendor/github.com/jinzhu/gorm/join_table_handler.go
deleted file mode 100644
index a036d46..0000000
--- a/vendor/github.com/jinzhu/gorm/join_table_handler.go
+++ /dev/null
@@ -1,211 +0,0 @@
-package gorm
-
-import (
- "errors"
- "fmt"
- "reflect"
- "strings"
-)
-
-// JoinTableHandlerInterface is an interface for how to handle many2many relations
-type JoinTableHandlerInterface interface {
- // initialize join table handler
- Setup(relationship *Relationship, tableName string, source reflect.Type, destination reflect.Type)
- // Table return join table's table name
- Table(db *DB) string
- // Add create relationship in join table for source and destination
- Add(handler JoinTableHandlerInterface, db *DB, source interface{}, destination interface{}) error
- // Delete delete relationship in join table for sources
- Delete(handler JoinTableHandlerInterface, db *DB, sources ...interface{}) error
- // JoinWith query with `Join` conditions
- JoinWith(handler JoinTableHandlerInterface, db *DB, source interface{}) *DB
- // SourceForeignKeys return source foreign keys
- SourceForeignKeys() []JoinTableForeignKey
- // DestinationForeignKeys return destination foreign keys
- DestinationForeignKeys() []JoinTableForeignKey
-}
-
-// JoinTableForeignKey join table foreign key struct
-type JoinTableForeignKey struct {
- DBName string
- AssociationDBName string
-}
-
-// JoinTableSource is a struct that contains model type and foreign keys
-type JoinTableSource struct {
- ModelType reflect.Type
- ForeignKeys []JoinTableForeignKey
-}
-
-// JoinTableHandler default join table handler
-type JoinTableHandler struct {
- TableName string `sql:"-"`
- Source JoinTableSource `sql:"-"`
- Destination JoinTableSource `sql:"-"`
-}
-
-// SourceForeignKeys return source foreign keys
-func (s *JoinTableHandler) SourceForeignKeys() []JoinTableForeignKey {
- return s.Source.ForeignKeys
-}
-
-// DestinationForeignKeys return destination foreign keys
-func (s *JoinTableHandler) DestinationForeignKeys() []JoinTableForeignKey {
- return s.Destination.ForeignKeys
-}
-
-// Setup initialize a default join table handler
-func (s *JoinTableHandler) Setup(relationship *Relationship, tableName string, source reflect.Type, destination reflect.Type) {
- s.TableName = tableName
-
- s.Source = JoinTableSource{ModelType: source}
- s.Source.ForeignKeys = []JoinTableForeignKey{}
- for idx, dbName := range relationship.ForeignFieldNames {
- s.Source.ForeignKeys = append(s.Source.ForeignKeys, JoinTableForeignKey{
- DBName: relationship.ForeignDBNames[idx],
- AssociationDBName: dbName,
- })
- }
-
- s.Destination = JoinTableSource{ModelType: destination}
- s.Destination.ForeignKeys = []JoinTableForeignKey{}
- for idx, dbName := range relationship.AssociationForeignFieldNames {
- s.Destination.ForeignKeys = append(s.Destination.ForeignKeys, JoinTableForeignKey{
- DBName: relationship.AssociationForeignDBNames[idx],
- AssociationDBName: dbName,
- })
- }
-}
-
-// Table return join table's table name
-func (s JoinTableHandler) Table(db *DB) string {
- return DefaultTableNameHandler(db, s.TableName)
-}
-
-func (s JoinTableHandler) updateConditionMap(conditionMap map[string]interface{}, db *DB, joinTableSources []JoinTableSource, sources ...interface{}) {
- for _, source := range sources {
- scope := db.NewScope(source)
- modelType := scope.GetModelStruct().ModelType
-
- for _, joinTableSource := range joinTableSources {
- if joinTableSource.ModelType == modelType {
- for _, foreignKey := range joinTableSource.ForeignKeys {
- if field, ok := scope.FieldByName(foreignKey.AssociationDBName); ok {
- conditionMap[foreignKey.DBName] = field.Field.Interface()
- }
- }
- break
- }
- }
- }
-}
-
-// Add create relationship in join table for source and destination
-func (s JoinTableHandler) Add(handler JoinTableHandlerInterface, db *DB, source interface{}, destination interface{}) error {
- var (
- scope = db.NewScope("")
- conditionMap = map[string]interface{}{}
- )
-
- // Update condition map for source
- s.updateConditionMap(conditionMap, db, []JoinTableSource{s.Source}, source)
-
- // Update condition map for destination
- s.updateConditionMap(conditionMap, db, []JoinTableSource{s.Destination}, destination)
-
- var assignColumns, binVars, conditions []string
- var values []interface{}
- for key, value := range conditionMap {
- assignColumns = append(assignColumns, scope.Quote(key))
- binVars = append(binVars, `?`)
- conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(key)))
- values = append(values, value)
- }
-
- for _, value := range values {
- values = append(values, value)
- }
-
- quotedTable := scope.Quote(handler.Table(db))
- sql := fmt.Sprintf(
- "INSERT INTO %v (%v) SELECT %v %v WHERE NOT EXISTS (SELECT * FROM %v WHERE %v)",
- quotedTable,
- strings.Join(assignColumns, ","),
- strings.Join(binVars, ","),
- scope.Dialect().SelectFromDummyTable(),
- quotedTable,
- strings.Join(conditions, " AND "),
- )
-
- return db.Exec(sql, values...).Error
-}
-
-// Delete delete relationship in join table for sources
-func (s JoinTableHandler) Delete(handler JoinTableHandlerInterface, db *DB, sources ...interface{}) error {
- var (
- scope = db.NewScope(nil)
- conditions []string
- values []interface{}
- conditionMap = map[string]interface{}{}
- )
-
- s.updateConditionMap(conditionMap, db, []JoinTableSource{s.Source, s.Destination}, sources...)
-
- for key, value := range conditionMap {
- conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(key)))
- values = append(values, value)
- }
-
- return db.Table(handler.Table(db)).Where(strings.Join(conditions, " AND "), values...).Delete("").Error
-}
-
-// JoinWith query with `Join` conditions
-func (s JoinTableHandler) JoinWith(handler JoinTableHandlerInterface, db *DB, source interface{}) *DB {
- var (
- scope = db.NewScope(source)
- tableName = handler.Table(db)
- quotedTableName = scope.Quote(tableName)
- joinConditions []string
- values []interface{}
- )
-
- if s.Source.ModelType == scope.GetModelStruct().ModelType {
- destinationTableName := db.NewScope(reflect.New(s.Destination.ModelType).Interface()).QuotedTableName()
- for _, foreignKey := range s.Destination.ForeignKeys {
- joinConditions = append(joinConditions, fmt.Sprintf("%v.%v = %v.%v", quotedTableName, scope.Quote(foreignKey.DBName), destinationTableName, scope.Quote(foreignKey.AssociationDBName)))
- }
-
- var foreignDBNames []string
- var foreignFieldNames []string
-
- for _, foreignKey := range s.Source.ForeignKeys {
- foreignDBNames = append(foreignDBNames, foreignKey.DBName)
- if field, ok := scope.FieldByName(foreignKey.AssociationDBName); ok {
- foreignFieldNames = append(foreignFieldNames, field.Name)
- }
- }
-
- foreignFieldValues := scope.getColumnAsArray(foreignFieldNames, scope.Value)
-
- var condString string
- if len(foreignFieldValues) > 0 {
- var quotedForeignDBNames []string
- for _, dbName := range foreignDBNames {
- quotedForeignDBNames = append(quotedForeignDBNames, tableName+"."+dbName)
- }
-
- condString = fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, quotedForeignDBNames), toQueryMarks(foreignFieldValues))
-
- keys := scope.getColumnAsArray(foreignFieldNames, scope.Value)
- values = append(values, toQueryValues(keys))
- } else {
- condString = fmt.Sprintf("1 <> 1")
- }
-
- return db.Joins(fmt.Sprintf("INNER JOIN %v ON %v", quotedTableName, strings.Join(joinConditions, " AND "))).
- Where(condString, toQueryValues(foreignFieldValues)...)
- }
-
- db.Error = errors.New("wrong source type for join table handler")
- return db
-}
diff --git a/vendor/github.com/jinzhu/gorm/logger.go b/vendor/github.com/jinzhu/gorm/logger.go
deleted file mode 100644
index 88e167d..0000000
--- a/vendor/github.com/jinzhu/gorm/logger.go
+++ /dev/null
@@ -1,141 +0,0 @@
-package gorm
-
-import (
- "database/sql/driver"
- "fmt"
- "log"
- "os"
- "reflect"
- "regexp"
- "strconv"
- "time"
- "unicode"
-)
-
-var (
- defaultLogger = Logger{log.New(os.Stdout, "\r\n", 0)}
- sqlRegexp = regexp.MustCompile(`\?`)
- numericPlaceHolderRegexp = regexp.MustCompile(`\$\d+`)
-)
-
-func isPrintable(s string) bool {
- for _, r := range s {
- if !unicode.IsPrint(r) {
- return false
- }
- }
- return true
-}
-
-var LogFormatter = func(values ...interface{}) (messages []interface{}) {
- if len(values) > 1 {
- var (
- sql string
- formattedValues []string
- level = values[0]
- currentTime = "\n\033[33m[" + NowFunc().Format("2006-01-02 15:04:05") + "]\033[0m"
- source = fmt.Sprintf("\033[35m(%v)\033[0m", values[1])
- )
-
- messages = []interface{}{source, currentTime}
-
- if len(values) == 2 {
- //remove the line break
- currentTime = currentTime[1:]
- //remove the brackets
- source = fmt.Sprintf("\033[35m%v\033[0m", values[1])
-
- messages = []interface{}{currentTime, source}
- }
-
- if level == "sql" {
- // duration
- messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0))
- // sql
-
- for _, value := range values[4].([]interface{}) {
- indirectValue := reflect.Indirect(reflect.ValueOf(value))
- if indirectValue.IsValid() {
- value = indirectValue.Interface()
- if t, ok := value.(time.Time); ok {
- if t.IsZero() {
- formattedValues = append(formattedValues, fmt.Sprintf("'%v'", "0000-00-00 00:00:00"))
- } else {
- formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05")))
- }
- } else if b, ok := value.([]byte); ok {
- if str := string(b); isPrintable(str) {
- formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str))
- } else {
- formattedValues = append(formattedValues, "''")
- }
- } else if r, ok := value.(driver.Valuer); ok {
- if value, err := r.Value(); err == nil && value != nil {
- formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
- } else {
- formattedValues = append(formattedValues, "NULL")
- }
- } else {
- switch value.(type) {
- case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool:
- formattedValues = append(formattedValues, fmt.Sprintf("%v", value))
- default:
- formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
- }
- }
- } else {
- formattedValues = append(formattedValues, "NULL")
- }
- }
-
- // differentiate between $n placeholders or else treat like ?
- if numericPlaceHolderRegexp.MatchString(values[3].(string)) {
- sql = values[3].(string)
- for index, value := range formattedValues {
- placeholder := fmt.Sprintf(`\$%d([^\d]|$)`, index+1)
- sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value+"$1")
- }
- } else {
- formattedValuesLength := len(formattedValues)
- for index, value := range sqlRegexp.Split(values[3].(string), -1) {
- sql += value
- if index < formattedValuesLength {
- sql += formattedValues[index]
- }
- }
- }
-
- messages = append(messages, sql)
- messages = append(messages, fmt.Sprintf(" \n\033[36;31m[%v]\033[0m ", strconv.FormatInt(values[5].(int64), 10)+" rows affected or returned "))
- } else {
- messages = append(messages, "\033[31;1m")
- messages = append(messages, values[2:]...)
- messages = append(messages, "\033[0m")
- }
- }
-
- return
-}
-
-type logger interface {
- Print(v ...interface{})
-}
-
-// LogWriter log writer interface
-type LogWriter interface {
- Println(v ...interface{})
-}
-
-// Logger default logger
-type Logger struct {
- LogWriter
-}
-
-// Print format & print log
-func (logger Logger) Print(values ...interface{}) {
- logger.Println(LogFormatter(values...)...)
-}
-
-type nopLogger struct{}
-
-func (nopLogger) Print(values ...interface{}) {}
diff --git a/vendor/github.com/jinzhu/gorm/main.go b/vendor/github.com/jinzhu/gorm/main.go
deleted file mode 100644
index 466e80c..0000000
--- a/vendor/github.com/jinzhu/gorm/main.go
+++ /dev/null
@@ -1,886 +0,0 @@
-package gorm
-
-import (
- "context"
- "database/sql"
- "errors"
- "fmt"
- "reflect"
- "strings"
- "sync"
- "time"
-)
-
-// DB contains information for current db connection
-type DB struct {
- sync.RWMutex
- Value interface{}
- Error error
- RowsAffected int64
-
- // single db
- db SQLCommon
- blockGlobalUpdate bool
- logMode logModeValue
- logger logger
- search *search
- values sync.Map
-
- // global db
- parent *DB
- callbacks *Callback
- dialect Dialect
- singularTable bool
-
- // function to be used to override the creating of a new timestamp
- nowFuncOverride func() time.Time
-}
-
-type logModeValue int
-
-const (
- defaultLogMode logModeValue = iota
- noLogMode
- detailedLogMode
-)
-
-// Open initialize a new db connection, need to import driver first, e.g:
-//
-// import _ "github.com/go-sql-driver/mysql"
-// func main() {
-// db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
-// }
-// GORM has wrapped some drivers, for easier to remember driver's import path, so you could import the mysql driver with
-// import _ "github.com/jinzhu/gorm/dialects/mysql"
-// // import _ "github.com/jinzhu/gorm/dialects/postgres"
-// // import _ "github.com/jinzhu/gorm/dialects/sqlite"
-// // import _ "github.com/jinzhu/gorm/dialects/mssql"
-func Open(dialect string, args ...interface{}) (db *DB, err error) {
- if len(args) == 0 {
- err = errors.New("invalid database source")
- return nil, err
- }
- var source string
- var dbSQL SQLCommon
- var ownDbSQL bool
-
- switch value := args[0].(type) {
- case string:
- var driver = dialect
- if len(args) == 1 {
- source = value
- } else if len(args) >= 2 {
- driver = value
- source = args[1].(string)
- }
- dbSQL, err = sql.Open(driver, source)
- ownDbSQL = true
- case SQLCommon:
- dbSQL = value
- ownDbSQL = false
- default:
- return nil, fmt.Errorf("invalid database source: %v is not a valid type", value)
- }
-
- db = &DB{
- db: dbSQL,
- logger: defaultLogger,
- callbacks: DefaultCallback,
- dialect: newDialect(dialect, dbSQL),
- }
- db.parent = db
- if err != nil {
- return
- }
- // Send a ping to make sure the database connection is alive.
- if d, ok := dbSQL.(*sql.DB); ok {
- if err = d.Ping(); err != nil && ownDbSQL {
- d.Close()
- }
- }
- return
-}
-
-// New clone a new db connection without search conditions
-func (s *DB) New() *DB {
- clone := s.clone()
- clone.search = nil
- clone.Value = nil
- return clone
-}
-
-type closer interface {
- Close() error
-}
-
-// Close close current db connection. If database connection is not an io.Closer, returns an error.
-func (s *DB) Close() error {
- if db, ok := s.parent.db.(closer); ok {
- return db.Close()
- }
- return errors.New("can't close current db")
-}
-
-// DB get `*sql.DB` from current connection
-// If the underlying database connection is not a *sql.DB, returns nil
-func (s *DB) DB() *sql.DB {
- db, ok := s.db.(*sql.DB)
- if !ok {
- panic("can't support full GORM on currently status, maybe this is a TX instance.")
- }
- return db
-}
-
-// CommonDB return the underlying `*sql.DB` or `*sql.Tx` instance, mainly intended to allow coexistence with legacy non-GORM code.
-func (s *DB) CommonDB() SQLCommon {
- return s.db
-}
-
-// Dialect get dialect
-func (s *DB) Dialect() Dialect {
- return s.dialect
-}
-
-// Callback return `Callbacks` container, you could add/change/delete callbacks with it
-// db.Callback().Create().Register("update_created_at", updateCreated)
-// Refer https://jinzhu.github.io/gorm/development.html#callbacks
-func (s *DB) Callback() *Callback {
- s.parent.callbacks = s.parent.callbacks.clone(s.logger)
- return s.parent.callbacks
-}
-
-// SetLogger replace default logger
-func (s *DB) SetLogger(log logger) {
- s.logger = log
-}
-
-// LogMode set log mode, `true` for detailed logs, `false` for no log, default, will only print error logs
-func (s *DB) LogMode(enable bool) *DB {
- if enable {
- s.logMode = detailedLogMode
- } else {
- s.logMode = noLogMode
- }
- return s
-}
-
-// SetNowFuncOverride set the function to be used when creating a new timestamp
-func (s *DB) SetNowFuncOverride(nowFuncOverride func() time.Time) *DB {
- s.nowFuncOverride = nowFuncOverride
- return s
-}
-
-// Get a new timestamp, using the provided nowFuncOverride on the DB instance if set,
-// otherwise defaults to the global NowFunc()
-func (s *DB) nowFunc() time.Time {
- if s.nowFuncOverride != nil {
- return s.nowFuncOverride()
- }
-
- return NowFunc()
-}
-
-// BlockGlobalUpdate if true, generates an error on update/delete without where clause.
-// This is to prevent eventual error with empty objects updates/deletions
-func (s *DB) BlockGlobalUpdate(enable bool) *DB {
- s.blockGlobalUpdate = enable
- return s
-}
-
-// HasBlockGlobalUpdate return state of block
-func (s *DB) HasBlockGlobalUpdate() bool {
- return s.blockGlobalUpdate
-}
-
-// SingularTable use singular table by default
-func (s *DB) SingularTable(enable bool) {
- s.parent.Lock()
- defer s.parent.Unlock()
- s.parent.singularTable = enable
-}
-
-// NewScope create a scope for current operation
-func (s *DB) NewScope(value interface{}) *Scope {
- dbClone := s.clone()
- dbClone.Value = value
- scope := &Scope{db: dbClone, Value: value}
- if s.search != nil {
- scope.Search = s.search.clone()
- } else {
- scope.Search = &search{}
- }
- return scope
-}
-
-// QueryExpr returns the query as SqlExpr object
-func (s *DB) QueryExpr() *SqlExpr {
- scope := s.NewScope(s.Value)
- scope.InstanceSet("skip_bindvar", true)
- scope.prepareQuerySQL()
-
- return Expr(scope.SQL, scope.SQLVars...)
-}
-
-// SubQuery returns the query as sub query
-func (s *DB) SubQuery() *SqlExpr {
- scope := s.NewScope(s.Value)
- scope.InstanceSet("skip_bindvar", true)
- scope.prepareQuerySQL()
-
- return Expr(fmt.Sprintf("(%v)", scope.SQL), scope.SQLVars...)
-}
-
-// Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/crud.html#query
-func (s *DB) Where(query interface{}, args ...interface{}) *DB {
- return s.clone().search.Where(query, args...).db
-}
-
-// Or filter records that match before conditions or this one, similar to `Where`
-func (s *DB) Or(query interface{}, args ...interface{}) *DB {
- return s.clone().search.Or(query, args...).db
-}
-
-// Not filter records that don't match current conditions, similar to `Where`
-func (s *DB) Not(query interface{}, args ...interface{}) *DB {
- return s.clone().search.Not(query, args...).db
-}
-
-// Limit specify the number of records to be retrieved
-func (s *DB) Limit(limit interface{}) *DB {
- return s.clone().search.Limit(limit).db
-}
-
-// Offset specify the number of records to skip before starting to return the records
-func (s *DB) Offset(offset interface{}) *DB {
- return s.clone().search.Offset(offset).db
-}
-
-// Order specify order when retrieve records from database, set reorder to `true` to overwrite defined conditions
-// db.Order("name DESC")
-// db.Order("name DESC", true) // reorder
-// db.Order(gorm.Expr("name = ? DESC", "first")) // sql expression
-func (s *DB) Order(value interface{}, reorder ...bool) *DB {
- return s.clone().search.Order(value, reorder...).db
-}
-
-// Select specify fields that you want to retrieve from database when querying, by default, will select all fields;
-// When creating/updating, specify fields that you want to save to database
-func (s *DB) Select(query interface{}, args ...interface{}) *DB {
- return s.clone().search.Select(query, args...).db
-}
-
-// Omit specify fields that you want to ignore when saving to database for creating, updating
-func (s *DB) Omit(columns ...string) *DB {
- return s.clone().search.Omit(columns...).db
-}
-
-// Group specify the group method on the find
-func (s *DB) Group(query string) *DB {
- return s.clone().search.Group(query).db
-}
-
-// Having specify HAVING conditions for GROUP BY
-func (s *DB) Having(query interface{}, values ...interface{}) *DB {
- return s.clone().search.Having(query, values...).db
-}
-
-// Joins specify Joins conditions
-// db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
-func (s *DB) Joins(query string, args ...interface{}) *DB {
- return s.clone().search.Joins(query, args...).db
-}
-
-// Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically
-// func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
-// return db.Where("amount > ?", 1000)
-// }
-//
-// func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
-// return func (db *gorm.DB) *gorm.DB {
-// return db.Scopes(AmountGreaterThan1000).Where("status in (?)", status)
-// }
-// }
-//
-// db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
-// Refer https://jinzhu.github.io/gorm/crud.html#scopes
-func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
- for _, f := range funcs {
- s = f(s)
- }
- return s
-}
-
-// Unscoped return all record including deleted record, refer Soft Delete https://jinzhu.github.io/gorm/crud.html#soft-delete
-func (s *DB) Unscoped() *DB {
- return s.clone().search.unscoped().db
-}
-
-// Attrs initialize struct with argument if record not found with `FirstOrInit` https://jinzhu.github.io/gorm/crud.html#firstorinit or `FirstOrCreate` https://jinzhu.github.io/gorm/crud.html#firstorcreate
-func (s *DB) Attrs(attrs ...interface{}) *DB {
- return s.clone().search.Attrs(attrs...).db
-}
-
-// Assign assign result with argument regardless it is found or not with `FirstOrInit` https://jinzhu.github.io/gorm/crud.html#firstorinit or `FirstOrCreate` https://jinzhu.github.io/gorm/crud.html#firstorcreate
-func (s *DB) Assign(attrs ...interface{}) *DB {
- return s.clone().search.Assign(attrs...).db
-}
-
-// First find first record that match given conditions, order by primary key
-func (s *DB) First(out interface{}, where ...interface{}) *DB {
- newScope := s.NewScope(out)
- newScope.Search.Limit(1)
-
- return newScope.Set("gorm:order_by_primary_key", "ASC").
- inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
-}
-
-// Take return a record that match given conditions, the order will depend on the database implementation
-func (s *DB) Take(out interface{}, where ...interface{}) *DB {
- newScope := s.NewScope(out)
- newScope.Search.Limit(1)
- return newScope.inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
-}
-
-// Last find last record that match given conditions, order by primary key
-func (s *DB) Last(out interface{}, where ...interface{}) *DB {
- newScope := s.NewScope(out)
- newScope.Search.Limit(1)
- return newScope.Set("gorm:order_by_primary_key", "DESC").
- inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
-}
-
-// Find find records that match given conditions
-func (s *DB) Find(out interface{}, where ...interface{}) *DB {
- return s.NewScope(out).inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
-}
-
-//Preloads preloads relations, don`t touch out
-func (s *DB) Preloads(out interface{}) *DB {
- return s.NewScope(out).InstanceSet("gorm:only_preload", 1).callCallbacks(s.parent.callbacks.queries).db
-}
-
-// Scan scan value to a struct
-func (s *DB) Scan(dest interface{}) *DB {
- return s.NewScope(s.Value).Set("gorm:query_destination", dest).callCallbacks(s.parent.callbacks.queries).db
-}
-
-// Row return `*sql.Row` with given conditions
-func (s *DB) Row() *sql.Row {
- return s.NewScope(s.Value).row()
-}
-
-// Rows return `*sql.Rows` with given conditions
-func (s *DB) Rows() (*sql.Rows, error) {
- return s.NewScope(s.Value).rows()
-}
-
-// ScanRows scan `*sql.Rows` to give struct
-func (s *DB) ScanRows(rows *sql.Rows, result interface{}) error {
- var (
- scope = s.NewScope(result)
- clone = scope.db
- columns, err = rows.Columns()
- )
-
- if clone.AddError(err) == nil {
- scope.scan(rows, columns, scope.Fields())
- }
-
- return clone.Error
-}
-
-// Pluck used to query single column from a model as a map
-// var ages []int64
-// db.Find(&users).Pluck("age", &ages)
-func (s *DB) Pluck(column string, value interface{}) *DB {
- return s.NewScope(s.Value).pluck(column, value).db
-}
-
-// Count get how many records for a model
-func (s *DB) Count(value interface{}) *DB {
- return s.NewScope(s.Value).count(value).db
-}
-
-// Related get related associations
-func (s *DB) Related(value interface{}, foreignKeys ...string) *DB {
- return s.NewScope(s.Value).related(value, foreignKeys...).db
-}
-
-// FirstOrInit find first matched record or initialize a new one with given conditions (only works with struct, map conditions)
-// https://jinzhu.github.io/gorm/crud.html#firstorinit
-func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
- c := s.clone()
- if result := c.First(out, where...); result.Error != nil {
- if !result.RecordNotFound() {
- return result
- }
- c.NewScope(out).inlineCondition(where...).initialize()
- } else {
- c.NewScope(out).updatedAttrsWithValues(c.search.assignAttrs)
- }
- return c
-}
-
-// FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)
-// https://jinzhu.github.io/gorm/crud.html#firstorcreate
-func (s *DB) FirstOrCreate(out interface{}, where ...interface{}) *DB {
- c := s.clone()
- if result := s.First(out, where...); result.Error != nil {
- if !result.RecordNotFound() {
- return result
- }
- return c.NewScope(out).inlineCondition(where...).initialize().callCallbacks(c.parent.callbacks.creates).db
- } else if len(c.search.assignAttrs) > 0 {
- return c.NewScope(out).InstanceSet("gorm:update_interface", c.search.assignAttrs).callCallbacks(c.parent.callbacks.updates).db
- }
- return c
-}
-
-// Update update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
-// WARNING when update with struct, GORM will not update fields that with zero value
-func (s *DB) Update(attrs ...interface{}) *DB {
- return s.Updates(toSearchableMap(attrs...), true)
-}
-
-// Updates update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
-func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB {
- return s.NewScope(s.Value).
- Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0).
- InstanceSet("gorm:update_interface", values).
- callCallbacks(s.parent.callbacks.updates).db
-}
-
-// UpdateColumn update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
-func (s *DB) UpdateColumn(attrs ...interface{}) *DB {
- return s.UpdateColumns(toSearchableMap(attrs...))
-}
-
-// UpdateColumns update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
-func (s *DB) UpdateColumns(values interface{}) *DB {
- return s.NewScope(s.Value).
- Set("gorm:update_column", true).
- Set("gorm:save_associations", false).
- InstanceSet("gorm:update_interface", values).
- callCallbacks(s.parent.callbacks.updates).db
-}
-
-// Save update value in database, if the value doesn't have primary key, will insert it
-func (s *DB) Save(value interface{}) *DB {
- scope := s.NewScope(value)
- if !scope.PrimaryKeyZero() {
- newDB := scope.callCallbacks(s.parent.callbacks.updates).db
- if newDB.Error == nil && newDB.RowsAffected == 0 {
- return s.New().Table(scope.TableName()).FirstOrCreate(value)
- }
- return newDB
- }
- return scope.callCallbacks(s.parent.callbacks.creates).db
-}
-
-// Create insert the value into database
-func (s *DB) Create(value interface{}) *DB {
- scope := s.NewScope(value)
- return scope.callCallbacks(s.parent.callbacks.creates).db
-}
-
-// Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition
-// WARNING If model has DeletedAt field, GORM will only set field DeletedAt's value to current time
-func (s *DB) Delete(value interface{}, where ...interface{}) *DB {
- return s.NewScope(value).inlineCondition(where...).callCallbacks(s.parent.callbacks.deletes).db
-}
-
-// Raw use raw sql as conditions, won't run it unless invoked by other methods
-// db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)
-func (s *DB) Raw(sql string, values ...interface{}) *DB {
- return s.clone().search.Raw(true).Where(sql, values...).db
-}
-
-// Exec execute raw sql
-func (s *DB) Exec(sql string, values ...interface{}) *DB {
- scope := s.NewScope(nil)
- generatedSQL := scope.buildCondition(map[string]interface{}{"query": sql, "args": values}, true)
- generatedSQL = strings.TrimSuffix(strings.TrimPrefix(generatedSQL, "("), ")")
- scope.Raw(generatedSQL)
- return scope.Exec().db
-}
-
-// Model specify the model you would like to run db operations
-// // update all users's name to `hello`
-// db.Model(&User{}).Update("name", "hello")
-// // if user's primary key is non-blank, will use it as condition, then will only update the user's name to `hello`
-// db.Model(&user).Update("name", "hello")
-func (s *DB) Model(value interface{}) *DB {
- c := s.clone()
- c.Value = value
- return c
-}
-
-// Table specify the table you would like to run db operations
-func (s *DB) Table(name string) *DB {
- clone := s.clone()
- clone.search.Table(name)
- clone.Value = nil
- return clone
-}
-
-// Debug start debug mode
-func (s *DB) Debug() *DB {
- return s.clone().LogMode(true)
-}
-
-// Transaction start a transaction as a block,
-// return error will rollback, otherwise to commit.
-func (s *DB) Transaction(fc func(tx *DB) error) (err error) {
-
- if _, ok := s.db.(*sql.Tx); ok {
- return fc(s)
- }
-
- panicked := true
- tx := s.Begin()
- defer func() {
- // Make sure to rollback when panic, Block error or Commit error
- if panicked || err != nil {
- tx.Rollback()
- }
- }()
-
- err = fc(tx)
-
- if err == nil {
- err = tx.Commit().Error
- }
-
- panicked = false
- return
-}
-
-// Begin begins a transaction
-func (s *DB) Begin() *DB {
- return s.BeginTx(context.Background(), &sql.TxOptions{})
-}
-
-// BeginTx begins a transaction with options
-func (s *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) *DB {
- c := s.clone()
- if db, ok := c.db.(sqlDb); ok && db != nil {
- tx, err := db.BeginTx(ctx, opts)
- c.db = interface{}(tx).(SQLCommon)
-
- c.dialect.SetDB(c.db)
- c.AddError(err)
- } else {
- c.AddError(ErrCantStartTransaction)
- }
- return c
-}
-
-// Commit commit a transaction
-func (s *DB) Commit() *DB {
- var emptySQLTx *sql.Tx
- if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
- s.AddError(db.Commit())
- } else {
- s.AddError(ErrInvalidTransaction)
- }
- return s
-}
-
-// Rollback rollback a transaction
-func (s *DB) Rollback() *DB {
- var emptySQLTx *sql.Tx
- if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
- if err := db.Rollback(); err != nil && err != sql.ErrTxDone {
- s.AddError(err)
- }
- } else {
- s.AddError(ErrInvalidTransaction)
- }
- return s
-}
-
-// RollbackUnlessCommitted rollback a transaction if it has not yet been
-// committed.
-func (s *DB) RollbackUnlessCommitted() *DB {
- var emptySQLTx *sql.Tx
- if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
- err := db.Rollback()
- // Ignore the error indicating that the transaction has already
- // been committed.
- if err != sql.ErrTxDone {
- s.AddError(err)
- }
- } else {
- s.AddError(ErrInvalidTransaction)
- }
- return s
-}
-
-// NewRecord check if value's primary key is blank
-func (s *DB) NewRecord(value interface{}) bool {
- return s.NewScope(value).PrimaryKeyZero()
-}
-
-// RecordNotFound check if returning ErrRecordNotFound error
-func (s *DB) RecordNotFound() bool {
- for _, err := range s.GetErrors() {
- if err == ErrRecordNotFound {
- return true
- }
- }
- return false
-}
-
-// CreateTable create table for models
-func (s *DB) CreateTable(models ...interface{}) *DB {
- db := s.Unscoped()
- for _, model := range models {
- db = db.NewScope(model).createTable().db
- }
- return db
-}
-
-// DropTable drop table for models
-func (s *DB) DropTable(values ...interface{}) *DB {
- db := s.clone()
- for _, value := range values {
- if tableName, ok := value.(string); ok {
- db = db.Table(tableName)
- }
-
- db = db.NewScope(value).dropTable().db
- }
- return db
-}
-
-// DropTableIfExists drop table if it is exist
-func (s *DB) DropTableIfExists(values ...interface{}) *DB {
- db := s.clone()
- for _, value := range values {
- if s.HasTable(value) {
- db.AddError(s.DropTable(value).Error)
- }
- }
- return db
-}
-
-// HasTable check has table or not
-func (s *DB) HasTable(value interface{}) bool {
- var (
- scope = s.NewScope(value)
- tableName string
- )
-
- if name, ok := value.(string); ok {
- tableName = name
- } else {
- tableName = scope.TableName()
- }
-
- has := scope.Dialect().HasTable(tableName)
- s.AddError(scope.db.Error)
- return has
-}
-
-// AutoMigrate run auto migration for given models, will only add missing fields, won't delete/change current data
-func (s *DB) AutoMigrate(values ...interface{}) *DB {
- db := s.Unscoped()
- for _, value := range values {
- db = db.NewScope(value).autoMigrate().db
- }
- return db
-}
-
-// ModifyColumn modify column to type
-func (s *DB) ModifyColumn(column string, typ string) *DB {
- scope := s.NewScope(s.Value)
- scope.modifyColumn(column, typ)
- return scope.db
-}
-
-// DropColumn drop a column
-func (s *DB) DropColumn(column string) *DB {
- scope := s.NewScope(s.Value)
- scope.dropColumn(column)
- return scope.db
-}
-
-// AddIndex add index for columns with given name
-func (s *DB) AddIndex(indexName string, columns ...string) *DB {
- scope := s.Unscoped().NewScope(s.Value)
- scope.addIndex(false, indexName, columns...)
- return scope.db
-}
-
-// AddUniqueIndex add unique index for columns with given name
-func (s *DB) AddUniqueIndex(indexName string, columns ...string) *DB {
- scope := s.Unscoped().NewScope(s.Value)
- scope.addIndex(true, indexName, columns...)
- return scope.db
-}
-
-// RemoveIndex remove index with name
-func (s *DB) RemoveIndex(indexName string) *DB {
- scope := s.NewScope(s.Value)
- scope.removeIndex(indexName)
- return scope.db
-}
-
-// AddForeignKey Add foreign key to the given scope, e.g:
-// db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
-func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB {
- scope := s.NewScope(s.Value)
- scope.addForeignKey(field, dest, onDelete, onUpdate)
- return scope.db
-}
-
-// RemoveForeignKey Remove foreign key from the given scope, e.g:
-// db.Model(&User{}).RemoveForeignKey("city_id", "cities(id)")
-func (s *DB) RemoveForeignKey(field string, dest string) *DB {
- scope := s.clone().NewScope(s.Value)
- scope.removeForeignKey(field, dest)
- return scope.db
-}
-
-// Association start `Association Mode` to handler relations things easir in that mode, refer: https://jinzhu.github.io/gorm/associations.html#association-mode
-func (s *DB) Association(column string) *Association {
- var err error
- var scope = s.Set("gorm:association:source", s.Value).NewScope(s.Value)
-
- if primaryField := scope.PrimaryField(); primaryField.IsBlank {
- err = errors.New("primary key can't be nil")
- } else {
- if field, ok := scope.FieldByName(column); ok {
- if field.Relationship == nil || len(field.Relationship.ForeignFieldNames) == 0 {
- err = fmt.Errorf("invalid association %v for %v", column, scope.IndirectValue().Type())
- } else {
- return &Association{scope: scope, column: column, field: field}
- }
- } else {
- err = fmt.Errorf("%v doesn't have column %v", scope.IndirectValue().Type(), column)
- }
- }
-
- return &Association{Error: err}
-}
-
-// Preload preload associations with given conditions
-// db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
-func (s *DB) Preload(column string, conditions ...interface{}) *DB {
- return s.clone().search.Preload(column, conditions...).db
-}
-
-// Set set setting by name, which could be used in callbacks, will clone a new db, and update its setting
-func (s *DB) Set(name string, value interface{}) *DB {
- return s.clone().InstantSet(name, value)
-}
-
-// InstantSet instant set setting, will affect current db
-func (s *DB) InstantSet(name string, value interface{}) *DB {
- s.values.Store(name, value)
- return s
-}
-
-// Get get setting by name
-func (s *DB) Get(name string) (value interface{}, ok bool) {
- value, ok = s.values.Load(name)
- return
-}
-
-// SetJoinTableHandler set a model's join table handler for a relation
-func (s *DB) SetJoinTableHandler(source interface{}, column string, handler JoinTableHandlerInterface) {
- scope := s.NewScope(source)
- for _, field := range scope.GetModelStruct().StructFields {
- if field.Name == column || field.DBName == column {
- if many2many, _ := field.TagSettingsGet("MANY2MANY"); many2many != "" {
- source := (&Scope{Value: source}).GetModelStruct().ModelType
- destination := (&Scope{Value: reflect.New(field.Struct.Type).Interface()}).GetModelStruct().ModelType
- handler.Setup(field.Relationship, many2many, source, destination)
- field.Relationship.JoinTableHandler = handler
- if table := handler.Table(s); scope.Dialect().HasTable(table) {
- s.Table(table).AutoMigrate(handler)
- }
- }
- }
- }
-}
-
-// AddError add error to the db
-func (s *DB) AddError(err error) error {
- if err != nil {
- if err != ErrRecordNotFound {
- if s.logMode == defaultLogMode {
- go s.print("error", fileWithLineNum(), err)
- } else {
- s.log(err)
- }
-
- errors := Errors(s.GetErrors())
- errors = errors.Add(err)
- if len(errors) > 1 {
- err = errors
- }
- }
-
- s.Error = err
- }
- return err
-}
-
-// GetErrors get happened errors from the db
-func (s *DB) GetErrors() []error {
- if errs, ok := s.Error.(Errors); ok {
- return errs
- } else if s.Error != nil {
- return []error{s.Error}
- }
- return []error{}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Private Methods For DB
-////////////////////////////////////////////////////////////////////////////////
-
-func (s *DB) clone() *DB {
- db := &DB{
- db: s.db,
- parent: s.parent,
- logger: s.logger,
- logMode: s.logMode,
- Value: s.Value,
- Error: s.Error,
- blockGlobalUpdate: s.blockGlobalUpdate,
- dialect: newDialect(s.dialect.GetName(), s.db),
- nowFuncOverride: s.nowFuncOverride,
- }
-
- s.values.Range(func(k, v interface{}) bool {
- db.values.Store(k, v)
- return true
- })
-
- if s.search == nil {
- db.search = &search{limit: -1, offset: -1}
- } else {
- db.search = s.search.clone()
- }
-
- db.search.db = db
- return db
-}
-
-func (s *DB) print(v ...interface{}) {
- s.logger.Print(v...)
-}
-
-func (s *DB) log(v ...interface{}) {
- if s != nil && s.logMode == detailedLogMode {
- s.print(append([]interface{}{"log", fileWithLineNum()}, v...)...)
- }
-}
-
-func (s *DB) slog(sql string, t time.Time, vars ...interface{}) {
- if s.logMode == detailedLogMode {
- s.print("sql", fileWithLineNum(), NowFunc().Sub(t), sql, vars, s.RowsAffected)
- }
-}
diff --git a/vendor/github.com/jinzhu/gorm/model.go b/vendor/github.com/jinzhu/gorm/model.go
deleted file mode 100644
index f37ff7e..0000000
--- a/vendor/github.com/jinzhu/gorm/model.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package gorm
-
-import "time"
-
-// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models
-// type User struct {
-// gorm.Model
-// }
-type Model struct {
- ID uint `gorm:"primary_key"`
- CreatedAt time.Time
- UpdatedAt time.Time
- DeletedAt *time.Time `sql:"index"`
-}
diff --git a/vendor/github.com/jinzhu/gorm/model_struct.go b/vendor/github.com/jinzhu/gorm/model_struct.go
deleted file mode 100644
index 57dbec3..0000000
--- a/vendor/github.com/jinzhu/gorm/model_struct.go
+++ /dev/null
@@ -1,677 +0,0 @@
-package gorm
-
-import (
- "database/sql"
- "errors"
- "go/ast"
- "reflect"
- "strings"
- "sync"
- "time"
-
- "github.com/jinzhu/inflection"
-)
-
-// DefaultTableNameHandler default table name handler
-var DefaultTableNameHandler = func(db *DB, defaultTableName string) string {
- return defaultTableName
-}
-
-// lock for mutating global cached model metadata
-var structsLock sync.Mutex
-
-// global cache of model metadata
-var modelStructsMap sync.Map
-
-// ModelStruct model definition
-type ModelStruct struct {
- PrimaryFields []*StructField
- StructFields []*StructField
- ModelType reflect.Type
-
- defaultTableName string
- l sync.Mutex
-}
-
-// TableName returns model's table name
-func (s *ModelStruct) TableName(db *DB) string {
- s.l.Lock()
- defer s.l.Unlock()
-
- if s.defaultTableName == "" && db != nil && s.ModelType != nil {
- // Set default table name
- if tabler, ok := reflect.New(s.ModelType).Interface().(tabler); ok {
- s.defaultTableName = tabler.TableName()
- } else {
- tableName := ToTableName(s.ModelType.Name())
- db.parent.RLock()
- if db == nil || (db.parent != nil && !db.parent.singularTable) {
- tableName = inflection.Plural(tableName)
- }
- db.parent.RUnlock()
- s.defaultTableName = tableName
- }
- }
-
- return DefaultTableNameHandler(db, s.defaultTableName)
-}
-
-// StructField model field's struct definition
-type StructField struct {
- DBName string
- Name string
- Names []string
- IsPrimaryKey bool
- IsNormal bool
- IsIgnored bool
- IsScanner bool
- HasDefaultValue bool
- Tag reflect.StructTag
- TagSettings map[string]string
- Struct reflect.StructField
- IsForeignKey bool
- Relationship *Relationship
-
- tagSettingsLock sync.RWMutex
-}
-
-// TagSettingsSet Sets a tag in the tag settings map
-func (sf *StructField) TagSettingsSet(key, val string) {
- sf.tagSettingsLock.Lock()
- defer sf.tagSettingsLock.Unlock()
- sf.TagSettings[key] = val
-}
-
-// TagSettingsGet returns a tag from the tag settings
-func (sf *StructField) TagSettingsGet(key string) (string, bool) {
- sf.tagSettingsLock.RLock()
- defer sf.tagSettingsLock.RUnlock()
- val, ok := sf.TagSettings[key]
- return val, ok
-}
-
-// TagSettingsDelete deletes a tag
-func (sf *StructField) TagSettingsDelete(key string) {
- sf.tagSettingsLock.Lock()
- defer sf.tagSettingsLock.Unlock()
- delete(sf.TagSettings, key)
-}
-
-func (sf *StructField) clone() *StructField {
- clone := &StructField{
- DBName: sf.DBName,
- Name: sf.Name,
- Names: sf.Names,
- IsPrimaryKey: sf.IsPrimaryKey,
- IsNormal: sf.IsNormal,
- IsIgnored: sf.IsIgnored,
- IsScanner: sf.IsScanner,
- HasDefaultValue: sf.HasDefaultValue,
- Tag: sf.Tag,
- TagSettings: map[string]string{},
- Struct: sf.Struct,
- IsForeignKey: sf.IsForeignKey,
- }
-
- if sf.Relationship != nil {
- relationship := *sf.Relationship
- clone.Relationship = &relationship
- }
-
- // copy the struct field tagSettings, they should be read-locked while they are copied
- sf.tagSettingsLock.Lock()
- defer sf.tagSettingsLock.Unlock()
- for key, value := range sf.TagSettings {
- clone.TagSettings[key] = value
- }
-
- return clone
-}
-
-// Relationship described the relationship between models
-type Relationship struct {
- Kind string
- PolymorphicType string
- PolymorphicDBName string
- PolymorphicValue string
- ForeignFieldNames []string
- ForeignDBNames []string
- AssociationForeignFieldNames []string
- AssociationForeignDBNames []string
- JoinTableHandler JoinTableHandlerInterface
-}
-
-func getForeignField(column string, fields []*StructField) *StructField {
- for _, field := range fields {
- if field.Name == column || field.DBName == column || field.DBName == ToColumnName(column) {
- return field
- }
- }
- return nil
-}
-
-// GetModelStruct get value's model struct, relationships based on struct and tag definition
-func (scope *Scope) GetModelStruct() *ModelStruct {
- return scope.getModelStruct(scope, make([]*StructField, 0))
-}
-
-func (scope *Scope) getModelStruct(rootScope *Scope, allFields []*StructField) *ModelStruct {
- var modelStruct ModelStruct
- // Scope value can't be nil
- if scope.Value == nil {
- return &modelStruct
- }
-
- reflectType := reflect.ValueOf(scope.Value).Type()
- for reflectType.Kind() == reflect.Slice || reflectType.Kind() == reflect.Ptr {
- reflectType = reflectType.Elem()
- }
-
- // Scope value need to be a struct
- if reflectType.Kind() != reflect.Struct {
- return &modelStruct
- }
-
- // Get Cached model struct
- isSingularTable := false
- if scope.db != nil && scope.db.parent != nil {
- scope.db.parent.RLock()
- isSingularTable = scope.db.parent.singularTable
- scope.db.parent.RUnlock()
- }
-
- hashKey := struct {
- singularTable bool
- reflectType reflect.Type
- }{isSingularTable, reflectType}
- if value, ok := modelStructsMap.Load(hashKey); ok && value != nil {
- return value.(*ModelStruct)
- }
-
- modelStruct.ModelType = reflectType
-
- // Get all fields
- for i := 0; i < reflectType.NumField(); i++ {
- if fieldStruct := reflectType.Field(i); ast.IsExported(fieldStruct.Name) {
- field := &StructField{
- Struct: fieldStruct,
- Name: fieldStruct.Name,
- Names: []string{fieldStruct.Name},
- Tag: fieldStruct.Tag,
- TagSettings: parseTagSetting(fieldStruct.Tag),
- }
-
- // is ignored field
- if _, ok := field.TagSettingsGet("-"); ok {
- field.IsIgnored = true
- } else {
- if _, ok := field.TagSettingsGet("PRIMARY_KEY"); ok {
- field.IsPrimaryKey = true
- modelStruct.PrimaryFields = append(modelStruct.PrimaryFields, field)
- }
-
- if _, ok := field.TagSettingsGet("DEFAULT"); ok && !field.IsPrimaryKey {
- field.HasDefaultValue = true
- }
-
- if _, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok && !field.IsPrimaryKey {
- field.HasDefaultValue = true
- }
-
- indirectType := fieldStruct.Type
- for indirectType.Kind() == reflect.Ptr {
- indirectType = indirectType.Elem()
- }
-
- fieldValue := reflect.New(indirectType).Interface()
- if _, isScanner := fieldValue.(sql.Scanner); isScanner {
- // is scanner
- field.IsScanner, field.IsNormal = true, true
- if indirectType.Kind() == reflect.Struct {
- for i := 0; i < indirectType.NumField(); i++ {
- for key, value := range parseTagSetting(indirectType.Field(i).Tag) {
- if _, ok := field.TagSettingsGet(key); !ok {
- field.TagSettingsSet(key, value)
- }
- }
- }
- }
- } else if _, isTime := fieldValue.(*time.Time); isTime {
- // is time
- field.IsNormal = true
- } else if _, ok := field.TagSettingsGet("EMBEDDED"); ok || fieldStruct.Anonymous {
- // is embedded struct
- for _, subField := range scope.New(fieldValue).getModelStruct(rootScope, allFields).StructFields {
- subField = subField.clone()
- subField.Names = append([]string{fieldStruct.Name}, subField.Names...)
- if prefix, ok := field.TagSettingsGet("EMBEDDED_PREFIX"); ok {
- subField.DBName = prefix + subField.DBName
- }
-
- if subField.IsPrimaryKey {
- if _, ok := subField.TagSettingsGet("PRIMARY_KEY"); ok {
- modelStruct.PrimaryFields = append(modelStruct.PrimaryFields, subField)
- } else {
- subField.IsPrimaryKey = false
- }
- }
-
- if subField.Relationship != nil && subField.Relationship.JoinTableHandler != nil {
- if joinTableHandler, ok := subField.Relationship.JoinTableHandler.(*JoinTableHandler); ok {
- newJoinTableHandler := &JoinTableHandler{}
- newJoinTableHandler.Setup(subField.Relationship, joinTableHandler.TableName, reflectType, joinTableHandler.Destination.ModelType)
- subField.Relationship.JoinTableHandler = newJoinTableHandler
- }
- }
-
- modelStruct.StructFields = append(modelStruct.StructFields, subField)
- allFields = append(allFields, subField)
- }
- continue
- } else {
- // build relationships
- switch indirectType.Kind() {
- case reflect.Slice:
- defer func(field *StructField) {
- var (
- relationship = &Relationship{}
- toScope = scope.New(reflect.New(field.Struct.Type).Interface())
- foreignKeys []string
- associationForeignKeys []string
- elemType = field.Struct.Type
- )
-
- if foreignKey, _ := field.TagSettingsGet("FOREIGNKEY"); foreignKey != "" {
- foreignKeys = strings.Split(foreignKey, ",")
- }
-
- if foreignKey, _ := field.TagSettingsGet("ASSOCIATION_FOREIGNKEY"); foreignKey != "" {
- associationForeignKeys = strings.Split(foreignKey, ",")
- } else if foreignKey, _ := field.TagSettingsGet("ASSOCIATIONFOREIGNKEY"); foreignKey != "" {
- associationForeignKeys = strings.Split(foreignKey, ",")
- }
-
- for elemType.Kind() == reflect.Slice || elemType.Kind() == reflect.Ptr {
- elemType = elemType.Elem()
- }
-
- if elemType.Kind() == reflect.Struct {
- if many2many, _ := field.TagSettingsGet("MANY2MANY"); many2many != "" {
- relationship.Kind = "many_to_many"
-
- { // Foreign Keys for Source
- joinTableDBNames := []string{}
-
- if foreignKey, _ := field.TagSettingsGet("JOINTABLE_FOREIGNKEY"); foreignKey != "" {
- joinTableDBNames = strings.Split(foreignKey, ",")
- }
-
- // if no foreign keys defined with tag
- if len(foreignKeys) == 0 {
- for _, field := range modelStruct.PrimaryFields {
- foreignKeys = append(foreignKeys, field.DBName)
- }
- }
-
- for idx, foreignKey := range foreignKeys {
- if foreignField := getForeignField(foreignKey, modelStruct.StructFields); foreignField != nil {
- // source foreign keys (db names)
- relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.DBName)
-
- // setup join table foreign keys for source
- if len(joinTableDBNames) > idx {
- // if defined join table's foreign key
- relationship.ForeignDBNames = append(relationship.ForeignDBNames, joinTableDBNames[idx])
- } else {
- defaultJointableForeignKey := ToColumnName(reflectType.Name()) + "_" + foreignField.DBName
- relationship.ForeignDBNames = append(relationship.ForeignDBNames, defaultJointableForeignKey)
- }
- }
- }
- }
-
- { // Foreign Keys for Association (Destination)
- associationJoinTableDBNames := []string{}
-
- if foreignKey, _ := field.TagSettingsGet("ASSOCIATION_JOINTABLE_FOREIGNKEY"); foreignKey != "" {
- associationJoinTableDBNames = strings.Split(foreignKey, ",")
- }
-
- // if no association foreign keys defined with tag
- if len(associationForeignKeys) == 0 {
- for _, field := range toScope.PrimaryFields() {
- associationForeignKeys = append(associationForeignKeys, field.DBName)
- }
- }
-
- for idx, name := range associationForeignKeys {
- if field, ok := toScope.FieldByName(name); ok {
- // association foreign keys (db names)
- relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, field.DBName)
-
- // setup join table foreign keys for association
- if len(associationJoinTableDBNames) > idx {
- relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, associationJoinTableDBNames[idx])
- } else {
- // join table foreign keys for association
- joinTableDBName := ToColumnName(elemType.Name()) + "_" + field.DBName
- relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, joinTableDBName)
- }
- }
- }
- }
-
- joinTableHandler := JoinTableHandler{}
- joinTableHandler.Setup(relationship, many2many, reflectType, elemType)
- relationship.JoinTableHandler = &joinTableHandler
- field.Relationship = relationship
- } else {
- // User has many comments, associationType is User, comment use UserID as foreign key
- var associationType = reflectType.Name()
- var toFields = toScope.GetStructFields()
- relationship.Kind = "has_many"
-
- if polymorphic, _ := field.TagSettingsGet("POLYMORPHIC"); polymorphic != "" {
- // Dog has many toys, tag polymorphic is Owner, then associationType is Owner
- // Toy use OwnerID, OwnerType ('dogs') as foreign key
- if polymorphicType := getForeignField(polymorphic+"Type", toFields); polymorphicType != nil {
- associationType = polymorphic
- relationship.PolymorphicType = polymorphicType.Name
- relationship.PolymorphicDBName = polymorphicType.DBName
- // if Dog has multiple set of toys set name of the set (instead of default 'dogs')
- if value, ok := field.TagSettingsGet("POLYMORPHIC_VALUE"); ok {
- relationship.PolymorphicValue = value
- } else {
- relationship.PolymorphicValue = scope.TableName()
- }
- polymorphicType.IsForeignKey = true
- }
- }
-
- // if no foreign keys defined with tag
- if len(foreignKeys) == 0 {
- // if no association foreign keys defined with tag
- if len(associationForeignKeys) == 0 {
- for _, field := range modelStruct.PrimaryFields {
- foreignKeys = append(foreignKeys, associationType+field.Name)
- associationForeignKeys = append(associationForeignKeys, field.Name)
- }
- } else {
- // generate foreign keys from defined association foreign keys
- for _, scopeFieldName := range associationForeignKeys {
- if foreignField := getForeignField(scopeFieldName, allFields); foreignField != nil {
- foreignKeys = append(foreignKeys, associationType+foreignField.Name)
- associationForeignKeys = append(associationForeignKeys, foreignField.Name)
- }
- }
- }
- } else {
- // generate association foreign keys from foreign keys
- if len(associationForeignKeys) == 0 {
- for _, foreignKey := range foreignKeys {
- if strings.HasPrefix(foreignKey, associationType) {
- associationForeignKey := strings.TrimPrefix(foreignKey, associationType)
- if foreignField := getForeignField(associationForeignKey, allFields); foreignField != nil {
- associationForeignKeys = append(associationForeignKeys, associationForeignKey)
- }
- }
- }
- if len(associationForeignKeys) == 0 && len(foreignKeys) == 1 {
- associationForeignKeys = []string{rootScope.PrimaryKey()}
- }
- } else if len(foreignKeys) != len(associationForeignKeys) {
- scope.Err(errors.New("invalid foreign keys, should have same length"))
- return
- }
- }
-
- for idx, foreignKey := range foreignKeys {
- if foreignField := getForeignField(foreignKey, toFields); foreignField != nil {
- if associationField := getForeignField(associationForeignKeys[idx], allFields); associationField != nil {
- // mark field as foreignkey, use global lock to avoid race
- structsLock.Lock()
- foreignField.IsForeignKey = true
- structsLock.Unlock()
-
- // association foreign keys
- relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, associationField.Name)
- relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, associationField.DBName)
-
- // association foreign keys
- relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.Name)
- relationship.ForeignDBNames = append(relationship.ForeignDBNames, foreignField.DBName)
- }
- }
- }
-
- if len(relationship.ForeignFieldNames) != 0 {
- field.Relationship = relationship
- }
- }
- } else {
- field.IsNormal = true
- }
- }(field)
- case reflect.Struct:
- defer func(field *StructField) {
- var (
- // user has one profile, associationType is User, profile use UserID as foreign key
- // user belongs to profile, associationType is Profile, user use ProfileID as foreign key
- associationType = reflectType.Name()
- relationship = &Relationship{}
- toScope = scope.New(reflect.New(field.Struct.Type).Interface())
- toFields = toScope.GetStructFields()
- tagForeignKeys []string
- tagAssociationForeignKeys []string
- )
-
- if foreignKey, _ := field.TagSettingsGet("FOREIGNKEY"); foreignKey != "" {
- tagForeignKeys = strings.Split(foreignKey, ",")
- }
-
- if foreignKey, _ := field.TagSettingsGet("ASSOCIATION_FOREIGNKEY"); foreignKey != "" {
- tagAssociationForeignKeys = strings.Split(foreignKey, ",")
- } else if foreignKey, _ := field.TagSettingsGet("ASSOCIATIONFOREIGNKEY"); foreignKey != "" {
- tagAssociationForeignKeys = strings.Split(foreignKey, ",")
- }
-
- if polymorphic, _ := field.TagSettingsGet("POLYMORPHIC"); polymorphic != "" {
- // Cat has one toy, tag polymorphic is Owner, then associationType is Owner
- // Toy use OwnerID, OwnerType ('cats') as foreign key
- if polymorphicType := getForeignField(polymorphic+"Type", toFields); polymorphicType != nil {
- associationType = polymorphic
- relationship.PolymorphicType = polymorphicType.Name
- relationship.PolymorphicDBName = polymorphicType.DBName
- // if Cat has several different types of toys set name for each (instead of default 'cats')
- if value, ok := field.TagSettingsGet("POLYMORPHIC_VALUE"); ok {
- relationship.PolymorphicValue = value
- } else {
- relationship.PolymorphicValue = scope.TableName()
- }
- polymorphicType.IsForeignKey = true
- }
- }
-
- // Has One
- {
- var foreignKeys = tagForeignKeys
- var associationForeignKeys = tagAssociationForeignKeys
- // if no foreign keys defined with tag
- if len(foreignKeys) == 0 {
- // if no association foreign keys defined with tag
- if len(associationForeignKeys) == 0 {
- for _, primaryField := range modelStruct.PrimaryFields {
- foreignKeys = append(foreignKeys, associationType+primaryField.Name)
- associationForeignKeys = append(associationForeignKeys, primaryField.Name)
- }
- } else {
- // generate foreign keys form association foreign keys
- for _, associationForeignKey := range tagAssociationForeignKeys {
- if foreignField := getForeignField(associationForeignKey, allFields); foreignField != nil {
- foreignKeys = append(foreignKeys, associationType+foreignField.Name)
- associationForeignKeys = append(associationForeignKeys, foreignField.Name)
- }
- }
- }
- } else {
- // generate association foreign keys from foreign keys
- if len(associationForeignKeys) == 0 {
- for _, foreignKey := range foreignKeys {
- if strings.HasPrefix(foreignKey, associationType) {
- associationForeignKey := strings.TrimPrefix(foreignKey, associationType)
- if foreignField := getForeignField(associationForeignKey, allFields); foreignField != nil {
- associationForeignKeys = append(associationForeignKeys, associationForeignKey)
- }
- }
- }
- if len(associationForeignKeys) == 0 && len(foreignKeys) == 1 {
- associationForeignKeys = []string{rootScope.PrimaryKey()}
- }
- } else if len(foreignKeys) != len(associationForeignKeys) {
- scope.Err(errors.New("invalid foreign keys, should have same length"))
- return
- }
- }
-
- for idx, foreignKey := range foreignKeys {
- if foreignField := getForeignField(foreignKey, toFields); foreignField != nil {
- if scopeField := getForeignField(associationForeignKeys[idx], allFields); scopeField != nil {
- // mark field as foreignkey, use global lock to avoid race
- structsLock.Lock()
- foreignField.IsForeignKey = true
- structsLock.Unlock()
-
- // association foreign keys
- relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, scopeField.Name)
- relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, scopeField.DBName)
-
- // association foreign keys
- relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.Name)
- relationship.ForeignDBNames = append(relationship.ForeignDBNames, foreignField.DBName)
- }
- }
- }
- }
-
- if len(relationship.ForeignFieldNames) != 0 {
- relationship.Kind = "has_one"
- field.Relationship = relationship
- } else {
- var foreignKeys = tagForeignKeys
- var associationForeignKeys = tagAssociationForeignKeys
-
- if len(foreignKeys) == 0 {
- // generate foreign keys & association foreign keys
- if len(associationForeignKeys) == 0 {
- for _, primaryField := range toScope.PrimaryFields() {
- foreignKeys = append(foreignKeys, field.Name+primaryField.Name)
- associationForeignKeys = append(associationForeignKeys, primaryField.Name)
- }
- } else {
- // generate foreign keys with association foreign keys
- for _, associationForeignKey := range associationForeignKeys {
- if foreignField := getForeignField(associationForeignKey, toFields); foreignField != nil {
- foreignKeys = append(foreignKeys, field.Name+foreignField.Name)
- associationForeignKeys = append(associationForeignKeys, foreignField.Name)
- }
- }
- }
- } else {
- // generate foreign keys & association foreign keys
- if len(associationForeignKeys) == 0 {
- for _, foreignKey := range foreignKeys {
- if strings.HasPrefix(foreignKey, field.Name) {
- associationForeignKey := strings.TrimPrefix(foreignKey, field.Name)
- if foreignField := getForeignField(associationForeignKey, toFields); foreignField != nil {
- associationForeignKeys = append(associationForeignKeys, associationForeignKey)
- }
- }
- }
- if len(associationForeignKeys) == 0 && len(foreignKeys) == 1 {
- associationForeignKeys = []string{toScope.PrimaryKey()}
- }
- } else if len(foreignKeys) != len(associationForeignKeys) {
- scope.Err(errors.New("invalid foreign keys, should have same length"))
- return
- }
- }
-
- for idx, foreignKey := range foreignKeys {
- if foreignField := getForeignField(foreignKey, modelStruct.StructFields); foreignField != nil {
- if associationField := getForeignField(associationForeignKeys[idx], toFields); associationField != nil {
- // mark field as foreignkey, use global lock to avoid race
- structsLock.Lock()
- foreignField.IsForeignKey = true
- structsLock.Unlock()
-
- // association foreign keys
- relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, associationField.Name)
- relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, associationField.DBName)
-
- // source foreign keys
- relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.Name)
- relationship.ForeignDBNames = append(relationship.ForeignDBNames, foreignField.DBName)
- }
- }
- }
-
- if len(relationship.ForeignFieldNames) != 0 {
- relationship.Kind = "belongs_to"
- field.Relationship = relationship
- }
- }
- }(field)
- default:
- field.IsNormal = true
- }
- }
- }
-
- // Even it is ignored, also possible to decode db value into the field
- if value, ok := field.TagSettingsGet("COLUMN"); ok {
- field.DBName = value
- } else {
- field.DBName = ToColumnName(fieldStruct.Name)
- }
-
- modelStruct.StructFields = append(modelStruct.StructFields, field)
- allFields = append(allFields, field)
- }
- }
-
- if len(modelStruct.PrimaryFields) == 0 {
- if field := getForeignField("id", modelStruct.StructFields); field != nil {
- field.IsPrimaryKey = true
- modelStruct.PrimaryFields = append(modelStruct.PrimaryFields, field)
- }
- }
-
- modelStructsMap.Store(hashKey, &modelStruct)
-
- return &modelStruct
-}
-
-// GetStructFields get model's field structs
-func (scope *Scope) GetStructFields() (fields []*StructField) {
- return scope.GetModelStruct().StructFields
-}
-
-func parseTagSetting(tags reflect.StructTag) map[string]string {
- setting := map[string]string{}
- for _, str := range []string{tags.Get("sql"), tags.Get("gorm")} {
- if str == "" {
- continue
- }
- tags := strings.Split(str, ";")
- for _, value := range tags {
- v := strings.Split(value, ":")
- k := strings.TrimSpace(strings.ToUpper(v[0]))
- if len(v) >= 2 {
- setting[k] = strings.Join(v[1:], ":")
- } else {
- setting[k] = k
- }
- }
- }
- return setting
-}
diff --git a/vendor/github.com/jinzhu/gorm/naming.go b/vendor/github.com/jinzhu/gorm/naming.go
deleted file mode 100644
index 6b0a4fd..0000000
--- a/vendor/github.com/jinzhu/gorm/naming.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package gorm
-
-import (
- "bytes"
- "strings"
-)
-
-// Namer is a function type which is given a string and return a string
-type Namer func(string) string
-
-// NamingStrategy represents naming strategies
-type NamingStrategy struct {
- DB Namer
- Table Namer
- Column Namer
-}
-
-// TheNamingStrategy is being initialized with defaultNamingStrategy
-var TheNamingStrategy = &NamingStrategy{
- DB: defaultNamer,
- Table: defaultNamer,
- Column: defaultNamer,
-}
-
-// AddNamingStrategy sets the naming strategy
-func AddNamingStrategy(ns *NamingStrategy) {
- if ns.DB == nil {
- ns.DB = defaultNamer
- }
- if ns.Table == nil {
- ns.Table = defaultNamer
- }
- if ns.Column == nil {
- ns.Column = defaultNamer
- }
- TheNamingStrategy = ns
-}
-
-// DBName alters the given name by DB
-func (ns *NamingStrategy) DBName(name string) string {
- return ns.DB(name)
-}
-
-// TableName alters the given name by Table
-func (ns *NamingStrategy) TableName(name string) string {
- return ns.Table(name)
-}
-
-// ColumnName alters the given name by Column
-func (ns *NamingStrategy) ColumnName(name string) string {
- return ns.Column(name)
-}
-
-// ToDBName convert string to db name
-func ToDBName(name string) string {
- return TheNamingStrategy.DBName(name)
-}
-
-// ToTableName convert string to table name
-func ToTableName(name string) string {
- return TheNamingStrategy.TableName(name)
-}
-
-// ToColumnName convert string to db name
-func ToColumnName(name string) string {
- return TheNamingStrategy.ColumnName(name)
-}
-
-var smap = newSafeMap()
-
-func defaultNamer(name string) string {
- const (
- lower = false
- upper = true
- )
-
- if v := smap.Get(name); v != "" {
- return v
- }
-
- if name == "" {
- return ""
- }
-
- var (
- value = commonInitialismsReplacer.Replace(name)
- buf = bytes.NewBufferString("")
- lastCase, currCase, nextCase, nextNumber bool
- )
-
- for i, v := range value[:len(value)-1] {
- nextCase = bool(value[i+1] >= 'A' && value[i+1] <= 'Z')
- nextNumber = bool(value[i+1] >= '0' && value[i+1] <= '9')
-
- if i > 0 {
- if currCase == upper {
- if lastCase == upper && (nextCase == upper || nextNumber == upper) {
- buf.WriteRune(v)
- } else {
- if value[i-1] != '_' && value[i+1] != '_' {
- buf.WriteRune('_')
- }
- buf.WriteRune(v)
- }
- } else {
- buf.WriteRune(v)
- if i == len(value)-2 && (nextCase == upper && nextNumber == lower) {
- buf.WriteRune('_')
- }
- }
- } else {
- currCase = upper
- buf.WriteRune(v)
- }
- lastCase = currCase
- currCase = nextCase
- }
-
- buf.WriteByte(value[len(value)-1])
-
- s := strings.ToLower(buf.String())
- smap.Set(name, s)
- return s
-}
diff --git a/vendor/github.com/jinzhu/gorm/scope.go b/vendor/github.com/jinzhu/gorm/scope.go
deleted file mode 100644
index 56c3d6e..0000000
--- a/vendor/github.com/jinzhu/gorm/scope.go
+++ /dev/null
@@ -1,1425 +0,0 @@
-package gorm
-
-import (
- "bytes"
- "database/sql"
- "database/sql/driver"
- "errors"
- "fmt"
- "reflect"
- "regexp"
- "strings"
- "time"
-)
-
-// Scope contain current operation's information when you perform any operation on the database
-type Scope struct {
- Search *search
- Value interface{}
- SQL string
- SQLVars []interface{}
- db *DB
- instanceID string
- primaryKeyField *Field
- skipLeft bool
- fields *[]*Field
- selectAttrs *[]string
-}
-
-// IndirectValue return scope's reflect value's indirect value
-func (scope *Scope) IndirectValue() reflect.Value {
- return indirect(reflect.ValueOf(scope.Value))
-}
-
-// New create a new Scope without search information
-func (scope *Scope) New(value interface{}) *Scope {
- return &Scope{db: scope.NewDB(), Search: &search{}, Value: value}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Scope DB
-////////////////////////////////////////////////////////////////////////////////
-
-// DB return scope's DB connection
-func (scope *Scope) DB() *DB {
- return scope.db
-}
-
-// NewDB create a new DB without search information
-func (scope *Scope) NewDB() *DB {
- if scope.db != nil {
- db := scope.db.clone()
- db.search = nil
- db.Value = nil
- return db
- }
- return nil
-}
-
-// SQLDB return *sql.DB
-func (scope *Scope) SQLDB() SQLCommon {
- return scope.db.db
-}
-
-// Dialect get dialect
-func (scope *Scope) Dialect() Dialect {
- return scope.db.dialect
-}
-
-// Quote used to quote string to escape them for database
-func (scope *Scope) Quote(str string) string {
- if strings.Contains(str, ".") {
- newStrs := []string{}
- for _, str := range strings.Split(str, ".") {
- newStrs = append(newStrs, scope.Dialect().Quote(str))
- }
- return strings.Join(newStrs, ".")
- }
-
- return scope.Dialect().Quote(str)
-}
-
-// Err add error to Scope
-func (scope *Scope) Err(err error) error {
- if err != nil {
- scope.db.AddError(err)
- }
- return err
-}
-
-// HasError check if there are any error
-func (scope *Scope) HasError() bool {
- return scope.db.Error != nil
-}
-
-// Log print log message
-func (scope *Scope) Log(v ...interface{}) {
- scope.db.log(v...)
-}
-
-// SkipLeft skip remaining callbacks
-func (scope *Scope) SkipLeft() {
- scope.skipLeft = true
-}
-
-// Fields get value's fields
-func (scope *Scope) Fields() []*Field {
- if scope.fields == nil {
- var (
- fields []*Field
- indirectScopeValue = scope.IndirectValue()
- isStruct = indirectScopeValue.Kind() == reflect.Struct
- )
-
- for _, structField := range scope.GetModelStruct().StructFields {
- if isStruct {
- fieldValue := indirectScopeValue
- for _, name := range structField.Names {
- if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
- fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
- }
- fieldValue = reflect.Indirect(fieldValue).FieldByName(name)
- }
- fields = append(fields, &Field{StructField: structField, Field: fieldValue, IsBlank: isBlank(fieldValue)})
- } else {
- fields = append(fields, &Field{StructField: structField, IsBlank: true})
- }
- }
- scope.fields = &fields
- }
-
- return *scope.fields
-}
-
-// FieldByName find `gorm.Field` with field name or db name
-func (scope *Scope) FieldByName(name string) (field *Field, ok bool) {
- var (
- dbName = ToColumnName(name)
- mostMatchedField *Field
- )
-
- for _, field := range scope.Fields() {
- if field.Name == name || field.DBName == name {
- return field, true
- }
- if field.DBName == dbName {
- mostMatchedField = field
- }
- }
- return mostMatchedField, mostMatchedField != nil
-}
-
-// PrimaryFields return scope's primary fields
-func (scope *Scope) PrimaryFields() (fields []*Field) {
- for _, field := range scope.Fields() {
- if field.IsPrimaryKey {
- fields = append(fields, field)
- }
- }
- return fields
-}
-
-// PrimaryField return scope's main primary field, if defined more that one primary fields, will return the one having column name `id` or the first one
-func (scope *Scope) PrimaryField() *Field {
- if primaryFields := scope.GetModelStruct().PrimaryFields; len(primaryFields) > 0 {
- if len(primaryFields) > 1 {
- if field, ok := scope.FieldByName("id"); ok {
- return field
- }
- }
- return scope.PrimaryFields()[0]
- }
- return nil
-}
-
-// PrimaryKey get main primary field's db name
-func (scope *Scope) PrimaryKey() string {
- if field := scope.PrimaryField(); field != nil {
- return field.DBName
- }
- return ""
-}
-
-// PrimaryKeyZero check main primary field's value is blank or not
-func (scope *Scope) PrimaryKeyZero() bool {
- field := scope.PrimaryField()
- return field == nil || field.IsBlank
-}
-
-// PrimaryKeyValue get the primary key's value
-func (scope *Scope) PrimaryKeyValue() interface{} {
- if field := scope.PrimaryField(); field != nil && field.Field.IsValid() {
- return field.Field.Interface()
- }
- return 0
-}
-
-// HasColumn to check if has column
-func (scope *Scope) HasColumn(column string) bool {
- for _, field := range scope.GetStructFields() {
- if field.IsNormal && (field.Name == column || field.DBName == column) {
- return true
- }
- }
- return false
-}
-
-// SetColumn to set the column's value, column could be field or field's name/dbname
-func (scope *Scope) SetColumn(column interface{}, value interface{}) error {
- var updateAttrs = map[string]interface{}{}
- if attrs, ok := scope.InstanceGet("gorm:update_attrs"); ok {
- updateAttrs = attrs.(map[string]interface{})
- defer scope.InstanceSet("gorm:update_attrs", updateAttrs)
- }
-
- if field, ok := column.(*Field); ok {
- updateAttrs[field.DBName] = value
- return field.Set(value)
- } else if name, ok := column.(string); ok {
- var (
- dbName = ToDBName(name)
- mostMatchedField *Field
- )
- for _, field := range scope.Fields() {
- if field.DBName == value {
- updateAttrs[field.DBName] = value
- return field.Set(value)
- }
- if !field.IsIgnored && ((field.DBName == dbName) || (field.Name == name && mostMatchedField == nil)) {
- mostMatchedField = field
- }
- }
-
- if mostMatchedField != nil {
- updateAttrs[mostMatchedField.DBName] = value
- return mostMatchedField.Set(value)
- }
- }
- return errors.New("could not convert column to field")
-}
-
-// CallMethod call scope value's method, if it is a slice, will call its element's method one by one
-func (scope *Scope) CallMethod(methodName string) {
- if scope.Value == nil {
- return
- }
-
- if indirectScopeValue := scope.IndirectValue(); indirectScopeValue.Kind() == reflect.Slice {
- for i := 0; i < indirectScopeValue.Len(); i++ {
- scope.callMethod(methodName, indirectScopeValue.Index(i))
- }
- } else {
- scope.callMethod(methodName, indirectScopeValue)
- }
-}
-
-// AddToVars add value as sql's vars, used to prevent SQL injection
-func (scope *Scope) AddToVars(value interface{}) string {
- _, skipBindVar := scope.InstanceGet("skip_bindvar")
-
- if expr, ok := value.(*SqlExpr); ok {
- exp := expr.expr
- for _, arg := range expr.args {
- if skipBindVar {
- scope.AddToVars(arg)
- } else {
- exp = strings.Replace(exp, "?", scope.AddToVars(arg), 1)
- }
- }
- return exp
- }
-
- scope.SQLVars = append(scope.SQLVars, value)
-
- if skipBindVar {
- return "?"
- }
- return scope.Dialect().BindVar(len(scope.SQLVars))
-}
-
-// SelectAttrs return selected attributes
-func (scope *Scope) SelectAttrs() []string {
- if scope.selectAttrs == nil {
- attrs := []string{}
- for _, value := range scope.Search.selects {
- if str, ok := value.(string); ok {
- attrs = append(attrs, str)
- } else if strs, ok := value.([]string); ok {
- attrs = append(attrs, strs...)
- } else if strs, ok := value.([]interface{}); ok {
- for _, str := range strs {
- attrs = append(attrs, fmt.Sprintf("%v", str))
- }
- }
- }
- scope.selectAttrs = &attrs
- }
- return *scope.selectAttrs
-}
-
-// OmitAttrs return omitted attributes
-func (scope *Scope) OmitAttrs() []string {
- return scope.Search.omits
-}
-
-type tabler interface {
- TableName() string
-}
-
-type dbTabler interface {
- TableName(*DB) string
-}
-
-// TableName return table name
-func (scope *Scope) TableName() string {
- if scope.Search != nil && len(scope.Search.tableName) > 0 {
- return scope.Search.tableName
- }
-
- if tabler, ok := scope.Value.(tabler); ok {
- return tabler.TableName()
- }
-
- if tabler, ok := scope.Value.(dbTabler); ok {
- return tabler.TableName(scope.db)
- }
-
- return scope.GetModelStruct().TableName(scope.db.Model(scope.Value))
-}
-
-// QuotedTableName return quoted table name
-func (scope *Scope) QuotedTableName() (name string) {
- if scope.Search != nil && len(scope.Search.tableName) > 0 {
- if strings.Contains(scope.Search.tableName, " ") {
- return scope.Search.tableName
- }
- return scope.Quote(scope.Search.tableName)
- }
-
- return scope.Quote(scope.TableName())
-}
-
-// CombinedConditionSql return combined condition sql
-func (scope *Scope) CombinedConditionSql() string {
- joinSQL := scope.joinsSQL()
- whereSQL := scope.whereSQL()
- if scope.Search.raw {
- whereSQL = strings.TrimSuffix(strings.TrimPrefix(whereSQL, "WHERE ("), ")")
- }
- return joinSQL + whereSQL + scope.groupSQL() +
- scope.havingSQL() + scope.orderSQL() + scope.limitAndOffsetSQL()
-}
-
-// Raw set raw sql
-func (scope *Scope) Raw(sql string) *Scope {
- scope.SQL = strings.Replace(sql, "$$$", "?", -1)
- return scope
-}
-
-// Exec perform generated SQL
-func (scope *Scope) Exec() *Scope {
- defer scope.trace(NowFunc())
-
- if !scope.HasError() {
- if result, err := scope.SQLDB().Exec(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
- if count, err := result.RowsAffected(); scope.Err(err) == nil {
- scope.db.RowsAffected = count
- }
- }
- }
- return scope
-}
-
-// Set set value by name
-func (scope *Scope) Set(name string, value interface{}) *Scope {
- scope.db.InstantSet(name, value)
- return scope
-}
-
-// Get get setting by name
-func (scope *Scope) Get(name string) (interface{}, bool) {
- return scope.db.Get(name)
-}
-
-// InstanceID get InstanceID for scope
-func (scope *Scope) InstanceID() string {
- if scope.instanceID == "" {
- scope.instanceID = fmt.Sprintf("%v%v", &scope, &scope.db)
- }
- return scope.instanceID
-}
-
-// InstanceSet set instance setting for current operation, but not for operations in callbacks, like saving associations callback
-func (scope *Scope) InstanceSet(name string, value interface{}) *Scope {
- return scope.Set(name+scope.InstanceID(), value)
-}
-
-// InstanceGet get instance setting from current operation
-func (scope *Scope) InstanceGet(name string) (interface{}, bool) {
- return scope.Get(name + scope.InstanceID())
-}
-
-// Begin start a transaction
-func (scope *Scope) Begin() *Scope {
- if db, ok := scope.SQLDB().(sqlDb); ok {
- if tx, err := db.Begin(); scope.Err(err) == nil {
- scope.db.db = interface{}(tx).(SQLCommon)
- scope.InstanceSet("gorm:started_transaction", true)
- }
- }
- return scope
-}
-
-// CommitOrRollback commit current transaction if no error happened, otherwise will rollback it
-func (scope *Scope) CommitOrRollback() *Scope {
- if _, ok := scope.InstanceGet("gorm:started_transaction"); ok {
- if db, ok := scope.db.db.(sqlTx); ok {
- if scope.HasError() {
- db.Rollback()
- } else {
- scope.Err(db.Commit())
- }
- scope.db.db = scope.db.parent.db
- }
- }
- return scope
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Private Methods For *gorm.Scope
-////////////////////////////////////////////////////////////////////////////////
-
-func (scope *Scope) callMethod(methodName string, reflectValue reflect.Value) {
- // Only get address from non-pointer
- if reflectValue.CanAddr() && reflectValue.Kind() != reflect.Ptr {
- reflectValue = reflectValue.Addr()
- }
-
- if methodValue := reflectValue.MethodByName(methodName); methodValue.IsValid() {
- switch method := methodValue.Interface().(type) {
- case func():
- method()
- case func(*Scope):
- method(scope)
- case func(*DB):
- newDB := scope.NewDB()
- method(newDB)
- scope.Err(newDB.Error)
- case func() error:
- scope.Err(method())
- case func(*Scope) error:
- scope.Err(method(scope))
- case func(*DB) error:
- newDB := scope.NewDB()
- scope.Err(method(newDB))
- scope.Err(newDB.Error)
- default:
- scope.Err(fmt.Errorf("unsupported function %v", methodName))
- }
- }
-}
-
-var (
- columnRegexp = regexp.MustCompile("^[a-zA-Z\\d]+(\\.[a-zA-Z\\d]+)*$") // only match string like `name`, `users.name`
- isNumberRegexp = regexp.MustCompile("^\\s*\\d+\\s*$") // match if string is number
- comparisonRegexp = regexp.MustCompile("(?i) (=|<>|(>|<)(=?)|LIKE|IS|IN) ")
- countingQueryRegexp = regexp.MustCompile("(?i)^count(.+)$")
-)
-
-func (scope *Scope) quoteIfPossible(str string) string {
- if columnRegexp.MatchString(str) {
- return scope.Quote(str)
- }
- return str
-}
-
-func (scope *Scope) scan(rows *sql.Rows, columns []string, fields []*Field) {
- var (
- ignored interface{}
- values = make([]interface{}, len(columns))
- selectFields []*Field
- selectedColumnsMap = map[string]int{}
- resetFields = map[int]*Field{}
- )
-
- for index, column := range columns {
- values[index] = &ignored
-
- selectFields = fields
- offset := 0
- if idx, ok := selectedColumnsMap[column]; ok {
- offset = idx + 1
- selectFields = selectFields[offset:]
- }
-
- for fieldIndex, field := range selectFields {
- if field.DBName == column {
- if field.Field.Kind() == reflect.Ptr {
- values[index] = field.Field.Addr().Interface()
- } else {
- reflectValue := reflect.New(reflect.PtrTo(field.Struct.Type))
- reflectValue.Elem().Set(field.Field.Addr())
- values[index] = reflectValue.Interface()
- resetFields[index] = field
- }
-
- selectedColumnsMap[column] = offset + fieldIndex
-
- if field.IsNormal {
- break
- }
- }
- }
- }
-
- scope.Err(rows.Scan(values...))
-
- for index, field := range resetFields {
- if v := reflect.ValueOf(values[index]).Elem().Elem(); v.IsValid() {
- field.Field.Set(v)
- }
- }
-}
-
-func (scope *Scope) primaryCondition(value interface{}) string {
- return fmt.Sprintf("(%v.%v = %v)", scope.QuotedTableName(), scope.Quote(scope.PrimaryKey()), value)
-}
-
-func (scope *Scope) buildCondition(clause map[string]interface{}, include bool) (str string) {
- var (
- quotedTableName = scope.QuotedTableName()
- quotedPrimaryKey = scope.Quote(scope.PrimaryKey())
- equalSQL = "="
- inSQL = "IN"
- )
-
- // If building not conditions
- if !include {
- equalSQL = "<>"
- inSQL = "NOT IN"
- }
-
- switch value := clause["query"].(type) {
- case sql.NullInt64:
- return fmt.Sprintf("(%v.%v %s %v)", quotedTableName, quotedPrimaryKey, equalSQL, value.Int64)
- case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
- return fmt.Sprintf("(%v.%v %s %v)", quotedTableName, quotedPrimaryKey, equalSQL, value)
- case []int, []int8, []int16, []int32, []int64, []uint, []uint8, []uint16, []uint32, []uint64, []string, []interface{}:
- if !include && reflect.ValueOf(value).Len() == 0 {
- return
- }
- str = fmt.Sprintf("(%v.%v %s (?))", quotedTableName, quotedPrimaryKey, inSQL)
- clause["args"] = []interface{}{value}
- case string:
- if isNumberRegexp.MatchString(value) {
- return fmt.Sprintf("(%v.%v %s %v)", quotedTableName, quotedPrimaryKey, equalSQL, scope.AddToVars(value))
- }
-
- if value != "" {
- if !include {
- if comparisonRegexp.MatchString(value) {
- str = fmt.Sprintf("NOT (%v)", value)
- } else {
- str = fmt.Sprintf("(%v.%v NOT IN (?))", quotedTableName, scope.Quote(value))
- }
- } else {
- str = fmt.Sprintf("(%v)", value)
- }
- }
- case map[string]interface{}:
- var sqls []string
- for key, value := range value {
- if value != nil {
- sqls = append(sqls, fmt.Sprintf("(%v.%v %s %v)", quotedTableName, scope.Quote(key), equalSQL, scope.AddToVars(value)))
- } else {
- if !include {
- sqls = append(sqls, fmt.Sprintf("(%v.%v IS NOT NULL)", quotedTableName, scope.Quote(key)))
- } else {
- sqls = append(sqls, fmt.Sprintf("(%v.%v IS NULL)", quotedTableName, scope.Quote(key)))
- }
- }
- }
- return strings.Join(sqls, " AND ")
- case interface{}:
- var sqls []string
- newScope := scope.New(value)
-
- if len(newScope.Fields()) == 0 {
- scope.Err(fmt.Errorf("invalid query condition: %v", value))
- return
- }
- scopeQuotedTableName := newScope.QuotedTableName()
- for _, field := range newScope.Fields() {
- if !field.IsIgnored && !field.IsBlank && field.Relationship == nil {
- sqls = append(sqls, fmt.Sprintf("(%v.%v %s %v)", scopeQuotedTableName, scope.Quote(field.DBName), equalSQL, scope.AddToVars(field.Field.Interface())))
- }
- }
- return strings.Join(sqls, " AND ")
- default:
- scope.Err(fmt.Errorf("invalid query condition: %v", value))
- return
- }
-
- replacements := []string{}
- args := clause["args"].([]interface{})
- for _, arg := range args {
- var err error
- switch reflect.ValueOf(arg).Kind() {
- case reflect.Slice: // For where("id in (?)", []int64{1,2})
- if scanner, ok := interface{}(arg).(driver.Valuer); ok {
- arg, err = scanner.Value()
- replacements = append(replacements, scope.AddToVars(arg))
- } else if b, ok := arg.([]byte); ok {
- replacements = append(replacements, scope.AddToVars(b))
- } else if as, ok := arg.([][]interface{}); ok {
- var tempMarks []string
- for _, a := range as {
- var arrayMarks []string
- for _, v := range a {
- arrayMarks = append(arrayMarks, scope.AddToVars(v))
- }
-
- if len(arrayMarks) > 0 {
- tempMarks = append(tempMarks, fmt.Sprintf("(%v)", strings.Join(arrayMarks, ",")))
- }
- }
-
- if len(tempMarks) > 0 {
- replacements = append(replacements, strings.Join(tempMarks, ","))
- }
- } else if values := reflect.ValueOf(arg); values.Len() > 0 {
- var tempMarks []string
- for i := 0; i < values.Len(); i++ {
- tempMarks = append(tempMarks, scope.AddToVars(values.Index(i).Interface()))
- }
- replacements = append(replacements, strings.Join(tempMarks, ","))
- } else {
- replacements = append(replacements, scope.AddToVars(Expr("NULL")))
- }
- default:
- if valuer, ok := interface{}(arg).(driver.Valuer); ok {
- arg, err = valuer.Value()
- }
-
- replacements = append(replacements, scope.AddToVars(arg))
- }
-
- if err != nil {
- scope.Err(err)
- }
- }
-
- buff := bytes.NewBuffer([]byte{})
- i := 0
- for _, s := range str {
- if s == '?' && len(replacements) > i {
- buff.WriteString(replacements[i])
- i++
- } else {
- buff.WriteRune(s)
- }
- }
-
- str = buff.String()
-
- return
-}
-
-func (scope *Scope) buildSelectQuery(clause map[string]interface{}) (str string) {
- switch value := clause["query"].(type) {
- case string:
- str = value
- case []string:
- str = strings.Join(value, ", ")
- }
-
- args := clause["args"].([]interface{})
- replacements := []string{}
- for _, arg := range args {
- switch reflect.ValueOf(arg).Kind() {
- case reflect.Slice:
- values := reflect.ValueOf(arg)
- var tempMarks []string
- for i := 0; i < values.Len(); i++ {
- tempMarks = append(tempMarks, scope.AddToVars(values.Index(i).Interface()))
- }
- replacements = append(replacements, strings.Join(tempMarks, ","))
- default:
- if valuer, ok := interface{}(arg).(driver.Valuer); ok {
- arg, _ = valuer.Value()
- }
- replacements = append(replacements, scope.AddToVars(arg))
- }
- }
-
- buff := bytes.NewBuffer([]byte{})
- i := 0
- for pos, char := range str {
- if str[pos] == '?' {
- buff.WriteString(replacements[i])
- i++
- } else {
- buff.WriteRune(char)
- }
- }
-
- str = buff.String()
-
- return
-}
-
-func (scope *Scope) whereSQL() (sql string) {
- var (
- quotedTableName = scope.QuotedTableName()
- deletedAtField, hasDeletedAtField = scope.FieldByName("DeletedAt")
- primaryConditions, andConditions, orConditions []string
- )
-
- if !scope.Search.Unscoped && hasDeletedAtField {
- sql := fmt.Sprintf("%v.%v IS NULL", quotedTableName, scope.Quote(deletedAtField.DBName))
- primaryConditions = append(primaryConditions, sql)
- }
-
- if !scope.PrimaryKeyZero() {
- for _, field := range scope.PrimaryFields() {
- sql := fmt.Sprintf("%v.%v = %v", quotedTableName, scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface()))
- primaryConditions = append(primaryConditions, sql)
- }
- }
-
- for _, clause := range scope.Search.whereConditions {
- if sql := scope.buildCondition(clause, true); sql != "" {
- andConditions = append(andConditions, sql)
- }
- }
-
- for _, clause := range scope.Search.orConditions {
- if sql := scope.buildCondition(clause, true); sql != "" {
- orConditions = append(orConditions, sql)
- }
- }
-
- for _, clause := range scope.Search.notConditions {
- if sql := scope.buildCondition(clause, false); sql != "" {
- andConditions = append(andConditions, sql)
- }
- }
-
- orSQL := strings.Join(orConditions, " OR ")
- combinedSQL := strings.Join(andConditions, " AND ")
- if len(combinedSQL) > 0 {
- if len(orSQL) > 0 {
- combinedSQL = combinedSQL + " OR " + orSQL
- }
- } else {
- combinedSQL = orSQL
- }
-
- if len(primaryConditions) > 0 {
- sql = "WHERE " + strings.Join(primaryConditions, " AND ")
- if len(combinedSQL) > 0 {
- sql = sql + " AND (" + combinedSQL + ")"
- }
- } else if len(combinedSQL) > 0 {
- sql = "WHERE " + combinedSQL
- }
- return
-}
-
-func (scope *Scope) selectSQL() string {
- if len(scope.Search.selects) == 0 {
- if len(scope.Search.joinConditions) > 0 {
- return fmt.Sprintf("%v.*", scope.QuotedTableName())
- }
- return "*"
- }
- return scope.buildSelectQuery(scope.Search.selects)
-}
-
-func (scope *Scope) orderSQL() string {
- if len(scope.Search.orders) == 0 || scope.Search.ignoreOrderQuery {
- return ""
- }
-
- var orders []string
- for _, order := range scope.Search.orders {
- if str, ok := order.(string); ok {
- orders = append(orders, scope.quoteIfPossible(str))
- } else if expr, ok := order.(*SqlExpr); ok {
- exp := expr.expr
- for _, arg := range expr.args {
- exp = strings.Replace(exp, "?", scope.AddToVars(arg), 1)
- }
- orders = append(orders, exp)
- }
- }
- return " ORDER BY " + strings.Join(orders, ",")
-}
-
-func (scope *Scope) limitAndOffsetSQL() string {
- sql, err := scope.Dialect().LimitAndOffsetSQL(scope.Search.limit, scope.Search.offset)
- scope.Err(err)
- return sql
-}
-
-func (scope *Scope) groupSQL() string {
- if len(scope.Search.group) == 0 {
- return ""
- }
- return " GROUP BY " + scope.Search.group
-}
-
-func (scope *Scope) havingSQL() string {
- if len(scope.Search.havingConditions) == 0 {
- return ""
- }
-
- var andConditions []string
- for _, clause := range scope.Search.havingConditions {
- if sql := scope.buildCondition(clause, true); sql != "" {
- andConditions = append(andConditions, sql)
- }
- }
-
- combinedSQL := strings.Join(andConditions, " AND ")
- if len(combinedSQL) == 0 {
- return ""
- }
-
- return " HAVING " + combinedSQL
-}
-
-func (scope *Scope) joinsSQL() string {
- var joinConditions []string
- for _, clause := range scope.Search.joinConditions {
- if sql := scope.buildCondition(clause, true); sql != "" {
- joinConditions = append(joinConditions, strings.TrimSuffix(strings.TrimPrefix(sql, "("), ")"))
- }
- }
-
- return strings.Join(joinConditions, " ") + " "
-}
-
-func (scope *Scope) prepareQuerySQL() {
- if scope.Search.raw {
- scope.Raw(scope.CombinedConditionSql())
- } else {
- scope.Raw(fmt.Sprintf("SELECT %v FROM %v %v", scope.selectSQL(), scope.QuotedTableName(), scope.CombinedConditionSql()))
- }
- return
-}
-
-func (scope *Scope) inlineCondition(values ...interface{}) *Scope {
- if len(values) > 0 {
- scope.Search.Where(values[0], values[1:]...)
- }
- return scope
-}
-
-func (scope *Scope) callCallbacks(funcs []*func(s *Scope)) *Scope {
- defer func() {
- if err := recover(); err != nil {
- if db, ok := scope.db.db.(sqlTx); ok {
- db.Rollback()
- }
- panic(err)
- }
- }()
- for _, f := range funcs {
- (*f)(scope)
- if scope.skipLeft {
- break
- }
- }
- return scope
-}
-
-func convertInterfaceToMap(values interface{}, withIgnoredField bool, db *DB) map[string]interface{} {
- var attrs = map[string]interface{}{}
-
- switch value := values.(type) {
- case map[string]interface{}:
- return value
- case []interface{}:
- for _, v := range value {
- for key, value := range convertInterfaceToMap(v, withIgnoredField, db) {
- attrs[key] = value
- }
- }
- case interface{}:
- reflectValue := reflect.ValueOf(values)
-
- switch reflectValue.Kind() {
- case reflect.Map:
- for _, key := range reflectValue.MapKeys() {
- attrs[ToColumnName(key.Interface().(string))] = reflectValue.MapIndex(key).Interface()
- }
- default:
- for _, field := range (&Scope{Value: values, db: db}).Fields() {
- if !field.IsBlank && (withIgnoredField || !field.IsIgnored) {
- attrs[field.DBName] = field.Field.Interface()
- }
- }
- }
- }
- return attrs
-}
-
-func (scope *Scope) updatedAttrsWithValues(value interface{}) (results map[string]interface{}, hasUpdate bool) {
- if scope.IndirectValue().Kind() != reflect.Struct {
- return convertInterfaceToMap(value, false, scope.db), true
- }
-
- results = map[string]interface{}{}
-
- for key, value := range convertInterfaceToMap(value, true, scope.db) {
- if field, ok := scope.FieldByName(key); ok {
- if scope.changeableField(field) {
- if _, ok := value.(*SqlExpr); ok {
- hasUpdate = true
- results[field.DBName] = value
- } else {
- err := field.Set(value)
- if field.IsNormal && !field.IsIgnored {
- hasUpdate = true
- if err == ErrUnaddressable {
- results[field.DBName] = value
- } else {
- results[field.DBName] = field.Field.Interface()
- }
- }
- }
- }
- } else {
- results[key] = value
- }
- }
- return
-}
-
-func (scope *Scope) row() *sql.Row {
- defer scope.trace(NowFunc())
-
- result := &RowQueryResult{}
- scope.InstanceSet("row_query_result", result)
- scope.callCallbacks(scope.db.parent.callbacks.rowQueries)
-
- return result.Row
-}
-
-func (scope *Scope) rows() (*sql.Rows, error) {
- defer scope.trace(NowFunc())
-
- result := &RowsQueryResult{}
- scope.InstanceSet("row_query_result", result)
- scope.callCallbacks(scope.db.parent.callbacks.rowQueries)
-
- return result.Rows, result.Error
-}
-
-func (scope *Scope) initialize() *Scope {
- for _, clause := range scope.Search.whereConditions {
- scope.updatedAttrsWithValues(clause["query"])
- }
- scope.updatedAttrsWithValues(scope.Search.initAttrs)
- scope.updatedAttrsWithValues(scope.Search.assignAttrs)
- return scope
-}
-
-func (scope *Scope) isQueryForColumn(query interface{}, column string) bool {
- queryStr := strings.ToLower(fmt.Sprint(query))
- if queryStr == column {
- return true
- }
-
- if strings.HasSuffix(queryStr, "as "+column) {
- return true
- }
-
- if strings.HasSuffix(queryStr, "as "+scope.Quote(column)) {
- return true
- }
-
- return false
-}
-
-func (scope *Scope) pluck(column string, value interface{}) *Scope {
- dest := reflect.Indirect(reflect.ValueOf(value))
- if dest.Kind() != reflect.Slice {
- scope.Err(fmt.Errorf("results should be a slice, not %s", dest.Kind()))
- return scope
- }
-
- if dest.Len() > 0 {
- dest.Set(reflect.Zero(dest.Type()))
- }
-
- if query, ok := scope.Search.selects["query"]; !ok || !scope.isQueryForColumn(query, column) {
- scope.Search.Select(column)
- }
-
- rows, err := scope.rows()
- if scope.Err(err) == nil {
- defer rows.Close()
- for rows.Next() {
- elem := reflect.New(dest.Type().Elem()).Interface()
- scope.Err(rows.Scan(elem))
- dest.Set(reflect.Append(dest, reflect.ValueOf(elem).Elem()))
- }
-
- if err := rows.Err(); err != nil {
- scope.Err(err)
- }
- }
- return scope
-}
-
-func (scope *Scope) count(value interface{}) *Scope {
- if query, ok := scope.Search.selects["query"]; !ok || !countingQueryRegexp.MatchString(fmt.Sprint(query)) {
- if len(scope.Search.group) != 0 {
- if len(scope.Search.havingConditions) != 0 {
- scope.prepareQuerySQL()
- scope.Search = &search{}
- scope.Search.Select("count(*)")
- scope.Search.Table(fmt.Sprintf("( %s ) AS count_table", scope.SQL))
- } else {
- scope.Search.Select("count(*) FROM ( SELECT count(*) as name ")
- scope.Search.group += " ) AS count_table"
- }
- } else {
- scope.Search.Select("count(*)")
- }
- }
- scope.Search.ignoreOrderQuery = true
- scope.Err(scope.row().Scan(value))
- return scope
-}
-
-func (scope *Scope) typeName() string {
- typ := scope.IndirectValue().Type()
-
- for typ.Kind() == reflect.Slice || typ.Kind() == reflect.Ptr {
- typ = typ.Elem()
- }
-
- return typ.Name()
-}
-
-// trace print sql log
-func (scope *Scope) trace(t time.Time) {
- if len(scope.SQL) > 0 {
- scope.db.slog(scope.SQL, t, scope.SQLVars...)
- }
-}
-
-func (scope *Scope) changeableField(field *Field) bool {
- if selectAttrs := scope.SelectAttrs(); len(selectAttrs) > 0 {
- for _, attr := range selectAttrs {
- if field.Name == attr || field.DBName == attr {
- return true
- }
- }
- return false
- }
-
- for _, attr := range scope.OmitAttrs() {
- if field.Name == attr || field.DBName == attr {
- return false
- }
- }
-
- return true
-}
-
-func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope {
- toScope := scope.db.NewScope(value)
- tx := scope.db.Set("gorm:association:source", scope.Value)
-
- for _, foreignKey := range append(foreignKeys, toScope.typeName()+"Id", scope.typeName()+"Id") {
- fromField, _ := scope.FieldByName(foreignKey)
- toField, _ := toScope.FieldByName(foreignKey)
-
- if fromField != nil {
- if relationship := fromField.Relationship; relationship != nil {
- if relationship.Kind == "many_to_many" {
- joinTableHandler := relationship.JoinTableHandler
- scope.Err(joinTableHandler.JoinWith(joinTableHandler, tx, scope.Value).Find(value).Error)
- } else if relationship.Kind == "belongs_to" {
- for idx, foreignKey := range relationship.ForeignDBNames {
- if field, ok := scope.FieldByName(foreignKey); ok {
- tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.AssociationForeignDBNames[idx])), field.Field.Interface())
- }
- }
- scope.Err(tx.Find(value).Error)
- } else if relationship.Kind == "has_many" || relationship.Kind == "has_one" {
- for idx, foreignKey := range relationship.ForeignDBNames {
- if field, ok := scope.FieldByName(relationship.AssociationForeignDBNames[idx]); ok {
- tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
- }
- }
-
- if relationship.PolymorphicType != "" {
- tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.PolymorphicDBName)), relationship.PolymorphicValue)
- }
- scope.Err(tx.Find(value).Error)
- }
- } else {
- sql := fmt.Sprintf("%v = ?", scope.Quote(toScope.PrimaryKey()))
- scope.Err(tx.Where(sql, fromField.Field.Interface()).Find(value).Error)
- }
- return scope
- } else if toField != nil {
- sql := fmt.Sprintf("%v = ?", scope.Quote(toField.DBName))
- scope.Err(tx.Where(sql, scope.PrimaryKeyValue()).Find(value).Error)
- return scope
- }
- }
-
- scope.Err(fmt.Errorf("invalid association %v", foreignKeys))
- return scope
-}
-
-// getTableOptions return the table options string or an empty string if the table options does not exist
-func (scope *Scope) getTableOptions() string {
- tableOptions, ok := scope.Get("gorm:table_options")
- if !ok {
- return ""
- }
- return " " + tableOptions.(string)
-}
-
-func (scope *Scope) createJoinTable(field *StructField) {
- if relationship := field.Relationship; relationship != nil && relationship.JoinTableHandler != nil {
- joinTableHandler := relationship.JoinTableHandler
- joinTable := joinTableHandler.Table(scope.db)
- if !scope.Dialect().HasTable(joinTable) {
- toScope := &Scope{Value: reflect.New(field.Struct.Type).Interface()}
-
- var sqlTypes, primaryKeys []string
- for idx, fieldName := range relationship.ForeignFieldNames {
- if field, ok := scope.FieldByName(fieldName); ok {
- foreignKeyStruct := field.clone()
- foreignKeyStruct.IsPrimaryKey = false
- foreignKeyStruct.TagSettingsSet("IS_JOINTABLE_FOREIGNKEY", "true")
- foreignKeyStruct.TagSettingsDelete("AUTO_INCREMENT")
- sqlTypes = append(sqlTypes, scope.Quote(relationship.ForeignDBNames[idx])+" "+scope.Dialect().DataTypeOf(foreignKeyStruct))
- primaryKeys = append(primaryKeys, scope.Quote(relationship.ForeignDBNames[idx]))
- }
- }
-
- for idx, fieldName := range relationship.AssociationForeignFieldNames {
- if field, ok := toScope.FieldByName(fieldName); ok {
- foreignKeyStruct := field.clone()
- foreignKeyStruct.IsPrimaryKey = false
- foreignKeyStruct.TagSettingsSet("IS_JOINTABLE_FOREIGNKEY", "true")
- foreignKeyStruct.TagSettingsDelete("AUTO_INCREMENT")
- sqlTypes = append(sqlTypes, scope.Quote(relationship.AssociationForeignDBNames[idx])+" "+scope.Dialect().DataTypeOf(foreignKeyStruct))
- primaryKeys = append(primaryKeys, scope.Quote(relationship.AssociationForeignDBNames[idx]))
- }
- }
-
- scope.Err(scope.NewDB().Exec(fmt.Sprintf("CREATE TABLE %v (%v, PRIMARY KEY (%v))%s", scope.Quote(joinTable), strings.Join(sqlTypes, ","), strings.Join(primaryKeys, ","), scope.getTableOptions())).Error)
- }
- scope.NewDB().Table(joinTable).AutoMigrate(joinTableHandler)
- }
-}
-
-func (scope *Scope) createTable() *Scope {
- var tags []string
- var primaryKeys []string
- var primaryKeyInColumnType = false
- for _, field := range scope.GetModelStruct().StructFields {
- if field.IsNormal {
- sqlTag := scope.Dialect().DataTypeOf(field)
-
- // Check if the primary key constraint was specified as
- // part of the column type. If so, we can only support
- // one column as the primary key.
- if strings.Contains(strings.ToLower(sqlTag), "primary key") {
- primaryKeyInColumnType = true
- }
-
- tags = append(tags, scope.Quote(field.DBName)+" "+sqlTag)
- }
-
- if field.IsPrimaryKey {
- primaryKeys = append(primaryKeys, scope.Quote(field.DBName))
- }
- scope.createJoinTable(field)
- }
-
- var primaryKeyStr string
- if len(primaryKeys) > 0 && !primaryKeyInColumnType {
- primaryKeyStr = fmt.Sprintf(", PRIMARY KEY (%v)", strings.Join(primaryKeys, ","))
- }
-
- scope.Raw(fmt.Sprintf("CREATE TABLE %v (%v %v)%s", scope.QuotedTableName(), strings.Join(tags, ","), primaryKeyStr, scope.getTableOptions())).Exec()
-
- scope.autoIndex()
- return scope
-}
-
-func (scope *Scope) dropTable() *Scope {
- scope.Raw(fmt.Sprintf("DROP TABLE %v", scope.QuotedTableName())).Exec()
- return scope
-}
-
-func (scope *Scope) modifyColumn(column string, typ string) {
- scope.db.AddError(scope.Dialect().ModifyColumn(scope.QuotedTableName(), scope.Quote(column), typ))
-}
-
-func (scope *Scope) dropColumn(column string) {
- scope.Raw(fmt.Sprintf("ALTER TABLE %v DROP COLUMN %v", scope.QuotedTableName(), scope.Quote(column))).Exec()
-}
-
-func (scope *Scope) addIndex(unique bool, indexName string, column ...string) {
- if scope.Dialect().HasIndex(scope.TableName(), indexName) {
- return
- }
-
- var columns []string
- for _, name := range column {
- columns = append(columns, scope.quoteIfPossible(name))
- }
-
- sqlCreate := "CREATE INDEX"
- if unique {
- sqlCreate = "CREATE UNIQUE INDEX"
- }
-
- scope.Raw(fmt.Sprintf("%s %v ON %v(%v) %v", sqlCreate, indexName, scope.QuotedTableName(), strings.Join(columns, ", "), scope.whereSQL())).Exec()
-}
-
-func (scope *Scope) addForeignKey(field string, dest string, onDelete string, onUpdate string) {
- // Compatible with old generated key
- keyName := scope.Dialect().BuildKeyName(scope.TableName(), field, dest, "foreign")
-
- if scope.Dialect().HasForeignKey(scope.TableName(), keyName) {
- return
- }
- var query = `ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s ON DELETE %s ON UPDATE %s;`
- scope.Raw(fmt.Sprintf(query, scope.QuotedTableName(), scope.quoteIfPossible(keyName), scope.quoteIfPossible(field), dest, onDelete, onUpdate)).Exec()
-}
-
-func (scope *Scope) removeForeignKey(field string, dest string) {
- keyName := scope.Dialect().BuildKeyName(scope.TableName(), field, dest, "foreign")
- if !scope.Dialect().HasForeignKey(scope.TableName(), keyName) {
- return
- }
- var mysql mysql
- var query string
- if scope.Dialect().GetName() == mysql.GetName() {
- query = `ALTER TABLE %s DROP FOREIGN KEY %s;`
- } else {
- query = `ALTER TABLE %s DROP CONSTRAINT %s;`
- }
-
- scope.Raw(fmt.Sprintf(query, scope.QuotedTableName(), scope.quoteIfPossible(keyName))).Exec()
-}
-
-func (scope *Scope) removeIndex(indexName string) {
- scope.Dialect().RemoveIndex(scope.TableName(), indexName)
-}
-
-func (scope *Scope) autoMigrate() *Scope {
- tableName := scope.TableName()
- quotedTableName := scope.QuotedTableName()
-
- if !scope.Dialect().HasTable(tableName) {
- scope.createTable()
- } else {
- for _, field := range scope.GetModelStruct().StructFields {
- if !scope.Dialect().HasColumn(tableName, field.DBName) {
- if field.IsNormal {
- sqlTag := scope.Dialect().DataTypeOf(field)
- scope.Raw(fmt.Sprintf("ALTER TABLE %v ADD %v %v;", quotedTableName, scope.Quote(field.DBName), sqlTag)).Exec()
- }
- }
- scope.createJoinTable(field)
- }
- scope.autoIndex()
- }
- return scope
-}
-
-func (scope *Scope) autoIndex() *Scope {
- var indexes = map[string][]string{}
- var uniqueIndexes = map[string][]string{}
-
- for _, field := range scope.GetStructFields() {
- if name, ok := field.TagSettingsGet("INDEX"); ok {
- names := strings.Split(name, ",")
-
- for _, name := range names {
- if name == "INDEX" || name == "" {
- name = scope.Dialect().BuildKeyName("idx", scope.TableName(), field.DBName)
- }
- name, column := scope.Dialect().NormalizeIndexAndColumn(name, field.DBName)
- indexes[name] = append(indexes[name], column)
- }
- }
-
- if name, ok := field.TagSettingsGet("UNIQUE_INDEX"); ok {
- names := strings.Split(name, ",")
-
- for _, name := range names {
- if name == "UNIQUE_INDEX" || name == "" {
- name = scope.Dialect().BuildKeyName("uix", scope.TableName(), field.DBName)
- }
- name, column := scope.Dialect().NormalizeIndexAndColumn(name, field.DBName)
- uniqueIndexes[name] = append(uniqueIndexes[name], column)
- }
- }
- }
-
- for name, columns := range indexes {
- if db := scope.NewDB().Table(scope.TableName()).Model(scope.Value).AddIndex(name, columns...); db.Error != nil {
- scope.db.AddError(db.Error)
- }
- }
-
- for name, columns := range uniqueIndexes {
- if db := scope.NewDB().Table(scope.TableName()).Model(scope.Value).AddUniqueIndex(name, columns...); db.Error != nil {
- scope.db.AddError(db.Error)
- }
- }
-
- return scope
-}
-
-func (scope *Scope) getColumnAsArray(columns []string, values ...interface{}) (results [][]interface{}) {
- resultMap := make(map[string][]interface{})
- for _, value := range values {
- indirectValue := indirect(reflect.ValueOf(value))
-
- switch indirectValue.Kind() {
- case reflect.Slice:
- for i := 0; i < indirectValue.Len(); i++ {
- var result []interface{}
- var object = indirect(indirectValue.Index(i))
- var hasValue = false
- for _, column := range columns {
- field := object.FieldByName(column)
- if hasValue || !isBlank(field) {
- hasValue = true
- }
- result = append(result, field.Interface())
- }
-
- if hasValue {
- h := fmt.Sprint(result...)
- if _, exist := resultMap[h]; !exist {
- resultMap[h] = result
- }
- }
- }
- case reflect.Struct:
- var result []interface{}
- var hasValue = false
- for _, column := range columns {
- field := indirectValue.FieldByName(column)
- if hasValue || !isBlank(field) {
- hasValue = true
- }
- result = append(result, field.Interface())
- }
-
- if hasValue {
- h := fmt.Sprint(result...)
- if _, exist := resultMap[h]; !exist {
- resultMap[h] = result
- }
- }
- }
- }
- for _, v := range resultMap {
- results = append(results, v)
- }
- return
-}
-
-func (scope *Scope) getColumnAsScope(column string) *Scope {
- indirectScopeValue := scope.IndirectValue()
-
- switch indirectScopeValue.Kind() {
- case reflect.Slice:
- if fieldStruct, ok := scope.GetModelStruct().ModelType.FieldByName(column); ok {
- fieldType := fieldStruct.Type
- if fieldType.Kind() == reflect.Slice || fieldType.Kind() == reflect.Ptr {
- fieldType = fieldType.Elem()
- }
-
- resultsMap := map[interface{}]bool{}
- results := reflect.New(reflect.SliceOf(reflect.PtrTo(fieldType))).Elem()
-
- for i := 0; i < indirectScopeValue.Len(); i++ {
- result := indirect(indirect(indirectScopeValue.Index(i)).FieldByName(column))
-
- if result.Kind() == reflect.Slice {
- for j := 0; j < result.Len(); j++ {
- if elem := result.Index(j); elem.CanAddr() && resultsMap[elem.Addr()] != true {
- resultsMap[elem.Addr()] = true
- results = reflect.Append(results, elem.Addr())
- }
- }
- } else if result.CanAddr() && resultsMap[result.Addr()] != true {
- resultsMap[result.Addr()] = true
- results = reflect.Append(results, result.Addr())
- }
- }
- return scope.New(results.Interface())
- }
- case reflect.Struct:
- if field := indirectScopeValue.FieldByName(column); field.CanAddr() {
- return scope.New(field.Addr().Interface())
- }
- }
- return nil
-}
-
-func (scope *Scope) hasConditions() bool {
- return !scope.PrimaryKeyZero() ||
- len(scope.Search.whereConditions) > 0 ||
- len(scope.Search.orConditions) > 0 ||
- len(scope.Search.notConditions) > 0
-}
diff --git a/vendor/github.com/jinzhu/gorm/search.go b/vendor/github.com/jinzhu/gorm/search.go
deleted file mode 100644
index 52ae2ef..0000000
--- a/vendor/github.com/jinzhu/gorm/search.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package gorm
-
-import (
- "fmt"
-)
-
-type search struct {
- db *DB
- whereConditions []map[string]interface{}
- orConditions []map[string]interface{}
- notConditions []map[string]interface{}
- havingConditions []map[string]interface{}
- joinConditions []map[string]interface{}
- initAttrs []interface{}
- assignAttrs []interface{}
- selects map[string]interface{}
- omits []string
- orders []interface{}
- preload []searchPreload
- offset interface{}
- limit interface{}
- group string
- tableName string
- raw bool
- Unscoped bool
- ignoreOrderQuery bool
-}
-
-type searchPreload struct {
- schema string
- conditions []interface{}
-}
-
-func (s *search) clone() *search {
- clone := search{
- db: s.db,
- whereConditions: make([]map[string]interface{}, len(s.whereConditions)),
- orConditions: make([]map[string]interface{}, len(s.orConditions)),
- notConditions: make([]map[string]interface{}, len(s.notConditions)),
- havingConditions: make([]map[string]interface{}, len(s.havingConditions)),
- joinConditions: make([]map[string]interface{}, len(s.joinConditions)),
- initAttrs: make([]interface{}, len(s.initAttrs)),
- assignAttrs: make([]interface{}, len(s.assignAttrs)),
- selects: s.selects,
- omits: make([]string, len(s.omits)),
- orders: make([]interface{}, len(s.orders)),
- preload: make([]searchPreload, len(s.preload)),
- offset: s.offset,
- limit: s.limit,
- group: s.group,
- tableName: s.tableName,
- raw: s.raw,
- Unscoped: s.Unscoped,
- ignoreOrderQuery: s.ignoreOrderQuery,
- }
- for i, value := range s.whereConditions {
- clone.whereConditions[i] = value
- }
- for i, value := range s.orConditions {
- clone.orConditions[i] = value
- }
- for i, value := range s.notConditions {
- clone.notConditions[i] = value
- }
- for i, value := range s.havingConditions {
- clone.havingConditions[i] = value
- }
- for i, value := range s.joinConditions {
- clone.joinConditions[i] = value
- }
- for i, value := range s.initAttrs {
- clone.initAttrs[i] = value
- }
- for i, value := range s.assignAttrs {
- clone.assignAttrs[i] = value
- }
- for i, value := range s.omits {
- clone.omits[i] = value
- }
- for i, value := range s.orders {
- clone.orders[i] = value
- }
- for i, value := range s.preload {
- clone.preload[i] = value
- }
- return &clone
-}
-
-func (s *search) Where(query interface{}, values ...interface{}) *search {
- s.whereConditions = append(s.whereConditions, map[string]interface{}{"query": query, "args": values})
- return s
-}
-
-func (s *search) Not(query interface{}, values ...interface{}) *search {
- s.notConditions = append(s.notConditions, map[string]interface{}{"query": query, "args": values})
- return s
-}
-
-func (s *search) Or(query interface{}, values ...interface{}) *search {
- s.orConditions = append(s.orConditions, map[string]interface{}{"query": query, "args": values})
- return s
-}
-
-func (s *search) Attrs(attrs ...interface{}) *search {
- s.initAttrs = append(s.initAttrs, toSearchableMap(attrs...))
- return s
-}
-
-func (s *search) Assign(attrs ...interface{}) *search {
- s.assignAttrs = append(s.assignAttrs, toSearchableMap(attrs...))
- return s
-}
-
-func (s *search) Order(value interface{}, reorder ...bool) *search {
- if len(reorder) > 0 && reorder[0] {
- s.orders = []interface{}{}
- }
-
- if value != nil && value != "" {
- s.orders = append(s.orders, value)
- }
- return s
-}
-
-func (s *search) Select(query interface{}, args ...interface{}) *search {
- s.selects = map[string]interface{}{"query": query, "args": args}
- return s
-}
-
-func (s *search) Omit(columns ...string) *search {
- s.omits = columns
- return s
-}
-
-func (s *search) Limit(limit interface{}) *search {
- s.limit = limit
- return s
-}
-
-func (s *search) Offset(offset interface{}) *search {
- s.offset = offset
- return s
-}
-
-func (s *search) Group(query string) *search {
- s.group = s.getInterfaceAsSQL(query)
- return s
-}
-
-func (s *search) Having(query interface{}, values ...interface{}) *search {
- if val, ok := query.(*SqlExpr); ok {
- s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": val.expr, "args": val.args})
- } else {
- s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": query, "args": values})
- }
- return s
-}
-
-func (s *search) Joins(query string, values ...interface{}) *search {
- s.joinConditions = append(s.joinConditions, map[string]interface{}{"query": query, "args": values})
- return s
-}
-
-func (s *search) Preload(schema string, values ...interface{}) *search {
- var preloads []searchPreload
- for _, preload := range s.preload {
- if preload.schema != schema {
- preloads = append(preloads, preload)
- }
- }
- preloads = append(preloads, searchPreload{schema, values})
- s.preload = preloads
- return s
-}
-
-func (s *search) Raw(b bool) *search {
- s.raw = b
- return s
-}
-
-func (s *search) unscoped() *search {
- s.Unscoped = true
- return s
-}
-
-func (s *search) Table(name string) *search {
- s.tableName = name
- return s
-}
-
-func (s *search) getInterfaceAsSQL(value interface{}) (str string) {
- switch value.(type) {
- case string, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
- str = fmt.Sprintf("%v", value)
- default:
- s.db.AddError(ErrInvalidSQL)
- }
-
- if str == "-1" {
- return ""
- }
- return
-}
diff --git a/vendor/github.com/jinzhu/gorm/test_all.sh b/vendor/github.com/jinzhu/gorm/test_all.sh
deleted file mode 100644
index 5cfb332..0000000
--- a/vendor/github.com/jinzhu/gorm/test_all.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-dialects=("postgres" "mysql" "mssql" "sqlite")
-
-for dialect in "${dialects[@]}" ; do
- DEBUG=false GORM_DIALECT=${dialect} go test
-done
diff --git a/vendor/github.com/jinzhu/gorm/utils.go b/vendor/github.com/jinzhu/gorm/utils.go
deleted file mode 100644
index d2ae946..0000000
--- a/vendor/github.com/jinzhu/gorm/utils.go
+++ /dev/null
@@ -1,226 +0,0 @@
-package gorm
-
-import (
- "database/sql/driver"
- "fmt"
- "reflect"
- "regexp"
- "runtime"
- "strings"
- "sync"
- "time"
-)
-
-// NowFunc returns current time, this function is exported in order to be able
-// to give the flexibility to the developer to customize it according to their
-// needs, e.g:
-// gorm.NowFunc = func() time.Time {
-// return time.Now().UTC()
-// }
-var NowFunc = func() time.Time {
- return time.Now()
-}
-
-// Copied from golint
-var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UID", "UI", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
-var commonInitialismsReplacer *strings.Replacer
-
-var goSrcRegexp = regexp.MustCompile(`jinzhu/gorm(@.*)?/.*.go`)
-var goTestRegexp = regexp.MustCompile(`jinzhu/gorm(@.*)?/.*test.go`)
-
-func init() {
- var commonInitialismsForReplacer []string
- for _, initialism := range commonInitialisms {
- commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
- }
- commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
-}
-
-type safeMap struct {
- m map[string]string
- l *sync.RWMutex
-}
-
-func (s *safeMap) Set(key string, value string) {
- s.l.Lock()
- defer s.l.Unlock()
- s.m[key] = value
-}
-
-func (s *safeMap) Get(key string) string {
- s.l.RLock()
- defer s.l.RUnlock()
- return s.m[key]
-}
-
-func newSafeMap() *safeMap {
- return &safeMap{l: new(sync.RWMutex), m: make(map[string]string)}
-}
-
-// SQL expression
-type SqlExpr struct {
- expr string
- args []interface{}
-}
-
-// Expr generate raw SQL expression, for example:
-// DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
-func Expr(expression string, args ...interface{}) *SqlExpr {
- return &SqlExpr{expr: expression, args: args}
-}
-
-func indirect(reflectValue reflect.Value) reflect.Value {
- for reflectValue.Kind() == reflect.Ptr {
- reflectValue = reflectValue.Elem()
- }
- return reflectValue
-}
-
-func toQueryMarks(primaryValues [][]interface{}) string {
- var results []string
-
- for _, primaryValue := range primaryValues {
- var marks []string
- for range primaryValue {
- marks = append(marks, "?")
- }
-
- if len(marks) > 1 {
- results = append(results, fmt.Sprintf("(%v)", strings.Join(marks, ",")))
- } else {
- results = append(results, strings.Join(marks, ""))
- }
- }
- return strings.Join(results, ",")
-}
-
-func toQueryCondition(scope *Scope, columns []string) string {
- var newColumns []string
- for _, column := range columns {
- newColumns = append(newColumns, scope.Quote(column))
- }
-
- if len(columns) > 1 {
- return fmt.Sprintf("(%v)", strings.Join(newColumns, ","))
- }
- return strings.Join(newColumns, ",")
-}
-
-func toQueryValues(values [][]interface{}) (results []interface{}) {
- for _, value := range values {
- for _, v := range value {
- results = append(results, v)
- }
- }
- return
-}
-
-func fileWithLineNum() string {
- for i := 2; i < 15; i++ {
- _, file, line, ok := runtime.Caller(i)
- if ok && (!goSrcRegexp.MatchString(file) || goTestRegexp.MatchString(file)) {
- return fmt.Sprintf("%v:%v", file, line)
- }
- }
- return ""
-}
-
-func isBlank(value reflect.Value) bool {
- switch value.Kind() {
- case reflect.String:
- return value.Len() == 0
- case reflect.Bool:
- return !value.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return value.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return value.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return value.Float() == 0
- case reflect.Interface, reflect.Ptr:
- return value.IsNil()
- }
-
- return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
-}
-
-func toSearchableMap(attrs ...interface{}) (result interface{}) {
- if len(attrs) > 1 {
- if str, ok := attrs[0].(string); ok {
- result = map[string]interface{}{str: attrs[1]}
- }
- } else if len(attrs) == 1 {
- if attr, ok := attrs[0].(map[string]interface{}); ok {
- result = attr
- }
-
- if attr, ok := attrs[0].(interface{}); ok {
- result = attr
- }
- }
- return
-}
-
-func equalAsString(a interface{}, b interface{}) bool {
- return toString(a) == toString(b)
-}
-
-func toString(str interface{}) string {
- if values, ok := str.([]interface{}); ok {
- var results []string
- for _, value := range values {
- results = append(results, toString(value))
- }
- return strings.Join(results, "_")
- } else if bytes, ok := str.([]byte); ok {
- return string(bytes)
- } else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
- return fmt.Sprintf("%v", reflectValue.Interface())
- }
- return ""
-}
-
-func makeSlice(elemType reflect.Type) interface{} {
- if elemType.Kind() == reflect.Slice {
- elemType = elemType.Elem()
- }
- sliceType := reflect.SliceOf(elemType)
- slice := reflect.New(sliceType)
- slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
- return slice.Interface()
-}
-
-func strInSlice(a string, list []string) bool {
- for _, b := range list {
- if b == a {
- return true
- }
- }
- return false
-}
-
-// getValueFromFields return given fields's value
-func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
- // If value is a nil pointer, Indirect returns a zero Value!
- // Therefor we need to check for a zero value,
- // as FieldByName could panic
- if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
- for _, fieldName := range fieldNames {
- if fieldValue := reflect.Indirect(indirectValue.FieldByName(fieldName)); fieldValue.IsValid() {
- result := fieldValue.Interface()
- if r, ok := result.(driver.Valuer); ok {
- result, _ = r.Value()
- }
- results = append(results, result)
- }
- }
- }
- return
-}
-
-func addExtraSpaceIfExist(str string) string {
- if str != "" {
- return " " + str
- }
- return ""
-}
diff --git a/vendor/github.com/jinzhu/gorm/wercker.yml b/vendor/github.com/jinzhu/gorm/wercker.yml
deleted file mode 100644
index 1de947b..0000000
--- a/vendor/github.com/jinzhu/gorm/wercker.yml
+++ /dev/null
@@ -1,149 +0,0 @@
-# use the default golang container from Docker Hub
-box: golang
-
-services:
- - name: mariadb
- id: mariadb:latest
- env:
- MYSQL_DATABASE: gorm
- MYSQL_USER: gorm
- MYSQL_PASSWORD: gorm
- MYSQL_RANDOM_ROOT_PASSWORD: "yes"
- - name: mysql
- id: mysql:latest
- env:
- MYSQL_DATABASE: gorm
- MYSQL_USER: gorm
- MYSQL_PASSWORD: gorm
- MYSQL_RANDOM_ROOT_PASSWORD: "yes"
- - name: mysql57
- id: mysql:5.7
- env:
- MYSQL_DATABASE: gorm
- MYSQL_USER: gorm
- MYSQL_PASSWORD: gorm
- MYSQL_RANDOM_ROOT_PASSWORD: "yes"
- - name: mysql56
- id: mysql:5.6
- env:
- MYSQL_DATABASE: gorm
- MYSQL_USER: gorm
- MYSQL_PASSWORD: gorm
- MYSQL_RANDOM_ROOT_PASSWORD: "yes"
- - name: postgres
- id: postgres:latest
- env:
- POSTGRES_USER: gorm
- POSTGRES_PASSWORD: gorm
- POSTGRES_DB: gorm
- - name: postgres96
- id: postgres:9.6
- env:
- POSTGRES_USER: gorm
- POSTGRES_PASSWORD: gorm
- POSTGRES_DB: gorm
- - name: postgres95
- id: postgres:9.5
- env:
- POSTGRES_USER: gorm
- POSTGRES_PASSWORD: gorm
- POSTGRES_DB: gorm
- - name: postgres94
- id: postgres:9.4
- env:
- POSTGRES_USER: gorm
- POSTGRES_PASSWORD: gorm
- POSTGRES_DB: gorm
- - name: postgres93
- id: postgres:9.3
- env:
- POSTGRES_USER: gorm
- POSTGRES_PASSWORD: gorm
- POSTGRES_DB: gorm
- - name: mssql
- id: mcmoe/mssqldocker:latest
- env:
- ACCEPT_EULA: Y
- SA_PASSWORD: LoremIpsum86
- MSSQL_DB: gorm
- MSSQL_USER: gorm
- MSSQL_PASSWORD: LoremIpsum86
-
-# The steps that will be executed in the build pipeline
-build:
- # The steps that will be executed on build
- steps:
- # Sets the go workspace and places you package
- # at the right place in the workspace tree
- - setup-go-workspace
-
- # Gets the dependencies
- - script:
- name: go get
- code: |
- cd $WERCKER_SOURCE_DIR
- go version
- go get -t -v ./...
-
- # Build the project
- - script:
- name: go build
- code: |
- go build ./...
-
- # Test the project
- - script:
- name: test sqlite
- code: |
- go test -race -v ./...
-
- - script:
- name: test mariadb
- code: |
- GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mariadb:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
-
- - script:
- name: test mysql
- code: |
- GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mysql:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
-
- - script:
- name: test mysql5.7
- code: |
- GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mysql57:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
-
- - script:
- name: test mysql5.6
- code: |
- GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mysql56:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
-
- - script:
- name: test postgres
- code: |
- GORM_DIALECT=postgres GORM_DSN="host=postgres user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
-
- - script:
- name: test postgres96
- code: |
- GORM_DIALECT=postgres GORM_DSN="host=postgres96 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
-
- - script:
- name: test postgres95
- code: |
- GORM_DIALECT=postgres GORM_DSN="host=postgres95 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
-
- - script:
- name: test postgres94
- code: |
- GORM_DIALECT=postgres GORM_DSN="host=postgres94 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
-
- - script:
- name: test postgres93
- code: |
- GORM_DIALECT=postgres GORM_DSN="host=postgres93 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
-
- - script:
- name: codecov
- code: |
- go test -race -coverprofile=coverage.txt -covermode=atomic ./...
- bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 7a54d6e..63fac51 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,16 +1,15 @@
# github.com/go-sql-driver/mysql v1.6.0
## explicit; go 1.10
github.com/go-sql-driver/mysql
+# github.com/gorilla/mux v1.8.0
+## explicit; go 1.12
+github.com/gorilla/mux
# github.com/gosimple/slug v1.12.0
## explicit; go 1.11
github.com/gosimple/slug
# github.com/gosimple/unidecode v1.0.1
## explicit; go 1.16
github.com/gosimple/unidecode
-# github.com/jinzhu/gorm v1.9.16
-## explicit; go 1.12
-github.com/jinzhu/gorm
-github.com/jinzhu/gorm/dialects/mysql
# github.com/jinzhu/inflection v1.0.0
## explicit
github.com/jinzhu/inflection