1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00

Change space service methods and change list storage

This commit is contained in:
mcrakhman 2022-10-17 12:40:55 +02:00 committed by Mikhail Iudin
parent 3752fde5e1
commit b07b50a042
No known key found for this signature in database
GPG key ID: FAAAA8BAABDFF1C0
18 changed files with 145 additions and 46 deletions

View file

@ -1,7 +1,9 @@
package api
type Controller interface {
CreateDerivedSpace() (id string, err error)
// DeriveSpace derives the space from current account
DeriveSpace() (id string, err error)
// CreateSpace creates new space with random data
CreateSpace() (id string, err error)
GetAllSpacesIds() (ids []string, err error)
// LoadSpace asks node to load a particular space

View file

@ -7,7 +7,6 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache"
"time"
)
@ -40,7 +39,7 @@ func (c *treeCache) Close(ctx context.Context) (err error) {
}
func (c *treeCache) Init(a *app.App) (err error) {
c.clientService = a.MustComponent(nodespace.CName).(nodespace.Service)
c.clientService = a.MustComponent(clientspace.CName).(clientspace.Service)
c.cache = ocache.New(
func(ctx context.Context, id string) (value ocache.Object, err error) {
spaceId := ctx.Value(spaceKey).(string)

View file

@ -23,6 +23,8 @@ func New() Service {
type Service interface {
GetSpace(ctx context.Context, id string) (commonspace.Space, error)
CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (commonspace.Space, error)
DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (commonspace.Space, error)
app.ComponentRunnable
}
@ -61,6 +63,32 @@ func (s *service) Run(ctx context.Context) (err error) {
return
}
func (s *service) CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (space commonspace.Space, err error) {
id, err := s.commonSpace.CreateSpace(ctx, payload)
if err != nil {
return
}
obj, err := s.commonSpace.GetSpace(ctx, id)
if err != nil {
return
}
return obj.(commonspace.Space), nil
}
func (s *service) DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (space commonspace.Space, err error) {
id, err := s.commonSpace.DeriveSpace(ctx, payload)
if err != nil {
return
}
obj, err := s.commonSpace.GetSpace(ctx, id)
if err != nil {
return
}
return obj.(commonspace.Space), nil
}
func (s *service) GetSpace(ctx context.Context, id string) (commonspace.Space, error) {
v, err := s.spaceCache.Get(ctx, id)
if err != nil {

View file

@ -0,0 +1,13 @@
package document
import "github.com/anytypeio/go-anytype-infrastructure-experiments/app"
type Service interface {
app.Component
CreateDocument(spaceId string) (id string, err error)
GetAllDocumentIds(spaceId string) (ids []string, err error)
AddText(documentId, text string) (err error)
DumpDocumentTree(documentId string) (err error)
}
const CName = "client.document"

View file

@ -1,26 +1,23 @@
package badgerprovider
package storage
import (
"errors"
"github.com/dgraph-io/badger/v3"
)
var ErrIncorrectKey = errors.New("the key is incorrect")
func Has(db *badger.DB, key []byte) bool {
func hasDB(db *badger.DB, key []byte) bool {
return db.View(func(txn *badger.Txn) error {
_, err := txn.Get(key)
return err
}) == nil
}
func Put(db *badger.DB, key, value []byte) (err error) {
func putDB(db *badger.DB, key, value []byte) (err error) {
return db.Update(func(txn *badger.Txn) error {
return txn.Set(key, value)
})
}
func Get(db *badger.DB, key []byte) (value []byte, err error) {
func getDB(db *badger.DB, key []byte) (value []byte, err error) {
err = db.View(func(txn *badger.Txn) error {
item, err := txn.Get(key)
if err != nil {
@ -35,7 +32,7 @@ func Get(db *badger.DB, key []byte) (value []byte, err error) {
return
}
func GetAndCopy(txn *badger.Txn, key []byte) (value []byte, err error) {
func getTxn(txn *badger.Txn, key []byte) (value []byte, err error) {
item, err := txn.Get(key)
if err != nil {
return

View file

@ -3,7 +3,6 @@ package storage
import (
"context"
"errors"
provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
"github.com/dgraph-io/badger/v3"
@ -20,13 +19,13 @@ type listStorage struct {
func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage.ListStorage, err error) {
keys := newACLKeys(spaceId)
rootId, err := provider.GetAndCopy(txn, keys.RootIdKey())
rootId, err := getTxn(txn, keys.RootIdKey())
if err != nil {
return
}
stringId := string(rootId)
value, err := provider.GetAndCopy(txn, keys.RawRecordKey(stringId))
value, err := getTxn(txn, keys.RawRecordKey(stringId))
if err != nil {
return
}
@ -47,7 +46,7 @@ func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage.
func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) {
keys := newACLKeys(spaceId)
_, err = provider.GetAndCopy(txn, keys.RootIdKey())
_, err = getTxn(txn, keys.RootIdKey())
if err != badger.ErrKeyNotFound {
if err == nil {
return newListStorage(spaceId, db, txn)
@ -87,7 +86,7 @@ func (l *listStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) {
}
func (l *listStorage) Head() (head string, err error) {
bytes, err := provider.Get(l.db, l.keys.HeadIdKey())
bytes, err := getDB(l.db, l.keys.HeadIdKey())
if err != nil {
return
}
@ -96,7 +95,7 @@ func (l *listStorage) Head() (head string, err error) {
}
func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) {
res, err := provider.Get(l.db, l.keys.RawRecordKey(id))
res, err := getDB(l.db, l.keys.RawRecordKey(id))
if err != nil {
if err == badger.ErrKeyNotFound {
err = storage.ErrUnknownRecord
@ -111,6 +110,10 @@ func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclreco
return
}
func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error {
return provider.Put(l.db, []byte(rec.Id), rec.Payload)
func (l *listStorage) SetHead(headId string) (err error) {
return putDB(l.db, l.keys.HeadIdKey(), []byte(headId))
}
func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error {
return putDB(l.db, l.keys.RawRecordKey(rec.Id), rec.Payload)
}

View file

@ -1,7 +1,6 @@
package storage
import (
provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
@ -21,7 +20,7 @@ type spaceStorage struct {
func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.SpaceStorage, err error) {
keys := newSpaceKeys(spaceId)
err = objDb.View(func(txn *badger.Txn) error {
header, err := provider.GetAndCopy(txn, keys.HeaderKey())
header, err := getTxn(txn, keys.HeaderKey())
if err != nil {
return err
}
@ -51,7 +50,7 @@ func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.Space
func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) {
keys := newSpaceKeys(payload.SpaceHeaderWithId.Id)
if provider.Has(db, keys.HeaderKey()) {
if hasDB(db, keys.HeaderKey()) {
err = spacesyncproto.ErrSpaceExists
return
}
@ -78,6 +77,10 @@ func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePa
return
}
func (s *spaceStorage) ID() (string, error) {
return s.spaceId, nil
}
func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) {
return newTreeStorage(s.objDb, s.spaceId, id)
}

View file

@ -2,7 +2,6 @@ package storage
import (
"context"
provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
"github.com/dgraph-io/badger/v3"
@ -23,7 +22,7 @@ func newTreeStorage(db *badger.DB, spaceId, treeId string) (ts storage.TreeStora
return err
}
root, err := provider.GetAndCopy(txn, keys.RawChangeKey(treeId))
root, err := getTxn(txn, keys.RawChangeKey(treeId))
if err != nil {
return err
}
@ -46,7 +45,7 @@ func newTreeStorage(db *badger.DB, spaceId, treeId string) (ts storage.TreeStora
func createTreeStorage(db *badger.DB, spaceId string, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) {
keys := newTreeKeys(spaceId, payload.TreeId)
if provider.Has(db, keys.RootIdKey()) {
if hasDB(db, keys.RootIdKey()) {
err = storage.ErrTreeExists
return
}
@ -95,7 +94,7 @@ func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err erro
}
func (t *treeStorage) Heads() (heads []string, err error) {
headsBytes, err := provider.Get(t.db, t.keys.HeadsKey())
headsBytes, err := getDB(t.db, t.keys.HeadsKey())
if err != nil {
if err == badger.ErrKeyNotFound {
err = storage.ErrUnknownTreeId
@ -108,15 +107,15 @@ func (t *treeStorage) Heads() (heads []string, err error) {
func (t *treeStorage) SetHeads(heads []string) (err error) {
payload := storage.CreateHeadsPayload(heads)
return provider.Put(t.db, t.keys.HeadsKey(), payload)
return putDB(t.db, t.keys.HeadsKey(), payload)
}
func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) {
return provider.Put(t.db, t.keys.RawChangeKey(change.Id), change.RawChange)
return putDB(t.db, t.keys.RawChangeKey(change.Id), change.RawChange)
}
func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) {
res, err := provider.Get(t.db, t.keys.RawChangeKey(id))
res, err := getDB(t.db, t.keys.RawChangeKey(id))
if err != nil {
if err == badger.ErrKeyNotFound {
err = storage.ErrUnknownTreeId
@ -132,5 +131,5 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha
}
func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) {
return provider.Has(t.db, t.keys.RawChangeKey(id)), nil
return hasDB(t.db, t.keys.RawChangeKey(id)), nil
}

View file

@ -22,8 +22,8 @@ func New() Service {
}
type Service interface {
DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (Space, error)
CreateSpace(ctx context.Context, payload SpaceCreatePayload) (Space, error)
DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (string, error)
CreateSpace(ctx context.Context, payload SpaceCreatePayload) (string, error)
GetSpace(ctx context.Context, id string) (sp Space, err error)
app.Component
}
@ -51,32 +51,32 @@ func (s *service) Name() (name string) {
func (s *service) CreateSpace(
ctx context.Context,
payload SpaceCreatePayload) (sp Space, err error) {
payload SpaceCreatePayload) (id string, err error) {
storageCreate, err := storagePayloadForSpaceCreate(payload)
if err != nil {
return
}
_, err = s.storageProvider.CreateSpaceStorage(storageCreate)
store, err := s.storageProvider.CreateSpaceStorage(storageCreate)
if err != nil {
return
}
return s.GetSpace(ctx, storageCreate.SpaceHeaderWithId.GetId())
return store.ID()
}
func (s *service) DeriveSpace(
ctx context.Context,
payload SpaceDerivePayload) (sp Space, err error) {
payload SpaceDerivePayload) (id string, err error) {
storageCreate, err := storagePayloadForSpaceDerive(payload)
if err != nil {
return
}
_, err = s.storageProvider.CreateSpaceStorage(storageCreate)
store, err := s.storageProvider.CreateSpaceStorage(storageCreate)
if err != nil {
return
}
return s.GetSpace(ctx, storageCreate.SpaceHeaderWithId.GetId())
return store.ID()
}
func (s *service) GetSpace(ctx context.Context, id string) (Space, error) {

View file

@ -19,10 +19,15 @@ import (
)
type SpaceCreatePayload struct {
SigningKey signingkey.PrivKey
EncryptionKey encryptionkey.PrivKey
SpaceType string
ReadKey []byte
// SigningKey is the signing key of the owner
SigningKey signingkey.PrivKey
// EncryptionKey is the encryption key of the owner
EncryptionKey encryptionkey.PrivKey
// SpaceType is an arbitrary string
SpaceType string
// ReadKey is a first symmetric encryption key for a space
ReadKey []byte
// ReplicationKey is a key which is to be used to determine the node where the space should be held
ReplicationKey uint64
}

View file

@ -162,6 +162,21 @@ func (mr *MockSpaceStorageMockRecorder) CreateTreeStorage(arg0 interface{}) *gom
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTreeStorage", reflect.TypeOf((*MockSpaceStorage)(nil).CreateTreeStorage), arg0)
}
// ID mocks base method.
func (m *MockSpaceStorage) ID() (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ID")
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ID indicates an expected call of ID.
func (mr *MockSpaceStorageMockRecorder) ID() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockSpaceStorage)(nil).ID))
}
// SpaceHeader mocks base method.
func (m *MockSpaceStorage) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) {
m.ctrl.T.Helper()

View file

@ -15,6 +15,7 @@ var ErrSpaceStorageExists = errors.New("space storage exists")
var ErrSpaceStorageMissing = errors.New("space storage missing")
type SpaceStorage interface {
storage.Storage
storage.Provider
ACLStorage() (storage.ListStorage, error)
SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error)

View file

@ -120,6 +120,10 @@ func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclreco
return
}
func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error {
return l.db.Put([]byte(rec.Id), rec.Payload)
func (l *listStorage) SetHead(headId string) (err error) {
return l.db.Put(l.keys.HeadIdKey(), []byte(headId))
}
func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error {
return l.db.Put(l.keys.RawRecordKey(rec.Id), rec.Payload)
}

View file

@ -15,6 +15,7 @@ var defPogrebOptions = &pogreb.Options{
}
type spaceStorage struct {
spaceId string
objDb *pogreb.DB
keys spaceKeys
aclStorage storage.ListStorage
@ -60,8 +61,9 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS
}
store = &spaceStorage{
objDb: objDb,
keys: keys,
spaceId: spaceId,
objDb: objDb,
keys: keys,
header: &spacesyncproto.RawSpaceHeaderWithId{
RawHeader: header,
Id: spaceId,
@ -110,6 +112,7 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate
}
store = &spaceStorage{
spaceId: payload.SpaceHeaderWithId.Id,
objDb: db,
keys: keys,
aclStorage: aclStorage,
@ -118,6 +121,10 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate
return
}
func (s *spaceStorage) ID() (string, error) {
return s.spaceId, nil
}
func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) {
return newTreeStorage(s.objDb, id)
}

View file

@ -31,6 +31,10 @@ func (i *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, err
return i.records[0], nil
}
func (i *inMemoryACLListStorage) SetHead(headId string) error {
panic("implement me")
}
func (i *inMemoryACLListStorage) Head() (string, error) {
i.RLock()
defer i.RUnlock()

View file

@ -15,6 +15,7 @@ type ListStorage interface {
Storage
Root() (*aclrecordproto.RawACLRecordWithId, error)
Head() (string, error)
SetHead(headId string) error
GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error)
AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error

View file

@ -110,6 +110,20 @@ func (mr *MockListStorageMockRecorder) Root() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockListStorage)(nil).Root))
}
// SetHead mocks base method.
func (m *MockListStorage) SetHead(arg0 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetHead", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// SetHead indicates an expected call of SetHead.
func (mr *MockListStorageMockRecorder) SetHead(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHead", reflect.TypeOf((*MockListStorage)(nil).SetHead), arg0)
}
// MockTreeStorage is a mock of TreeStorage interface.
type MockTreeStorage struct {
ctrl *gomock.Controller

View file

@ -97,6 +97,10 @@ func (t *ACLListStorageBuilder) Head() (string, error) {
return t.rawRoot.Id, nil
}
func (t *ACLListStorageBuilder) SetHead(headId string) error {
panic("SetHead is not implemented")
}
func (t *ACLListStorageBuilder) Root() (*aclrecordproto.RawACLRecordWithId, error) {
return t.rawRoot, nil
}