From 8a05c520f8bcf9a6e75b7e7801ce39fbb269c3d7 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sun, 29 Dec 2013 16:28:06 -0800 Subject: [PATCH] search: make sort type encode as a string in JSON Change-Id: I50c5663e850f3e8710381cc59daf246c8a600482 --- pkg/search/query.go | 27 ++++++++++++++++++- pkg/search/query_test.go | 31 ++++++++++++++++++++++ server/camlistored/ui/server_connection.js | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/pkg/search/query.go b/pkg/search/query.go index 9d702490a..a80cb2951 100644 --- a/pkg/search/query.go +++ b/pkg/search/query.go @@ -17,6 +17,7 @@ limitations under the License. package search import ( + "bytes" "encoding/json" "errors" "fmt" @@ -38,7 +39,6 @@ import ( type SortType int -// TODO: add MarshalJSON and UnmarshalJSON to SortType const ( UnspecifiedSort SortType = iota LastModifiedDesc @@ -48,6 +48,31 @@ const ( maxSortType ) +var sortName = map[SortType][]byte{ + LastModifiedDesc: []byte(`"-mod"`), + LastModifiedAsc: []byte(`"mod"`), + CreatedDesc: []byte(`"-created"`), + CreatedAsc: []byte(`"created"`), +} + +func (t SortType) MarshalJSON() ([]byte, error) { + v, ok := sortName[t] + if !ok { + panic("unnamed SortType " + strconv.Itoa(int(t))) + } + return v, nil +} + +func (t *SortType) UnmarshalJSON(v []byte) error { + for n, nv := range sortName { + if bytes.Equal(v, nv) { + *t = n + return nil + } + } + return fmt.Errorf("Bogus search sort type %q", v) +} + type SearchQuery struct { // Exactly one of Expression or Contraint must be set. // If an Expression is set, it's compiled to an Constraint. diff --git a/pkg/search/query_test.go b/pkg/search/query_test.go index 0170a930f..4354005e9 100644 --- a/pkg/search/query_test.go +++ b/pkg/search/query_test.go @@ -895,6 +895,37 @@ func TestPlannedQuery(t *testing.T) { } } +func TestSortMarshal(t *testing.T) { + q := &SearchQuery{ + Sort: CreatedDesc, + } + enc, err := json.Marshal(q) + if err != nil { + t.Fatal(err) + } + if got, want := string(enc), `{"sort":"-created"}`; got != want { + t.Logf("JSON: %s; want %s", got, want) + } + back := &SearchQuery{} + err = json.Unmarshal(enc, back) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(q, back) { + t.Errorf("Didn't round-trip. Got %#v; want %#v", back, q) + } + + // and the zero value + q = &SearchQuery{} + enc, err = json.Marshal(q) + if err != nil { + t.Fatal(err) + } + if string(enc) != "{}" { + t.Errorf("Zero value: %s; want {}", enc) + } +} + func BenchmarkQueryRecentPermanodes(b *testing.B) { b.ReportAllocs() testQueryTypes(b, corpusTypeOnly, func(qt *queryTest) { diff --git a/server/camlistored/ui/server_connection.js b/server/camlistored/ui/server_connection.js index 3783befa8..2194ce769 100644 --- a/server/camlistored/ui/server_connection.js +++ b/server/camlistored/ui/server_connection.js @@ -174,7 +174,7 @@ camlistore.ServerConnection.prototype.permanodeOfSignerAttrValue = function(sign // @param {?object} opt_describe The describe property to send for the query camlistore.ServerConnection.prototype.buildQuery = function(callerQuery, opt_describe, opt_limit, opt_continuationToken) { var query = { - sort: 1 // LastModifiedDesc + sort: "-mod" }; if (goog.isString(callerQuery)) {