Skip to content

Commit

Permalink
Add method Raw and Scan
Browse files Browse the repository at this point in the history
  • Loading branch information
jinzhu committed Jan 3, 2014
1 parent 3e24b14 commit 8010616
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 5 deletions.
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 12 additions & 3 deletions do.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,11 @@ func (s *Do) delete() *Do {
}

func (s *Do) prepareQuerySql() {
s.setSql(fmt.Sprintf("SELECT %v FROM %v %v", s.selectSql(), s.table(), s.combinedSql()))
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
}

Expand Down Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions gorm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down
7 changes: 7 additions & 0 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type search struct {
groupStr string
tableName string
unscope bool
raw bool
}

func (s *search) clone() *search {
Expand All @@ -39,6 +40,7 @@ func (s *search) clone() *search {
groupStr: s.groupStr,
joinsStr: s.joinsStr,
tableName: s.tableName,
raw: s.raw,
}
}

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 8010616

Please sign in to comment.