Merge 977a60eb3f9fefaf414f0c0ed8d4fd2e888253ad into caa792644ce60fd7b429e0616afbdbccdf011be2

This commit is contained in:
Jay Taylor 2016-06-23 13:48:38 +00:00 committed by GitHub
commit 12377105a0
6 changed files with 32 additions and 22 deletions

View File

@ -35,7 +35,7 @@ type Dialect interface {
HasColumn(tableName string, columnName string) bool HasColumn(tableName string, columnName string) bool
// LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case // LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case
LimitAndOffsetSQL(limit, offset int) string LimitAndOffsetSQL(limit, offset interface{}) string
// SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL` // SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
SelectFromDummyTable() string SelectFromDummyTable() string
// LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING` // LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING`

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"regexp" "regexp"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -122,13 +123,15 @@ func (s commonDialect) currentDatabase() (name string) {
return return
} }
func (commonDialect) LimitAndOffsetSQL(limit, offset int) (sql string) { func (commonDialect) LimitAndOffsetSQL(limit, offset interface{}) (sql string) {
if limit > 0 || offset > 0 { if limit != nil {
if limit >= 0 { if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit > 0 {
sql += fmt.Sprintf(" LIMIT %d", limit) sql += fmt.Sprintf(" LIMIT %d", parsedLimit)
} }
if offset >= 0 { }
sql += fmt.Sprintf(" OFFSET %d", offset) if offset != nil {
if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset > 0 {
sql += fmt.Sprintf(" OFFSET %d", parsedOffset)
} }
} }
return return

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"reflect" "reflect"
"strconv"
"strings" "strings"
"time" "time"
@ -127,16 +128,15 @@ func (s mssql) currentDatabase() (name string) {
return return
} }
func (mssql) LimitAndOffsetSQL(limit, offset int) (sql string) { func (mssql) LimitAndOffsetSQL(limit, offset interface{}) (sql string) {
if limit > 0 || offset > 0 { if limit != nil {
if offset < 0 { if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit > 0 {
offset = 0 sql += fmt.Sprintf(" FETCH NEXT %d ROWS ONLY", parsedLimit)
} }
}
sql += fmt.Sprintf(" OFFSET %d ROWS", offset) if offset != nil {
if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset > 0 {
if limit >= 0 { sql += fmt.Sprintf(" OFFSET %d ROWS", parsedOffset)
sql += fmt.Sprintf(" FETCH NEXT %d ROWS ONLY", limit)
} }
} }
return return

View File

@ -156,12 +156,12 @@ func (s *DB) Not(query interface{}, args ...interface{}) *DB {
} }
// Limit specify the number of records to be retrieved // Limit specify the number of records to be retrieved
func (s *DB) Limit(limit int) *DB { func (s *DB) Limit(limit interface{}) *DB {
return s.clone().search.Limit(limit).db return s.clone().search.Limit(limit).db
} }
// Offset specify the number of records to skip before starting to return the records // Offset specify the number of records to skip before starting to return the records
func (s *DB) Offset(offset int) *DB { func (s *DB) Offset(offset interface{}) *DB {
return s.clone().search.Offset(offset).db return s.clone().search.Offset(offset).db
} }

View File

@ -3,6 +3,7 @@ package gorm_test
import ( import (
"database/sql/driver" "database/sql/driver"
"encoding/json" "encoding/json"
"fmt"
"testing" "testing"
) )
@ -51,6 +52,12 @@ func (l ExampleStringSlice) Value() (driver.Value, error) {
} }
func (l *ExampleStringSlice) Scan(input interface{}) error { func (l *ExampleStringSlice) Scan(input interface{}) error {
switch input.(type) {
case string:
fmt.Printf("string: %+v\n", input.(string))
case []byte:
fmt.Printf("[]byte: %+v\n", string(input.([]byte)))
}
return json.Unmarshal(input.([]byte), l) return json.Unmarshal(input.([]byte), l)
} }

View File

@ -15,8 +15,8 @@ type search struct {
omits []string omits []string
orders []string orders []string
preload []searchPreload preload []searchPreload
offset int offset interface{}
limit int limit interface{}
group string group string
tableName string tableName string
raw bool raw bool
@ -82,12 +82,12 @@ func (s *search) Omit(columns ...string) *search {
return s return s
} }
func (s *search) Limit(limit int) *search { func (s *search) Limit(limit interface{}) *search {
s.limit = limit s.limit = limit
return s return s
} }
func (s *search) Offset(offset int) *search { func (s *search) Offset(offset interface{}) *search {
s.offset = offset s.offset = offset
return s return s
} }