From df3697f3be86df0e764f5afd865ec4a4d457dcaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net> Date: Tue, 29 Jul 2014 22:25:26 -0500 Subject: [PATCH] Adding order by function on SQLite, PostgreSQL and MySQL adapters (#32). --- main.go | 2 +- main_test.go | 36 ++++++++++++++++++++++++++++++++++-- mongo/result.go | 8 ++++++-- mysql/result.go | 32 ++++++++++++++++++++------------ postgresql/result.go | 32 ++++++++++++++++++++------------ ql/result.go | 32 ++++++++++++++++++++------------ sqlite/result.go | 32 ++++++++++++++++++++------------ 7 files changed, 121 insertions(+), 53 deletions(-) diff --git a/main.go b/main.go index 855e7b8d..44151672 100644 --- a/main.go +++ b/main.go @@ -289,7 +289,7 @@ type Result interface { // Receives fields that define the order in which elements will be returned // in a query, field names may be prefixed with a minus sign (-) indicating // descending order; ascending order would be used by default. - Sort(...string) Result + Sort(...interface{}) Result // Defines specific fields to be fulfilled on results in this result set. Select(...interface{}) Result diff --git a/main_test.go b/main_test.go index ce689374..461d5257 100644 --- a/main_test.go +++ b/main_test.go @@ -517,6 +517,8 @@ func TestSimpleCRUD(t *testing.T) { func TestFibonacci(t *testing.T) { var err error + var res db.Result + var total uint64 for _, wrapper := range wrappers { if settings[wrapper] == nil { @@ -551,9 +553,39 @@ func TestFibonacci(t *testing.T) { } } + // Testing sorting by function. + res = col.Find( + // 5, 6, 7, 3 + db.Or{ + db.And{ + db.Cond{"input >=": 5}, + db.Cond{"input <=": 7}, + }, + db.Cond{"input": 3}, + }, + ) + + // Testing sort by function. + switch wrapper { + case `postgresql`: + res = res.Sort(db.Raw{`RANDOM()`}) + case `sqlite`: + res = res.Sort(db.Raw{`RANDOM()`}) + case `mysql`: + res = res.Sort(db.Raw{`RAND()`}) + } + + total, err = res.Count() + + if err != nil { + t.Fatalf(`%s: %s`, wrapper, err.Error()) + } + + if total != 4 { + t.Fatalf("%s: Expecting a count of 4, got %d.", wrapper, total) + } + // Find() with IN/$in - var res db.Result - var total uint64 var whereIn db.Cond switch wrapper { diff --git a/mongo/result.go b/mongo/result.go index a18034d4..0655eeb0 100644 --- a/mongo/result.go +++ b/mongo/result.go @@ -75,8 +75,12 @@ func (self *Result) Skip(n uint) db.Result { // Determines sorting of results according to the provided names. Fields may be // prefixed by - (minus) which means descending order, ascending order would be // used otherwise. -func (self *Result) Sort(fields ...string) db.Result { - self.queryChunks.Sort = fields +func (self *Result) Sort(fields ...interface{}) db.Result { + ss := make([]string, len(fields)) + for i, field := range fields { + ss[i] = fmt.Sprintf(`%v`, field) + } + self.queryChunks.Sort = ss return self } diff --git a/mysql/result.go b/mysql/result.go index 685dde30..afe77ec2 100644 --- a/mysql/result.go +++ b/mysql/result.go @@ -86,27 +86,35 @@ func (self *Result) Skip(n uint) db.Result { // Determines sorting of results according to the provided names. Fields may be // prefixed by - (minus) which means descending order, ascending order would be // used otherwise. -func (self *Result) Sort(fields ...string) db.Result { +func (self *Result) Sort(fields ...interface{}) db.Result { sortColumns := make(sqlgen.SortColumns, 0, len(fields)) - for _, field := range fields { + l := len(fields) + for i := 0; i < l; i++ { var sort sqlgen.SortColumn - if strings.HasPrefix(field, `-`) { - // Explicit descending order. - sort = sqlgen.SortColumn{ - sqlgen.Column{field[1:]}, - sqlgen.SqlSortDesc, - } - } else { - // Ascending order. + switch value := fields[i].(type) { + case db.Raw: sort = sqlgen.SortColumn{ - sqlgen.Column{field}, + sqlgen.Column{sqlgen.Raw{fmt.Sprintf(`%v`, value.Value)}}, sqlgen.SqlSortAsc, } + case string: + if strings.HasPrefix(value, `-`) { + // Explicit descending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value[1:]}, + sqlgen.SqlSortDesc, + } + } else { + // Ascending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value}, + sqlgen.SqlSortAsc, + } + } } - sortColumns = append(sortColumns, sort) } diff --git a/postgresql/result.go b/postgresql/result.go index c17fdc49..24b3f16b 100644 --- a/postgresql/result.go +++ b/postgresql/result.go @@ -86,27 +86,35 @@ func (self *result) Skip(n uint) db.Result { // Determines sorting of results according to the provided names. Fields may be // prefixed by - (minus) which means descending order, ascending order would be // used otherwise. -func (self *result) Sort(fields ...string) db.Result { +func (self *result) Sort(fields ...interface{}) db.Result { sortColumns := make(sqlgen.SortColumns, 0, len(fields)) - for _, field := range fields { + l := len(fields) + for i := 0; i < l; i++ { var sort sqlgen.SortColumn - if strings.HasPrefix(field, `-`) { - // Explicit descending order. - sort = sqlgen.SortColumn{ - sqlgen.Column{field[1:]}, - sqlgen.SqlSortDesc, - } - } else { - // Ascending order. + switch value := fields[i].(type) { + case db.Raw: sort = sqlgen.SortColumn{ - sqlgen.Column{field}, + sqlgen.Column{sqlgen.Raw{fmt.Sprintf(`%v`, value.Value)}}, sqlgen.SqlSortAsc, } + case string: + if strings.HasPrefix(value, `-`) { + // Explicit descending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value[1:]}, + sqlgen.SqlSortDesc, + } + } else { + // Ascending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value}, + sqlgen.SqlSortAsc, + } + } } - sortColumns = append(sortColumns, sort) } diff --git a/ql/result.go b/ql/result.go index de5aa120..4c9dc638 100644 --- a/ql/result.go +++ b/ql/result.go @@ -86,27 +86,35 @@ func (self *result) Skip(n uint) db.Result { // Determines sorting of results according to the provided names. Fields may be // prefixed by - (minus) which means descending order, ascending order would be // used otherwise. -func (self *result) Sort(fields ...string) db.Result { +func (self *result) Sort(fields ...interface{}) db.Result { sortColumns := make(sqlgen.SortColumns, 0, len(fields)) - for _, field := range fields { + l := len(fields) + for i := 0; i < l; i++ { var sort sqlgen.SortColumn - if strings.HasPrefix(field, `-`) { - // Explicit descending order. - sort = sqlgen.SortColumn{ - sqlgen.Column{field[1:]}, - sqlgen.SqlSortDesc, - } - } else { - // Ascending order. + switch value := fields[i].(type) { + case db.Raw: sort = sqlgen.SortColumn{ - sqlgen.Column{field}, + sqlgen.Column{sqlgen.Raw{fmt.Sprintf(`%v`, value.Value)}}, sqlgen.SqlSortAsc, } + case string: + if strings.HasPrefix(value, `-`) { + // Explicit descending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value[1:]}, + sqlgen.SqlSortDesc, + } + } else { + // Ascending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value}, + sqlgen.SqlSortAsc, + } + } } - sortColumns = append(sortColumns, sort) } diff --git a/sqlite/result.go b/sqlite/result.go index c396daa8..79f14063 100644 --- a/sqlite/result.go +++ b/sqlite/result.go @@ -86,27 +86,35 @@ func (self *result) Skip(n uint) db.Result { // Determines sorting of results according to the provided names. Fields may be // prefixed by - (minus) which means descending order, ascending order would be // used otherwise. -func (self *result) Sort(fields ...string) db.Result { +func (self *result) Sort(fields ...interface{}) db.Result { sortColumns := make(sqlgen.SortColumns, 0, len(fields)) - for _, field := range fields { + l := len(fields) + for i := 0; i < l; i++ { var sort sqlgen.SortColumn - if strings.HasPrefix(field, `-`) { - // Explicit descending order. - sort = sqlgen.SortColumn{ - sqlgen.Column{field[1:]}, - sqlgen.SqlSortDesc, - } - } else { - // Ascending order. + switch value := fields[i].(type) { + case db.Raw: sort = sqlgen.SortColumn{ - sqlgen.Column{field}, + sqlgen.Column{sqlgen.Raw{fmt.Sprintf(`%v`, value.Value)}}, sqlgen.SqlSortAsc, } + case string: + if strings.HasPrefix(value, `-`) { + // Explicit descending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value[1:]}, + sqlgen.SqlSortDesc, + } + } else { + // Ascending order. + sort = sqlgen.SortColumn{ + sqlgen.Column{value}, + sqlgen.SqlSortAsc, + } + } } - sortColumns = append(sortColumns, sort) } -- GitLab