mirror of https://github.com/perkeep/perkeep.git
search: implement post-search Created sort
Fix some UI queries, since UI always queries with "-created". Also add Unsorted, to override the CreatedDesc default, for when we really do not want to sort, e.g. when we don't have a corpus and trying to sort would make us error out. Issue #579 Change-Id: Ife0aa816c5e8cac8dc6612d0ffd104238abc6838
This commit is contained in:
parent
017d57d9d2
commit
3e79e73272
|
@ -44,6 +44,7 @@ type SortType int
|
|||
|
||||
const (
|
||||
UnspecifiedSort SortType = iota
|
||||
Unsorted
|
||||
LastModifiedDesc
|
||||
LastModifiedAsc
|
||||
CreatedDesc
|
||||
|
@ -53,6 +54,7 @@ const (
|
|||
)
|
||||
|
||||
var sortName = map[SortType][]byte{
|
||||
Unsorted: []byte(`"unsorted"`),
|
||||
LastModifiedDesc: []byte(`"-mod"`),
|
||||
LastModifiedAsc: []byte(`"mod"`),
|
||||
CreatedDesc: []byte(`"-created"`),
|
||||
|
@ -88,8 +90,13 @@ type SearchQuery struct {
|
|||
Expression string `json:"expression,omitempty"`
|
||||
Constraint *Constraint `json:"constraint,omitempty"`
|
||||
|
||||
Limit int `json:"limit,omitempty"` // optional. default is automatic. negative means no limit.
|
||||
Sort SortType `json:"sort,omitempty"` // optional. default is automatic or unsorted.
|
||||
// Limit is the maximum number of returned results. A negative value means no
|
||||
// limit. If unspecified, a default (of 200) will be used.
|
||||
Limit int `json:"limit,omitempty"`
|
||||
|
||||
// Sort specifies how the results will be sorted. It defaults to CreatedDesc when the
|
||||
// query is about permanodes only.
|
||||
Sort SortType `json:"sort,omitempty"`
|
||||
|
||||
// Continue specifies the opaque token (as returned by a
|
||||
// SearchResult) for where to continue fetching results when
|
||||
|
@ -134,7 +141,7 @@ func (q *SearchQuery) plannedQuery(expr *SearchQuery) *SearchQuery {
|
|||
pq.Limit = expr.Limit
|
||||
}
|
||||
}
|
||||
if pq.Sort == 0 {
|
||||
if pq.Sort == UnspecifiedSort {
|
||||
if pq.Constraint.onlyMatchesPermanode() {
|
||||
pq.Sort = CreatedDesc
|
||||
}
|
||||
|
@ -862,12 +869,42 @@ func (h *Handler) Query(rawq *SearchQuery) (*SearchResult, error) {
|
|||
}
|
||||
if !cands.sorted {
|
||||
switch q.Sort {
|
||||
case UnspecifiedSort:
|
||||
case UnspecifiedSort, Unsorted:
|
||||
// Nothing to do.
|
||||
case BlobRefAsc:
|
||||
sort.Sort(sortSearchResultBlobs{res.Blobs, func(a, b *SearchResultBlob) bool {
|
||||
return a.Blob.Less(b.Blob)
|
||||
}})
|
||||
case CreatedDesc, CreatedAsc:
|
||||
if corpus == nil {
|
||||
return nil, errors.New("TODO: Sorting without a corpus unsupported")
|
||||
}
|
||||
var err error
|
||||
corpus.RLock()
|
||||
sort.Sort(sortSearchResultBlobs{res.Blobs, func(a, b *SearchResultBlob) bool {
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
ta, ok := corpus.PermanodeAnyTimeLocked(a.Blob)
|
||||
if !ok {
|
||||
err = fmt.Errorf("no ctime or modtime found for %v", a.Blob)
|
||||
return false
|
||||
}
|
||||
tb, ok := corpus.PermanodeAnyTimeLocked(b.Blob)
|
||||
if !ok {
|
||||
err = fmt.Errorf("no ctime or modtime found for %v", b.Blob)
|
||||
return false
|
||||
}
|
||||
if q.Sort == CreatedAsc {
|
||||
return ta.Before(tb)
|
||||
}
|
||||
return tb.Before(ta)
|
||||
}})
|
||||
corpus.RUnlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO(mpl): LastModifiedDesc, LastModifiedAsc
|
||||
default:
|
||||
return nil, errors.New("TODO: unsupported sort+query combination.")
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ func (i indexType) String() string {
|
|||
type queryTest struct {
|
||||
t testing.TB
|
||||
id *indextest.IndexDeps
|
||||
itype indexType
|
||||
|
||||
Handler func() *Handler
|
||||
}
|
||||
|
@ -92,6 +93,7 @@ func testQueryType(t testing.TB, fn func(*queryTest), itype indexType) {
|
|||
qt := &queryTest{
|
||||
t: t,
|
||||
id: indextest.NewIndexDeps(idx),
|
||||
itype: itype,
|
||||
}
|
||||
qt.id.Fataler = t
|
||||
qt.Handler = func() *Handler {
|
||||
|
@ -118,6 +120,9 @@ func dumpRes(t *testing.T, res *SearchResult) {
|
|||
}
|
||||
|
||||
func (qt *queryTest) wantRes(req *SearchQuery, wanted ...blob.Ref) {
|
||||
if qt.itype == indexClassic {
|
||||
req.Sort = Unsorted
|
||||
}
|
||||
res, err := qt.Handler().Query(req)
|
||||
if err != nil {
|
||||
qt.t.Fatal(err)
|
||||
|
|
|
@ -218,6 +218,8 @@ cam.ServerConnection.prototype.permanodeOfSignerAttrValue = function(signer, att
|
|||
// @param {?object} opt_describe The describe property to send for the query
|
||||
cam.ServerConnection.prototype.buildQuery = function(callerQuery, opt_describe, opt_limit, opt_continuationToken) {
|
||||
var query = {
|
||||
// TODO(mpl): it'd be better to not ask for a sort when none is needed (less work for server),
|
||||
// e.g. for a plain BlobRefPrefix query.
|
||||
sort: "-created"
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue