mirror of https://github.com/go-gorm/gorm.git
Add method Raw and Scan
This commit is contained in:
parent
3e24b14906
commit
8010616e89
30
README.md
30
README.md
|
@ -818,16 +818,42 @@ db.Debug().Where("name = ?", "jinzhu").First(&User{})
|
|||
Row & Rows is not chainable, it works just like `QueryRow` and `Query`
|
||||
|
||||
```go
|
||||
row := db.Where("name = ?", "jinzhu").select("name, age").Row() // (*sql.Row)
|
||||
row := db.Table("users").Where("name = ?", "jinzhu").select("name, age").Row() // (*sql.Row)
|
||||
row.Scan(&name, &age)
|
||||
|
||||
rows, err := db.Where("name = ?", "jinzhu").select("name, age, email").Rows() // (*sql.Rows, error)
|
||||
rows, err := db.Model(User{}).Where("name = ?", "jinzhu").select("name, age, email").Rows() // (*sql.Rows, error)
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
...
|
||||
rows.Scan(&name, &age, &email)
|
||||
...
|
||||
}
|
||||
|
||||
// Rows() with raw sql
|
||||
rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows() // (*sql.Rows, error)
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
...
|
||||
rows.Scan(&name, &age, &email)
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Scan
|
||||
|
||||
Scan sql results into strcut
|
||||
|
||||
```go
|
||||
type Result struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
var result Result
|
||||
db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&result)
|
||||
|
||||
// Scan raw sql
|
||||
db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)
|
||||
```
|
||||
|
||||
## Group & Having
|
||||
|
|
13
do.go
13
do.go
|
@ -327,7 +327,11 @@ func (s *Do) delete() *Do {
|
|||
}
|
||||
|
||||
func (s *Do) prepareQuerySql() {
|
||||
if s.search.raw {
|
||||
s.setSql(strings.TrimLeft(s.combinedSql(), "WHERE "))
|
||||
} else {
|
||||
s.setSql(fmt.Sprintf("SELECT %v FROM %v %v", s.selectSql(), s.table(), s.combinedSql()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -398,13 +402,18 @@ func (s *Do) rows() (*sql.Rows, error) {
|
|||
return s.db.db.Query(s.sql, s.sqlVars...)
|
||||
}
|
||||
|
||||
func (s *Do) query() *Do {
|
||||
func (s *Do) query(dests ...interface{}) *Do {
|
||||
defer s.trace(time.Now())
|
||||
var (
|
||||
is_slice bool
|
||||
dest_type reflect.Type
|
||||
)
|
||||
dest_out := reflect.Indirect(reflect.ValueOf(s.value))
|
||||
var dest_out reflect.Value
|
||||
if len(dests) > 0 {
|
||||
dest_out = reflect.Indirect(reflect.ValueOf(dests[0]))
|
||||
} else {
|
||||
dest_out = reflect.Indirect(reflect.ValueOf(s.value))
|
||||
}
|
||||
|
||||
if dest_out.Kind() == reflect.Slice {
|
||||
is_slice = true
|
||||
|
|
36
gorm_test.go
36
gorm_test.go
|
@ -1527,6 +1527,42 @@ func TestRows(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type result struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
func TestScan(t *testing.T) {
|
||||
var res result
|
||||
db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&res)
|
||||
if res.Name != "3" {
|
||||
t.Errorf("Scan into struct should works")
|
||||
}
|
||||
|
||||
var ress []result
|
||||
db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&ress)
|
||||
if len(ress) != 2 || ress[0].Name != "3" || ress[1].Name != "3" {
|
||||
t.Errorf("Scan into struct map")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRaw(t *testing.T) {
|
||||
var ress []result
|
||||
db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&ress)
|
||||
if len(ress) != 2 || ress[0].Name != "3" || ress[1].Name != "3" {
|
||||
t.Errorf("Raw with scan")
|
||||
}
|
||||
|
||||
rows, _ := db.Raw("select name, age from users where name = ?", 3).Rows()
|
||||
count := 0
|
||||
for rows.Next() {
|
||||
count++
|
||||
}
|
||||
if count != 2 {
|
||||
t.Errorf("Raw with Rows should find two records with name 3")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroup(t *testing.T) {
|
||||
rows, err := db.Select("name").Table("users").Group("name").Rows()
|
||||
|
||||
|
|
8
main.go
8
main.go
|
@ -128,6 +128,10 @@ func (s *DB) Rows() (*sql.Rows, error) {
|
|||
return s.do(s.data).rows()
|
||||
}
|
||||
|
||||
func (s *DB) Scan(dest interface{}) *DB {
|
||||
return s.do(s.data).query(dest).db
|
||||
}
|
||||
|
||||
func (s *DB) Attrs(attrs ...interface{}) *DB {
|
||||
return s.clone().search.attrs(attrs...).db
|
||||
}
|
||||
|
@ -180,6 +184,10 @@ func (s *DB) Delete(value interface{}) *DB {
|
|||
return s.clone().do(value).begin().delete().commit_or_rollback().db
|
||||
}
|
||||
|
||||
func (s *DB) Raw(sql string, values ...interface{}) *DB {
|
||||
return s.clone().search.setraw(true).where(sql, values...).db
|
||||
}
|
||||
|
||||
func (s *DB) Exec(sql string, values ...interface{}) *DB {
|
||||
return s.clone().do(nil).raw(sql, values...).exec().db
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ type search struct {
|
|||
groupStr string
|
||||
tableName string
|
||||
unscope bool
|
||||
raw bool
|
||||
}
|
||||
|
||||
func (s *search) clone() *search {
|
||||
|
@ -39,6 +40,7 @@ func (s *search) clone() *search {
|
|||
groupStr: s.groupStr,
|
||||
joinsStr: s.joinsStr,
|
||||
tableName: s.tableName,
|
||||
raw: s.raw,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,6 +112,11 @@ func (s *search) joins(query string) *search {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *search) setraw(b bool) *search {
|
||||
s.raw = b
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *search) unscoped() *search {
|
||||
s.unscope = true
|
||||
return s
|
||||
|
|
Loading…
Reference in New Issue