mirror of https://github.com/go-gorm/gorm.git
Add sql builder test
This commit is contained in:
parent
5457fe88e6
commit
749ca37eb0
|
@ -19,93 +19,7 @@ func Query(db *gorm.DB) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if db.Statement.SQL.String() == "" {
|
if db.Statement.SQL.String() == "" {
|
||||||
clauseSelect := clause.Select{}
|
BuildQuerySQL(db)
|
||||||
|
|
||||||
if len(db.Statement.Selects) > 0 {
|
|
||||||
for _, name := range db.Statement.Selects {
|
|
||||||
if f := db.Statement.Schema.LookUpField(name); f != nil {
|
|
||||||
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
|
||||||
Name: f.DBName,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
|
||||||
Name: name,
|
|
||||||
Raw: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// inline joins
|
|
||||||
if len(db.Statement.Joins) != 0 {
|
|
||||||
joins := []clause.Join{}
|
|
||||||
|
|
||||||
if len(db.Statement.Selects) == 0 {
|
|
||||||
for _, dbName := range db.Statement.Schema.DBNames {
|
|
||||||
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
|
||||||
Table: db.Statement.Table,
|
|
||||||
Name: dbName,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, conds := range db.Statement.Joins {
|
|
||||||
if relation, ok := db.Statement.Schema.Relationships.Relations[name]; ok {
|
|
||||||
tableAliasName := relation.Name
|
|
||||||
|
|
||||||
for _, s := range relation.FieldSchema.DBNames {
|
|
||||||
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
|
||||||
Table: tableAliasName,
|
|
||||||
Name: s,
|
|
||||||
Alias: tableAliasName + "__" + s,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var exprs []clause.Expression
|
|
||||||
for _, ref := range relation.References {
|
|
||||||
if ref.OwnPrimaryKey {
|
|
||||||
exprs = append(exprs, clause.Eq{
|
|
||||||
Column: clause.Column{Table: db.Statement.Schema.Table, Name: ref.PrimaryKey.DBName},
|
|
||||||
Value: clause.Column{Table: tableAliasName, Name: ref.ForeignKey.DBName},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
if ref.PrimaryValue == "" {
|
|
||||||
exprs = append(exprs, clause.Eq{
|
|
||||||
Column: clause.Column{Table: db.Statement.Schema.Table, Name: ref.ForeignKey.DBName},
|
|
||||||
Value: clause.Column{Table: tableAliasName, Name: ref.PrimaryKey.DBName},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
exprs = append(exprs, clause.Eq{
|
|
||||||
Column: clause.Column{Table: tableAliasName, Name: ref.ForeignKey.DBName},
|
|
||||||
Value: ref.PrimaryValue,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
joins = append(joins, clause.Join{
|
|
||||||
Type: clause.LeftJoin,
|
|
||||||
Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName},
|
|
||||||
ON: clause.Where{Exprs: exprs},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
joins = append(joins, clause.Join{
|
|
||||||
Expression: clause.Expr{SQL: name, Vars: conds},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
db.Statement.AddClause(clause.From{Joins: joins})
|
|
||||||
} else {
|
|
||||||
db.Statement.AddClauseIfNotExists(clause.From{})
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(clauseSelect.Columns) > 0 {
|
|
||||||
db.Statement.AddClause(clauseSelect)
|
|
||||||
} else {
|
|
||||||
db.Statement.AddClauseIfNotExists(clauseSelect)
|
|
||||||
}
|
|
||||||
db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := db.Statement.ConnPool.QueryContext(db.Statement.Context, db.Statement.SQL.String(), db.Statement.Vars...)
|
rows, err := db.Statement.ConnPool.QueryContext(db.Statement.Context, db.Statement.SQL.String(), db.Statement.Vars...)
|
||||||
|
@ -118,6 +32,106 @@ func Query(db *gorm.DB) {
|
||||||
gorm.Scan(rows, db, false)
|
gorm.Scan(rows, db, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BuildQuerySQL(db *gorm.DB) {
|
||||||
|
clauseSelect := clause.Select{}
|
||||||
|
|
||||||
|
if len(db.Statement.Selects) > 0 {
|
||||||
|
for _, name := range db.Statement.Selects {
|
||||||
|
if db.Statement.Schema == nil {
|
||||||
|
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
||||||
|
Name: name,
|
||||||
|
Raw: true,
|
||||||
|
})
|
||||||
|
} else if f := db.Statement.Schema.LookUpField(name); f != nil {
|
||||||
|
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
||||||
|
Name: f.DBName,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
||||||
|
Name: name,
|
||||||
|
Raw: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// inline joins
|
||||||
|
if len(db.Statement.Joins) != 0 {
|
||||||
|
joins := []clause.Join{}
|
||||||
|
|
||||||
|
if len(db.Statement.Selects) == 0 {
|
||||||
|
for _, dbName := range db.Statement.Schema.DBNames {
|
||||||
|
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
||||||
|
Table: db.Statement.Table,
|
||||||
|
Name: dbName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, conds := range db.Statement.Joins {
|
||||||
|
if db.Statement.Schema == nil {
|
||||||
|
joins = append(joins, clause.Join{
|
||||||
|
Expression: clause.Expr{SQL: name, Vars: conds},
|
||||||
|
})
|
||||||
|
} else if relation, ok := db.Statement.Schema.Relationships.Relations[name]; ok {
|
||||||
|
tableAliasName := relation.Name
|
||||||
|
|
||||||
|
for _, s := range relation.FieldSchema.DBNames {
|
||||||
|
clauseSelect.Columns = append(clauseSelect.Columns, clause.Column{
|
||||||
|
Table: tableAliasName,
|
||||||
|
Name: s,
|
||||||
|
Alias: tableAliasName + "__" + s,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var exprs []clause.Expression
|
||||||
|
for _, ref := range relation.References {
|
||||||
|
if ref.OwnPrimaryKey {
|
||||||
|
exprs = append(exprs, clause.Eq{
|
||||||
|
Column: clause.Column{Table: db.Statement.Schema.Table, Name: ref.PrimaryKey.DBName},
|
||||||
|
Value: clause.Column{Table: tableAliasName, Name: ref.ForeignKey.DBName},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if ref.PrimaryValue == "" {
|
||||||
|
exprs = append(exprs, clause.Eq{
|
||||||
|
Column: clause.Column{Table: db.Statement.Schema.Table, Name: ref.ForeignKey.DBName},
|
||||||
|
Value: clause.Column{Table: tableAliasName, Name: ref.PrimaryKey.DBName},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
exprs = append(exprs, clause.Eq{
|
||||||
|
Column: clause.Column{Table: tableAliasName, Name: ref.ForeignKey.DBName},
|
||||||
|
Value: ref.PrimaryValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joins = append(joins, clause.Join{
|
||||||
|
Type: clause.LeftJoin,
|
||||||
|
Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName},
|
||||||
|
ON: clause.Where{Exprs: exprs},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
joins = append(joins, clause.Join{
|
||||||
|
Expression: clause.Expr{SQL: name, Vars: conds},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Statement.AddClause(clause.From{Joins: joins})
|
||||||
|
} else {
|
||||||
|
db.Statement.AddClauseIfNotExists(clause.From{})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(clauseSelect.Columns) > 0 {
|
||||||
|
db.Statement.AddClause(clauseSelect)
|
||||||
|
} else {
|
||||||
|
db.Statement.AddClauseIfNotExists(clauseSelect)
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR")
|
||||||
|
}
|
||||||
|
|
||||||
func Preload(db *gorm.DB) {
|
func Preload(db *gorm.DB) {
|
||||||
if len(db.Statement.Preloads) > 0 {
|
if len(db.Statement.Preloads) > 0 {
|
||||||
preloadMap := map[string][]string{}
|
preloadMap := map[string][]string{}
|
||||||
|
|
|
@ -2,15 +2,11 @@ package callbacks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/jinzhu/gorm/clause"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func RowQuery(db *gorm.DB) {
|
func RowQuery(db *gorm.DB) {
|
||||||
if db.Statement.SQL.String() == "" {
|
if db.Statement.SQL.String() == "" {
|
||||||
db.Statement.AddClauseIfNotExists(clause.Select{})
|
BuildQuerySQL(db)
|
||||||
db.Statement.AddClauseIfNotExists(clause.From{})
|
|
||||||
|
|
||||||
db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := db.Get("rows"); ok {
|
if _, ok := db.Get("rows"); ok {
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package tests_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
. "github.com/jinzhu/gorm/tests"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRow(t *testing.T) {
|
||||||
|
user1 := User{Name: "RowUser1", Age: 1}
|
||||||
|
user2 := User{Name: "RowUser2", Age: 10}
|
||||||
|
user3 := User{Name: "RowUser3", Age: 20}
|
||||||
|
DB.Save(&user1).Save(&user2).Save(&user3)
|
||||||
|
|
||||||
|
row := DB.Table("users").Where("name = ?", user2.Name).Select("age").Row()
|
||||||
|
|
||||||
|
var age int64
|
||||||
|
if err := row.Scan(&age); err != nil {
|
||||||
|
t.Fatalf("Failed to scan age, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if age != 10 {
|
||||||
|
t.Errorf("Scan with Row, age expects: %v, got %v", user2.Age, age)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRows(t *testing.T) {
|
||||||
|
user1 := User{Name: "RowsUser1", Age: 1}
|
||||||
|
user2 := User{Name: "RowsUser2", Age: 10}
|
||||||
|
user3 := User{Name: "RowsUser3", Age: 20}
|
||||||
|
DB.Save(&user1).Save(&user2).Save(&user3)
|
||||||
|
|
||||||
|
rows, err := DB.Table("users").Where("name = ? or name = ?", user2.Name, user3.Name).Select("name, age").Rows()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Not error should happen, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
for rows.Next() {
|
||||||
|
var name string
|
||||||
|
var age int64
|
||||||
|
rows.Scan(&name, &age)
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
if count != 2 {
|
||||||
|
t.Errorf("Should found two records")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRaw(t *testing.T) {
|
||||||
|
user1 := User{Name: "ExecRawSqlUser1", Age: 1}
|
||||||
|
user2 := User{Name: "ExecRawSqlUser2", Age: 10}
|
||||||
|
user3 := User{Name: "ExecRawSqlUser3", Age: 20}
|
||||||
|
DB.Save(&user1).Save(&user2).Save(&user3)
|
||||||
|
|
||||||
|
type result struct {
|
||||||
|
Name string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []result
|
||||||
|
DB.Raw("SELECT name, age FROM users WHERE name = ? or name = ?", user2.Name, user3.Name).Scan(&results)
|
||||||
|
if len(results) != 2 || results[0].Name != user2.Name || results[1].Name != user3.Name {
|
||||||
|
t.Errorf("Raw with scan")
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, _ := DB.Raw("select name, age from users where name = ?", user3.Name).Rows()
|
||||||
|
count := 0
|
||||||
|
for rows.Next() {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
if count != 1 {
|
||||||
|
t.Errorf("Raw with Rows should find one record with name 3")
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Exec("update users set name=? where name in (?)", "jinzhu", []string{user1.Name, user2.Name, user3.Name})
|
||||||
|
if DB.Where("name in (?)", []string{user1.Name, user2.Name, user3.Name}).First(&User{}).Error != gorm.ErrRecordNotFound {
|
||||||
|
t.Error("Raw sql to update records")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue