Skip to content

Commit ac3d188

Browse files
committed
Add exptime support for virtual xattrs
1 parent 42bfa64 commit ac3d188

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

collection+xattrs.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const (
2727
virtualXattrName = "$document"
2828
virtualXattrRevSeqNo = "revid"
2929
virtualXattrCAS = "CAS"
30+
virtualXattrExpiry = "exptime"
3031
)
3132

3233
// ////// SGBUCKET XATTR STORE INTERFACE
@@ -412,12 +413,13 @@ func (c *Collection) getRawXattrs(txn *sql.Tx, key string) ([]byte, error) {
412413
// get doc's raw body and an xattr.
413414
func (c *Collection) getRawWithXattrs(key string, xattrKeys []string) (sgbucket.BucketDocument, error) {
414415
var revSeqNo int64
415-
row := c.db().QueryRow(`SELECT value, cas, xattrs, tombstone, revSeqNo FROM documents WHERE collection=?1 AND key=?2`, c.id, key)
416+
var exp Exp
417+
row := c.db().QueryRow(`SELECT value, cas, xattrs, tombstone, revSeqNo, exp FROM documents WHERE collection=?1 AND key=?2`, c.id, key)
416418
rawDoc := sgbucket.BucketDocument{
417419
Xattrs: make(map[string][]byte, len(xattrKeys)),
418420
}
419421
var xattrs []byte
420-
err := scan(row, &rawDoc.Body, &rawDoc.Cas, &xattrs, &rawDoc.IsTombstone, &revSeqNo)
422+
err := scan(row, &rawDoc.Body, &rawDoc.Cas, &xattrs, &rawDoc.IsTombstone, &revSeqNo, &exp)
421423
if err != nil {
422424
return sgbucket.BucketDocument{}, remapKeyError(err, key)
423425
}
@@ -438,6 +440,9 @@ func (c *Collection) getRawWithXattrs(key string, xattrKeys []string) (sgbucket.
438440
} else if xattrKey == virtualXattrName+"."+virtualXattrCAS {
439441
rawDoc.Xattrs[xattrKey] = []byte(fmt.Sprintf(`"0x%s"`, strconv.FormatUint(rawDoc.Cas, 16)))
440442
continue
443+
} else if xattrKey == virtualXattrName+"."+virtualXattrExpiry {
444+
rawDoc.Xattrs[xattrKey] = []byte(strconv.FormatUint(uint64(exp), 10))
445+
continue
441446
}
442447
val, ok := xattrMap[xattrKey]
443448
if !ok {

collection_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,30 @@ func TestVirtualXattr(t *testing.T) {
10881088
expectedCAS := fmt.Sprintf(`0x%s`, strconv.FormatUint(cas, 16))
10891089
require.Equal(t, expectedCAS, fetchedCAS)
10901090
})
1091+
1092+
// $document.exptime returns the doc expiry as a JSON number (always present, even when 0).
1093+
t.Run("expiry", func(t *testing.T) {
1094+
xattrKey := fmt.Sprintf("%s.%s", virtualXattrName, virtualXattrExpiry)
1095+
1096+
// Doc written above has no expiry — should return 0.
1097+
xattrs, _, err := col.GetXattrs(ctx, docID, []string{xattrKey})
1098+
require.NoError(t, err)
1099+
require.Contains(t, xattrs, xattrKey)
1100+
var fetchedExpiry uint32
1101+
require.NoError(t, json.Unmarshal(xattrs[xattrKey], &fetchedExpiry))
1102+
require.Equal(t, uint32(0), fetchedExpiry)
1103+
1104+
// Write a doc with a real expiry and confirm it round-trips.
1105+
expDocID := docID + "_exp"
1106+
expiry := uint32(time.Now().Add(1 * time.Hour).Unix())
1107+
require.NoError(t, col.Set(ctx, expDocID, expiry, nil, []byte(`{"foo": 2}`)))
1108+
1109+
xattrs, _, err = col.GetXattrs(ctx, expDocID, []string{xattrKey})
1110+
require.NoError(t, err)
1111+
require.Contains(t, xattrs, xattrKey)
1112+
require.NoError(t, json.Unmarshal(xattrs[xattrKey], &fetchedExpiry))
1113+
require.Equal(t, expiry, fetchedExpiry)
1114+
})
10911115
}
10921116

10931117
func assertRevSeqNo(t *testing.T, col *Collection, docID string, expectedRevSeqNo string) {

0 commit comments

Comments
 (0)