diff --git a/dialect.go b/dialect.go index 033b9555..96bf4a2c 100644 --- a/dialect.go +++ b/dialect.go @@ -35,7 +35,7 @@ type Dialect interface { HasColumn(tableName string, columnName string) bool // 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() string // LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING` diff --git a/dialect_common.go b/dialect_common.go index 6d43fb84..8e66110f 100644 --- a/dialect_common.go +++ b/dialect_common.go @@ -5,6 +5,7 @@ import ( "fmt" "reflect" "regexp" + "strconv" "strings" "time" ) @@ -122,13 +123,15 @@ func (s commonDialect) currentDatabase() (name string) { return } -func (commonDialect) LimitAndOffsetSQL(limit, offset int) (sql string) { - if limit > 0 || offset > 0 { - if limit >= 0 { - sql += fmt.Sprintf(" LIMIT %d", limit) +func (commonDialect) LimitAndOffsetSQL(limit, offset interface{}) (sql string) { + if limit != nil { + if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit > 0 { + 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 diff --git a/dialects/mssql/mssql.go b/dialects/mssql/mssql.go index 34eda717..fcdd0ed8 100644 --- a/dialects/mssql/mssql.go +++ b/dialects/mssql/mssql.go @@ -4,6 +4,7 @@ import ( "database/sql" "fmt" "reflect" + "strconv" "strings" "time" @@ -127,16 +128,15 @@ func (s mssql) currentDatabase() (name string) { return } -func (mssql) LimitAndOffsetSQL(limit, offset int) (sql string) { - if limit > 0 || offset > 0 { - if offset < 0 { - offset = 0 +func (mssql) LimitAndOffsetSQL(limit, offset interface{}) (sql string) { + if limit != nil { + if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit > 0 { + sql += fmt.Sprintf(" FETCH NEXT %d ROWS ONLY", parsedLimit) } - - sql += fmt.Sprintf(" OFFSET %d ROWS", offset) - - if limit >= 0 { - sql += fmt.Sprintf(" FETCH NEXT %d ROWS ONLY", limit) + } + if offset != nil { + if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset > 0 { + sql += fmt.Sprintf(" OFFSET %d ROWS", parsedOffset) } } return diff --git a/main.go b/main.go index cd445555..82ec2a16 100644 --- a/main.go +++ b/main.go @@ -156,12 +156,12 @@ func (s *DB) Not(query interface{}, args ...interface{}) *DB { } // 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 } // 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 } diff --git a/search.go b/search.go index 078bd429..1cb577ad 100644 --- a/search.go +++ b/search.go @@ -15,8 +15,8 @@ type search struct { omits []string orders []string preload []searchPreload - offset int - limit int + offset interface{} + limit interface{} group string tableName string raw bool @@ -82,12 +82,12 @@ func (s *search) Omit(columns ...string) *search { return s } -func (s *search) Limit(limit int) *search { +func (s *search) Limit(limit interface{}) *search { s.limit = limit return s } -func (s *search) Offset(offset int) *search { +func (s *search) Offset(offset interface{}) *search { s.offset = offset return s }