Skip to content

Commit

Permalink
firestore: marshal keys as []byte
Browse files Browse the repository at this point in the history
Same as values, `backend.Item` passes keys as `[]byte` and has no
guarantees about the encoding. GetRange queries need extra care because
of this type mismatch too: `where` clauses are type-sensitive.
  • Loading branch information
Andrew Lytvynov committed Aug 11, 2020
1 parent 4105887 commit 6a212f1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
24 changes: 18 additions & 6 deletions lib/backend/firestore/firestorebk.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ type FirestoreBackend struct {
}

type record struct {
Key string `firestore:"key,omitempty"`
Key []byte `firestore:"key,omitempty"`
Timestamp int64 `firestore:"timestamp,omitempty"`
Expires int64 `firestore:"expires,omitempty"`
ID int64 `firestore:"id,omitempty"`
Expand All @@ -135,7 +135,7 @@ type legacyRecord struct {

func newRecord(from backend.Item, clock clockwork.Clock) record {
r := record{
Key: string(from.Key),
Key: from.Key,
Value: from.Value,
Timestamp: clock.Now().UTC().Unix(),
ID: clock.Now().UTC().UnixNano(),
Expand All @@ -157,7 +157,7 @@ func newRecordFromDoc(doc *firestore.DocumentSnapshot) (*record, error) {
return nil, ConvertGRPCError(err)
}
r = record{
Key: rl.Key,
Key: []byte(rl.Key),
Value: []byte(rl.Value),
Timestamp: rl.Timestamp,
Expires: rl.Expires,
Expand All @@ -178,7 +178,7 @@ func (r *record) isExpired() bool {

func (r *record) backendItem() backend.Item {
bi := backend.Item{
Key: []byte(r.Key),
Key: r.Key,
Value: r.Value,
ID: r.ID,
}
Expand Down Expand Up @@ -341,11 +341,23 @@ func (b *FirestoreBackend) getRangeDocs(ctx context.Context, startKey []byte, en
if limit <= 0 {
limit = backend.DefaultLargeLimit
}
return b.svc.Collection(b.CollectionName).
docs, err := b.svc.Collection(b.CollectionName).
Where(keyDocProperty, ">=", startKey).
Where(keyDocProperty, "<=", endKey).
Limit(limit).
Documents(ctx).GetAll()
if err != nil {
return nil, trace.Wrap(err)
}
legacyDocs, err := b.svc.Collection(b.CollectionName).
Where(keyDocProperty, ">=", string(startKey)).
Where(keyDocProperty, "<=", string(endKey)).
Limit(limit).
Documents(ctx).GetAll()
if err != nil {
return nil, trace.Wrap(err)
}
return append(docs, legacyDocs...), nil
}

// GetRange returns range of elements
Expand Down Expand Up @@ -612,7 +624,7 @@ func (b *FirestoreBackend) watchCollection() error {
e = backend.Event{
Type: backend.OpDelete,
Item: backend.Item{
Key: []byte(r.Key),
Key: r.Key,
},
}
}
Expand Down
10 changes: 10 additions & 0 deletions lib/backend/firestore/firestorebk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,14 @@ func (s *FirestoreSuite) TestReadLegacyRecord(c *check.C) {
c.Assert(got.Value, check.DeepEquals, item.Value)
c.Assert(got.ID, check.DeepEquals, item.ID)
c.Assert(got.Expires.Equal(item.Expires), check.Equals, true)

// Read the data back using a range query too.
gotRange, err := s.bk.GetRange(ctx, item.Key, item.Key, 1)
c.Assert(err, check.IsNil)
c.Assert(len(gotRange.Items), check.Equals, 1)
got = &gotRange.Items[0]
c.Assert(got.Key, check.DeepEquals, item.Key)
c.Assert(got.Value, check.DeepEquals, item.Value)
c.Assert(got.ID, check.DeepEquals, item.ID)
c.Assert(got.Expires.Equal(item.Expires), check.Equals, true)
}
6 changes: 4 additions & 2 deletions lib/backend/test/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ func (s *BackendSuite) CRUD(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(string(out.Value), check.Equals, string(item.Value))

// put with binary data succeeds
// put with binary key and value succeeds
key := make([]byte, 1024)
rand.Read(key)
data := make([]byte, 1024)
rand.Read(data)
item = backend.Item{Key: prefix("/binary"), Value: data}
item = backend.Item{Key: prefix(string(key)), Value: data}
_, err = s.B.Put(ctx, item)
c.Assert(err, check.IsNil)

Expand Down

0 comments on commit 6a212f1

Please sign in to comment.