Skip to content

Commit 30aac69

Browse files
authored
Merge pull request #140 from timshannon/issue139
Added missing key handling in sort queries
2 parents dca5178 + 9e67def commit 30aac69

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

query.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ func (s *Store) runQuerySort(source BucketSource, dataType interface{}, query *Q
144144
}
145145
}
146146

147+
tp := query.dataType
148+
149+
var keyType reflect.Type
150+
var keyField string
151+
152+
for i := 0; i < tp.NumField(); i++ {
153+
if strings.Contains(string(tp.Field(i).Tag), BoltholdKeyTag) {
154+
keyType = tp.Field(i).Type
155+
keyField = tp.Field(i).Name
156+
break
157+
}
158+
}
159+
147160
// Run query without sort, skip or limit
148161
// apply sort, skip and limit to entire dataset
149162
qCopy := *query
@@ -154,6 +167,24 @@ func (s *Store) runQuerySort(source BucketSource, dataType interface{}, query *Q
154167
var records []*record
155168
err := s.runQuery(source, dataType, &qCopy, nil, 0,
156169
func(r *record) error {
170+
if keyType != nil {
171+
var rowValue reflect.Value
172+
173+
// FIXME:
174+
if tp.Kind() == reflect.Ptr {
175+
rowValue = r.value
176+
} else {
177+
rowValue = r.value.Elem()
178+
}
179+
rowKey := rowValue
180+
for rowKey.Kind() == reflect.Ptr {
181+
rowKey = rowKey.Elem()
182+
}
183+
err := s.decode(r.key, rowKey.FieldByName(keyField).Addr().Interface())
184+
if err != nil {
185+
return err
186+
}
187+
}
157188
records = append(records, r)
158189

159190
return nil

sort_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ var sortTests = []test{
7272
query: bolthold.Where("Category").Eq("animal").SortBy("Name").Skip(10),
7373
result: []int{},
7474
},
75+
{
76+
name: "Sort By Key",
77+
query: bolthold.Where("Category").Eq("animal").SortBy("Key"),
78+
result: []int{2, 5, 8, 9, 13, 14, 16},
79+
},
80+
{
81+
name: "Sort By Key Reversed",
82+
query: bolthold.Where("Category").Eq("animal").SortBy("Key").Reverse(),
83+
result: []int{16, 14, 13, 9, 8, 5, 2},
84+
},
7585
}
7686

7787
func TestSortedFind(t *testing.T) {
@@ -259,3 +269,45 @@ func TestSortedFindWithNonSlicePtr(t *testing.T) {
259269
_ = store.Find(result, bolthold.Where("Name").Eq("blah").SortBy("Name"))
260270
})
261271
}
272+
273+
func TestIssue139SortOnSequenceKey(t *testing.T) {
274+
testWrap(t, func(store *bolthold.Store, t *testing.T) {
275+
276+
type Row struct {
277+
ID uint64 `boltholdKey:"ID"`
278+
}
279+
280+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
281+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
282+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
283+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
284+
285+
var rows []*Row
286+
ok(t, store.Find(&rows, (&bolthold.Query{}).SortBy("ID").Reverse()))
287+
equals(t, uint64(4), rows[0].ID)
288+
equals(t, uint64(3), rows[1].ID)
289+
equals(t, uint64(2), rows[2].ID)
290+
equals(t, uint64(1), rows[3].ID)
291+
292+
})
293+
294+
testWrap(t, func(store *bolthold.Store, t *testing.T) {
295+
296+
type Row struct {
297+
ID *uint64 `boltholdKey:"ID"`
298+
}
299+
300+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
301+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
302+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
303+
ok(t, store.Insert(bolthold.NextSequence(), &Row{}))
304+
305+
var rows []*Row
306+
ok(t, store.Find(&rows, (&bolthold.Query{}).SortBy("ID").Reverse()))
307+
equals(t, uint64(4), *rows[0].ID)
308+
equals(t, uint64(3), *rows[1].ID)
309+
equals(t, uint64(2), *rows[2].ID)
310+
equals(t, uint64(1), *rows[3].ID)
311+
312+
})
313+
}

0 commit comments

Comments
 (0)