forked from mirror/gorm
Search with struct
This commit is contained in:
parent
fd3ed7ffaf
commit
c74af2210d
|
@ -64,6 +64,8 @@ db.Where("name in (?)", []string["jinzhu", "jinzhu 2"]).Find(&users)
|
||||||
//// users -> select * from users name in ('jinzhu', 'jinzhu 2');
|
//// users -> select * from users name in ('jinzhu', 'jinzhu 2');
|
||||||
db.Where("name LIKE ?", "%jin%").Find(&users)
|
db.Where("name LIKE ?", "%jin%").Find(&users)
|
||||||
//// users -> select * from users name LIKE "%jinzhu%";
|
//// users -> select * from users name LIKE "%jinzhu%";
|
||||||
|
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
|
||||||
|
//// user -> select * from users name = "jinzhu" and age = 20 limit 1;
|
||||||
db.Where("birthday < ?", time.Now()).Find(&users)
|
db.Where("birthday < ?", time.Now()).Find(&users)
|
||||||
|
|
||||||
// Inline search condition
|
// Inline search condition
|
||||||
|
@ -75,6 +77,8 @@ db.Find(&users, "name = ?", "jinzhu")
|
||||||
//// users -> select * from users where name = "jinzhu";
|
//// users -> select * from users where name = "jinzhu";
|
||||||
db.Find(&users, "name <> ? and age > ?", "jinzhu", 20)
|
db.Find(&users, "name <> ? and age > ?", "jinzhu", 20)
|
||||||
//// users -> select * from users where name <> "jinzhu" and age > 20;
|
//// users -> select * from users where name <> "jinzhu" and age > 20;
|
||||||
|
db.Find(&users, &User{Age: 20})
|
||||||
|
//// users -> select * from users where age = 20;
|
||||||
|
|
||||||
// Select
|
// Select
|
||||||
db.Select("name").Find(&users)
|
db.Select("name").Find(&users)
|
||||||
|
@ -243,7 +247,6 @@ db.Where("mail_type = ?", "TEXT").Find(&users1).Table("deleted_users").First(&us
|
||||||
```
|
```
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
* Query with struct
|
|
||||||
* SubStruct
|
* SubStruct
|
||||||
* Index, Unique, Valiations
|
* Index, Unique, Valiations
|
||||||
* Auto Migration
|
* Auto Migration
|
||||||
|
|
16
do.go
16
do.go
|
@ -330,9 +330,10 @@ func (s *Do) primaryCondiation(value interface{}) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Do) buildWhereCondition(clause map[string]interface{}) (str string) {
|
func (s *Do) buildWhereCondition(clause map[string]interface{}) (str string) {
|
||||||
switch clause["query"].(type) {
|
query := clause["query"]
|
||||||
|
switch query.(type) {
|
||||||
case string:
|
case string:
|
||||||
value := clause["query"].(string)
|
value := query.(string)
|
||||||
if regexp.MustCompile("^\\s*\\d+\\s*$").MatchString(value) {
|
if regexp.MustCompile("^\\s*\\d+\\s*$").MatchString(value) {
|
||||||
id, _ := strconv.Atoi(value)
|
id, _ := strconv.Atoi(value)
|
||||||
return s.primaryCondiation(s.addToVars(id))
|
return s.primaryCondiation(s.addToVars(id))
|
||||||
|
@ -340,10 +341,17 @@ func (s *Do) buildWhereCondition(clause map[string]interface{}) (str string) {
|
||||||
str = "( " + value + " )"
|
str = "( " + value + " )"
|
||||||
}
|
}
|
||||||
case int, int64, int32:
|
case int, int64, int32:
|
||||||
return s.primaryCondiation(s.addToVars(clause["query"]))
|
return s.primaryCondiation(s.addToVars(query))
|
||||||
case []int64, []int, []int32, []string:
|
case []int64, []int, []int32, []string:
|
||||||
str = fmt.Sprintf("(%v in (?))", s.model.primaryKeyDb())
|
str = fmt.Sprintf("(%v in (?))", s.model.primaryKeyDb())
|
||||||
clause["args"] = []interface{}{clause["query"]}
|
clause["args"] = []interface{}{query}
|
||||||
|
case interface{}:
|
||||||
|
m := &Model{data: query, driver: s.driver}
|
||||||
|
var sqls []string
|
||||||
|
for _, field := range m.columnsHasValue("") {
|
||||||
|
sqls = append(sqls, fmt.Sprintf(" ( %v = %v ) ", field.DbName, s.addToVars(field.Value)))
|
||||||
|
}
|
||||||
|
return strings.Join(sqls, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
args := clause["args"].([]interface{})
|
args := clause["args"].([]interface{})
|
||||||
|
|
33
gorm_test.go
33
gorm_test.go
|
@ -51,7 +51,7 @@ func init() {
|
||||||
|
|
||||||
err = db.Exec("drop table users;").Error
|
err = db.Exec("drop table users;").Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Got error when try to delete table uses, %+v\n", err)
|
fmt.Printf("Got error when try to delete table users, %+v\n", err)
|
||||||
}
|
}
|
||||||
db.Exec("drop table products;")
|
db.Exec("drop table products;")
|
||||||
|
|
||||||
|
@ -193,9 +193,9 @@ func TestComplexWhere(t *testing.T) {
|
||||||
if len(user_ids) != 3 {
|
if len(user_ids) != 3 {
|
||||||
t.Errorf("Should only found 3 users that age > 20, but have %v", len(users))
|
t.Errorf("Should only found 3 users that age > 20, but have %v", len(users))
|
||||||
}
|
}
|
||||||
|
|
||||||
users = []User{}
|
users = []User{}
|
||||||
db.Where(user_ids).Find(&users)
|
db.Where(user_ids).Find(&users)
|
||||||
|
|
||||||
if len(users) != 3 {
|
if len(users) != 3 {
|
||||||
t.Errorf("Should only found 3 users that age > 20 when search with id map, but have %v", len(users))
|
t.Errorf("Should only found 3 users that age > 20 when search with id map, but have %v", len(users))
|
||||||
}
|
}
|
||||||
|
@ -289,6 +289,35 @@ func TestComplexWhere(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWhereWithStruct(t *testing.T) {
|
||||||
|
var user User
|
||||||
|
db.First(&user, &User{Name: "2"})
|
||||||
|
if user.Id == 0 || user.Name != "2" {
|
||||||
|
t.Errorf("Should be able to search first record with struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
db.First(&user, User{Name: "2"})
|
||||||
|
if user.Id == 0 || user.Name != "2" {
|
||||||
|
t.Errorf("Should be able to search first record with struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Where(&User{Name: "2"}).First(&user)
|
||||||
|
if user.Id == 0 || user.Name != "2" {
|
||||||
|
t.Errorf("Should be able to search first record with struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
var users []User
|
||||||
|
db.Find(&users, &User{Name: "3"})
|
||||||
|
if len(users) != 2 {
|
||||||
|
t.Errorf("Should be able to search all record with struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Where(User{Name: "3"}).Find(&users)
|
||||||
|
if user.Id == 0 || user.Name != "2" {
|
||||||
|
t.Errorf("Should be able to search first record with struct")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInitlineCondition(t *testing.T) {
|
func TestInitlineCondition(t *testing.T) {
|
||||||
var u1, u2, u3, u4, u5, u6, u7 User
|
var u1, u2, u3, u4, u5, u6, u7 User
|
||||||
db.Where("name = ?", "3").Order("age desc").First(&u1).First(&u2)
|
db.Where("name = ?", "3").Order("age desc").First(&u1).First(&u2)
|
||||||
|
|
27
model.go
27
model.go
|
@ -22,6 +22,7 @@ type Field struct {
|
||||||
AutoCreateTime bool
|
AutoCreateTime bool
|
||||||
AutoUpdateTime bool
|
AutoUpdateTime bool
|
||||||
IsPrimaryKey bool
|
IsPrimaryKey bool
|
||||||
|
IsBlank bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) primaryKeyZero() bool {
|
func (m *Model) primaryKeyZero() bool {
|
||||||
|
@ -57,7 +58,8 @@ func (m *Model) primaryKeyDb() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) fields(operation string) (fields []Field) {
|
func (m *Model) fields(operation string) (fields []Field) {
|
||||||
typ := reflect.TypeOf(m.data).Elem()
|
indirect_value := reflect.Indirect(reflect.ValueOf(m.data))
|
||||||
|
typ := indirect_value.Type()
|
||||||
|
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
p := typ.Field(i)
|
p := typ.Field(i)
|
||||||
|
@ -68,7 +70,18 @@ func (m *Model) fields(operation string) (fields []Field) {
|
||||||
field.IsPrimaryKey = m.primaryKeyDb() == field.DbName
|
field.IsPrimaryKey = m.primaryKeyDb() == field.DbName
|
||||||
field.AutoCreateTime = "created_at" == field.DbName
|
field.AutoCreateTime = "created_at" == field.DbName
|
||||||
field.AutoUpdateTime = "updated_at" == field.DbName
|
field.AutoUpdateTime = "updated_at" == field.DbName
|
||||||
value := reflect.ValueOf(m.data).Elem().FieldByName(p.Name)
|
value := indirect_value.FieldByName(p.Name)
|
||||||
|
|
||||||
|
switch value.Kind() {
|
||||||
|
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||||
|
field.IsBlank = value.Int() == 0
|
||||||
|
case reflect.String:
|
||||||
|
field.IsBlank = value.String() == ""
|
||||||
|
default:
|
||||||
|
if value, ok := value.Interface().(time.Time); ok {
|
||||||
|
field.IsBlank = value.IsZero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch operation {
|
switch operation {
|
||||||
case "create":
|
case "create":
|
||||||
|
@ -92,6 +105,16 @@ func (m *Model) fields(operation string) (fields []Field) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) columnsHasValue(operation string) (fields []Field) {
|
||||||
|
for _, field := range m.fields(operation) {
|
||||||
|
if !field.IsBlank {
|
||||||
|
fields = append(fields, field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) columnsAndValues(operation string) map[string]interface{} {
|
func (m *Model) columnsAndValues(operation string) map[string]interface{} {
|
||||||
|
|
Loading…
Reference in New Issue