2023-02-09 12:16:36 +01:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"forge.cadoles.com/arcad/edge/pkg/storage/filter"
|
|
|
|
"github.com/oklog/ulid/v2"
|
|
|
|
)
|
|
|
|
|
2024-01-11 19:30:30 +01:00
|
|
|
var (
|
|
|
|
ErrDocumentNotFound = errors.New("document not found")
|
|
|
|
ErrDocumentRevisionConflict = errors.New("document revision conflict")
|
|
|
|
)
|
2023-02-09 12:16:36 +01:00
|
|
|
|
|
|
|
type DocumentID string
|
|
|
|
|
|
|
|
const (
|
|
|
|
DocumentAttrID = "_id"
|
2024-01-11 19:30:30 +01:00
|
|
|
DocumentAttrRevision = "_revision"
|
2023-02-09 12:16:36 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:26:12 +01:00
|
|
|
strID, ok := rawID.(string)
|
2023-02-09 12:16:36 +01:00
|
|
|
if ok {
|
2023-02-17 22:26:12 +01:00
|
|
|
return DocumentID(strID), true
|
2023-02-09 12:16:36 +01:00
|
|
|
}
|
|
|
|
|
2023-02-17 22:26:12 +01:00
|
|
|
docID, ok := rawID.(DocumentID)
|
|
|
|
if ok {
|
|
|
|
return docID, true
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", false
|
2023-02-09 12:16:36 +01:00
|
|
|
}
|
|
|
|
|
2024-01-11 19:30:30 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-09 12:16:36 +01:00
|
|
|
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)
|
2023-02-17 22:26:12 +01:00
|
|
|
if !ok {
|
2023-02-09 12:16:36 +01:00
|
|
|
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
|
|
|
|
}
|