edge/pkg/storage/document_store.go

93 lines
1.8 KiB
Go

package storage
import (
"context"
"errors"
"time"
"forge.cadoles.com/arcad/edge/pkg/storage/filter"
"github.com/oklog/ulid/v2"
)
var (
ErrDocumentNotFound = errors.New("document not found")
ErrDocumentRevisionConflict = errors.New("document revision conflict")
)
type DocumentID string
const (
DocumentAttrID = "_id"
DocumentAttrRevision = "_revision"
DocumentAttrCreatedAt = "_createdAt"
DocumentAttrUpdatedAt = "_updatedAt"
)
func NewDocumentID() DocumentID {
return DocumentID(ulid.Make().String())
}
type Document map[string]interface{}
func (d Document) ID() (DocumentID, bool) {
rawID, exists := d[DocumentAttrID]
if !exists {
return "", false
}
strID, ok := rawID.(string)
if ok {
return DocumentID(strID), true
}
docID, ok := rawID.(DocumentID)
if ok {
return docID, true
}
return "", false
}
func (d Document) Revision() (int, bool) {
rawRevision, exists := d[DocumentAttrRevision]
if !exists {
return 0, false
}
revision, ok := rawRevision.(int)
if ok {
return revision, true
}
return 0, false
}
func (d Document) CreatedAt() (time.Time, bool) {
return d.timeAttr(DocumentAttrCreatedAt)
}
func (d Document) UpdatedAt() (time.Time, bool) {
return d.timeAttr(DocumentAttrUpdatedAt)
}
func (d Document) timeAttr(attr string) (time.Time, bool) {
rawTime, exists := d[attr]
if !exists {
return time.Time{}, false
}
t, ok := rawTime.(time.Time)
if !ok {
return time.Time{}, false
}
return t, true
}
type DocumentStore interface {
Get(ctx context.Context, collection string, id DocumentID) (Document, error)
Query(ctx context.Context, collection string, filter *filter.Filter, funcs ...QueryOptionFunc) ([]Document, error)
Upsert(ctx context.Context, collection string, document Document) (Document, error)
Delete(ctx context.Context, collection string, id DocumentID) error
}