Skip to content

Commit

Permalink
Added NextSequence to generate sequential ids
Browse files Browse the repository at this point in the history
Finished sorting

Closes #24 and #26
  • Loading branch information
timshannon committed Jul 26, 2017
1 parent 5cbf811 commit 166c964
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 13 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,17 @@ type Employee struct {
Hired time.Time
}
```

Bolthold assumes only one of such struct tags exists. If a value already exists in the key field, it will be overwritten.

If you want to insert an auto-incrementing Key you can pass the `bolthold.NextSequence()` func as the Key value.

```Go
err := store.Insert(bolthold.NextSequence(), data)
```

The key value will be a `uint`.


### Aggregate Queries

Aggregate queries are queries that group results by a field. For example, lets say you had a collection of employees:
Expand Down
23 changes: 20 additions & 3 deletions put.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import (
// ErrKeyExists is the error returned when data is being Inserted for a Key that already exists
var ErrKeyExists = errors.New("This Key already exists in this bolthold for this type")

// sequence tells bolthold to insert the key as the next sequence in the bucket
type sequence struct{}

// NextSequence is used to create a sequential key for inserts
// Inserts a uint64 as the key
// store.Insert(bolthold.NextSequence(), data)
func NextSequence() interface{} {
return sequence{}
}

// Insert inserts the passed in data into the the bolthold
// If the the key already exists in the bolthold, then an ErrKeyExists is returned
func (s *Store) Insert(key, data interface{}) error {
Expand All @@ -30,13 +40,20 @@ func (s *Store) TxInsert(tx *bolt.Tx, key, data interface{}) error {

storer := newStorer(data)

gk, err := encode(key)

b, err := tx.CreateBucketIfNotExists([]byte(storer.Type()))
if err != nil {
return err
}

b, err := tx.CreateBucketIfNotExists([]byte(storer.Type()))
if _, ok := key.(sequence); ok {
key, err = b.NextSequence()
if err != nil {
return err
}
}

gk, err := encode(key)

if err != nil {
return err
}
Expand Down
31 changes: 31 additions & 0 deletions put_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,34 @@ func TestIssue14UpdateMatching(t *testing.T) {

})
}

func TestInsertSequence(t *testing.T) {
testWrap(t, func(store *bolthold.Store, t *testing.T) {

type SequenceTest struct {
Key uint `boltholdKey:"Key"`
}

for i := 0; i < 10; i++ {
err := store.Insert(bolthold.NextSequence(), &SequenceTest{})
if err != nil {
t.Fatalf("Error inserting data for sequence test: %s", err)
}
}

var result []SequenceTest

err := store.Find(&result, nil)
if err != nil {
t.Fatalf("Error getting data from bolthold: %s", err)
}

for i := 0; i < 10; i++ {
seq := i + 1
if seq != int(result[i].Key) {
t.Fatalf("Sequence is not correct. Wanted %d, got %d", i, result[i].Key)
}
}

})
}
11 changes: 2 additions & 9 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,15 +559,8 @@ func runQuery(tx *bolt.Tx, dataType interface{}, query *Query, retrievedKeys key

sort.Slice(records, func(i, j int) bool {
for _, field := range query.sort {
var value interface{}
var other interface{}
if query.dataType.Kind() == reflect.Ptr {
value = records[i].value.FieldByName(field).Interface()
other = records[j].value.FieldByName(field).Interface()
} else {
value = records[i].value.Elem().FieldByName(field).Interface()
other = records[j].value.Elem().FieldByName(field).Interface()
}
value := records[i].value.Elem().FieldByName(field).Interface()
other := records[j].value.Elem().FieldByName(field).Interface()

if query.reverse {
value, other = other, value
Expand Down

0 comments on commit 166c964

Please sign in to comment.