From 98237036644bd53005cb21ddbc9630951c2696a9 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Tue, 26 Sep 2023 10:55:27 +0200 Subject: [PATCH 01/22] GO-1612: add tests for collections Search Signed-off-by: AnastasiaShemyakinskaya --- .mockery.yaml | 3 + .../mock_CollectionService.go | 130 ++++++ core/subscription/service.go | 2 +- core/subscription/service_test.go | 377 +++++++++++++++++- 4 files changed, 495 insertions(+), 17 deletions(-) create mode 100644 core/subscription/mock_subscription/mock_CollectionService.go diff --git a/.mockery.yaml b/.mockery.yaml index a308d5e0f..8c50d8fec 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -19,3 +19,6 @@ packages: github.com/anyproto/anytype-heart/core/block/restriction: interfaces: Service: + github.com/anyproto/anytype-heart/core/subscription: + interfaces: + CollectionService: diff --git a/core/subscription/mock_subscription/mock_CollectionService.go b/core/subscription/mock_subscription/mock_CollectionService.go new file mode 100644 index 000000000..67e368aef --- /dev/null +++ b/core/subscription/mock_subscription/mock_CollectionService.go @@ -0,0 +1,130 @@ +// Code generated by mockery v2.30.1. DO NOT EDIT. + +package mock_subscription + +import mock "github.com/stretchr/testify/mock" + +// MockCollectionService is an autogenerated mock type for the CollectionService type +type MockCollectionService struct { + mock.Mock +} + +type MockCollectionService_Expecter struct { + mock *mock.Mock +} + +func (_m *MockCollectionService) EXPECT() *MockCollectionService_Expecter { + return &MockCollectionService_Expecter{mock: &_m.Mock} +} + +// SubscribeForCollection provides a mock function with given fields: collectionID, subscriptionID +func (_m *MockCollectionService) SubscribeForCollection(collectionID string, subscriptionID string) ([]string, <-chan []string, error) { + ret := _m.Called(collectionID, subscriptionID) + + var r0 []string + var r1 <-chan []string + var r2 error + if rf, ok := ret.Get(0).(func(string, string) ([]string, <-chan []string, error)); ok { + return rf(collectionID, subscriptionID) + } + if rf, ok := ret.Get(0).(func(string, string) []string); ok { + r0 = rf(collectionID, subscriptionID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(string, string) <-chan []string); ok { + r1 = rf(collectionID, subscriptionID) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(<-chan []string) + } + } + + if rf, ok := ret.Get(2).(func(string, string) error); ok { + r2 = rf(collectionID, subscriptionID) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockCollectionService_SubscribeForCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeForCollection' +type MockCollectionService_SubscribeForCollection_Call struct { + *mock.Call +} + +// SubscribeForCollection is a helper method to define mock.On call +// - collectionID string +// - subscriptionID string +func (_e *MockCollectionService_Expecter) SubscribeForCollection(collectionID interface{}, subscriptionID interface{}) *MockCollectionService_SubscribeForCollection_Call { + return &MockCollectionService_SubscribeForCollection_Call{Call: _e.mock.On("SubscribeForCollection", collectionID, subscriptionID)} +} + +func (_c *MockCollectionService_SubscribeForCollection_Call) Run(run func(collectionID string, subscriptionID string)) *MockCollectionService_SubscribeForCollection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *MockCollectionService_SubscribeForCollection_Call) Return(_a0 []string, _a1 <-chan []string, _a2 error) *MockCollectionService_SubscribeForCollection_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockCollectionService_SubscribeForCollection_Call) RunAndReturn(run func(string, string) ([]string, <-chan []string, error)) *MockCollectionService_SubscribeForCollection_Call { + _c.Call.Return(run) + return _c +} + +// UnsubscribeFromCollection provides a mock function with given fields: collectionID, subscriptionID +func (_m *MockCollectionService) UnsubscribeFromCollection(collectionID string, subscriptionID string) { + _m.Called(collectionID, subscriptionID) +} + +// MockCollectionService_UnsubscribeFromCollection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnsubscribeFromCollection' +type MockCollectionService_UnsubscribeFromCollection_Call struct { + *mock.Call +} + +// UnsubscribeFromCollection is a helper method to define mock.On call +// - collectionID string +// - subscriptionID string +func (_e *MockCollectionService_Expecter) UnsubscribeFromCollection(collectionID interface{}, subscriptionID interface{}) *MockCollectionService_UnsubscribeFromCollection_Call { + return &MockCollectionService_UnsubscribeFromCollection_Call{Call: _e.mock.On("UnsubscribeFromCollection", collectionID, subscriptionID)} +} + +func (_c *MockCollectionService_UnsubscribeFromCollection_Call) Run(run func(collectionID string, subscriptionID string)) *MockCollectionService_UnsubscribeFromCollection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *MockCollectionService_UnsubscribeFromCollection_Call) Return() *MockCollectionService_UnsubscribeFromCollection_Call { + _c.Call.Return() + return _c +} + +func (_c *MockCollectionService_UnsubscribeFromCollection_Call) RunAndReturn(run func(string, string)) *MockCollectionService_UnsubscribeFromCollection_Call { + _c.Call.Return(run) + return _c +} + +// NewMockCollectionService creates a new instance of MockCollectionService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockCollectionService(t interface { + mock.TestingT + Cleanup(func()) +}) *MockCollectionService { + mock := &MockCollectionService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/subscription/service.go b/core/subscription/service.go index 8c2e81e5b..3900589e7 100644 --- a/core/subscription/service.go +++ b/core/subscription/service.go @@ -215,7 +215,7 @@ func (s *service) subscribeForCollection(req pb.RpcObjectSearchSubscribeRequest, var depRecords, subRecords []*types.Struct subRecords = sub.getActiveRecords() - if sub.sortedSub.depSub != nil { + if sub.sortedSub.depSub != nil && !sub.sortedSub.disableDep { depRecords = sub.sortedSub.depSub.getActiveRecords() } diff --git a/core/subscription/service_test.go b/core/subscription/service_test.go index d2433b8b5..202e35e57 100644 --- a/core/subscription/service_test.go +++ b/core/subscription/service_test.go @@ -2,12 +2,13 @@ package subscription import ( "context" - "testing" - + "fmt" + "github.com/anyproto/anytype-heart/core/subscription/mock_subscription" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" + "testing" "github.com/anyproto/any-sync/app" "github.com/anyproto/anytype-heart/app/testapp" @@ -303,17 +304,358 @@ func TestService_Search(t *testing.T) { assert.NotEmpty(t, fx.events[0].Messages[3].GetSubscriptionCounters()) assert.NotEmpty(t, fx.events[0].Messages[0].GetObjectDetailsSet().Details) }) + + t.Run("collection: error getting collections entries - no records in response", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return(nil, nil, fmt.Errorf("error")) + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: "subId", + CollectionId: collectionID, + }) + require.Error(t, err) + assert.Nil(t, resp) + }) + + t.Run("collection: collection is empty - no records in response", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return(nil, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + CollectionId: collectionID, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 0) + assert.Len(t, resp.Dependencies, 0) + }) + + t.Run("collection: collection has 2 objects - return 2 objects in response", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2"}, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + + fx.store.EXPECT().QueryByID([]string{"1", "2"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("1"), + "name": pbtypes.String("1"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("2"), + "name": pbtypes.String("2"), + }}}, + }, nil) + + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + Key: bundle.RelationKeyName.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + Key: bundle.RelationKeyId.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, + CollectionId: collectionID, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 2) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String())) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String())) + assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], bundle.RelationKeyName.String())) + assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], bundle.RelationKeyId.String())) + }) + + t.Run("collection: collection has 3 objects, 1 is filtered - return 2 objects in response", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2", "3"}, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + + fx.store.EXPECT().QueryByID([]string{"1", "2", "3"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("1"), + "name": pbtypes.String("1"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("2"), + "name": pbtypes.String("2"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("3"), + "name": pbtypes.String("3"), + }}}, + }, nil) + + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + Key: bundle.RelationKeyName.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + Key: bundle.RelationKeyId.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, + CollectionId: collectionID, + Filters: []*model.BlockContentDataviewFilter{ + { + Id: "1", + RelationKey: bundle.RelationKeyName.String(), + Condition: model.BlockContentDataviewFilter_NotEqual, + Value: pbtypes.String("3"), + }, + }, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 2) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String())) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String())) + assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], bundle.RelationKeyName.String())) + assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], bundle.RelationKeyId.String())) + }) + t.Run("collection: collection has 3 objects, offset = 2 - return 1 object after offset", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2", "3"}, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + + fx.store.EXPECT().QueryByID([]string{"1", "2", "3"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("1"), + "name": pbtypes.String("1"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("2"), + "name": pbtypes.String("2"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("3"), + "name": pbtypes.String("3"), + }}}, + }, nil) + + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + Key: bundle.RelationKeyName.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + Key: bundle.RelationKeyId.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, + CollectionId: collectionID, + Offset: 2, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 1) + assert.Equal(t, "3", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String())) + assert.Equal(t, "3", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String())) + }) + t.Run("collection: collection has object with dependency - return objects without dependency", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + testRelationKey := "link_to_object" + + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1"}, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + + fx.store.EXPECT().QueryByID([]string{"1"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("1"), + "name": pbtypes.String("1"), + testRelationKey: pbtypes.String("2"), + }}}, + }, nil) + + // dependency + fx.store.EXPECT().QueryByID([]string{"2"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("2"), + "name": pbtypes.String("2"), + }}}, + }, nil) + + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + Key: bundle.RelationKeyName.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + + fx.store.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ + Key: testRelationKey, + Format: model.RelationFormat_object, + }, nil).AnyTimes() + + s := fx.Service.(*service) + s.ds = newDependencyService(s) + + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String(), testRelationKey}, + CollectionId: collectionID, + NoDepSubscription: true, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 1) + assert.Len(t, resp.Dependencies, 0) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String())) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String())) + }) + t.Run("collection: collection has object with dependency - return objects with dependency", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + testRelationKey := "link_to_object" + + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1"}, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + + fx.store.EXPECT().QueryByID([]string{"1"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("1"), + "name": pbtypes.String("1"), + testRelationKey: pbtypes.String("2"), + }}}, + }, nil) + + // dependency + fx.store.EXPECT().QueryByID([]string{"2"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("2"), + "name": pbtypes.String("2"), + }}}, + }, nil) + + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + Key: bundle.RelationKeyName.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + + fx.store.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ + Key: testRelationKey, + Format: model.RelationFormat_object, + }, nil).AnyTimes() + + s := fx.Service.(*service) + s.ds = newDependencyService(s) + + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String(), testRelationKey}, + CollectionId: collectionID, + NoDepSubscription: false, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 1) + assert.Len(t, resp.Dependencies, 1) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String())) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String())) + assert.Equal(t, "2", pbtypes.GetString(resp.Dependencies[0], bundle.RelationKeyName.String())) + assert.Equal(t, "2", pbtypes.GetString(resp.Dependencies[0], bundle.RelationKeyId.String())) + }) + t.Run("collection: collection has 3 objects, but limit = 2 - return 2 objects in response", func(t *testing.T) { + fx := newFixture(t) + defer fx.a.Close(context.Background()) + defer fx.ctrl.Finish() + + collectionID := "id" + subscriptionID := "subId" + + fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2", "3"}, nil, nil) + fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() + + fx.store.EXPECT().QueryByID([]string{"1", "2", "3"}).Return([]database.Record{ + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("1"), + "name": pbtypes.String("1"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("2"), + "name": pbtypes.String("2"), + }}}, + {Details: &types.Struct{Fields: map[string]*types.Value{ + "id": pbtypes.String("3"), + "name": pbtypes.String("3"), + }}}, + }, nil) + + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + Key: bundle.RelationKeyName.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + Key: bundle.RelationKeyId.String(), + Format: model.RelationFormat_shorttext, + }, nil).AnyTimes() + + var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ + SubId: subscriptionID, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, + CollectionId: collectionID, + Limit: 1, + }) + + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Len(t, resp.Records, 1) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String())) + assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String())) + }) } type collectionServiceMock struct { - updateCh chan []string -} - -func (c *collectionServiceMock) SubscribeForCollection(collectionID string, subscriptionID string) ([]string, <-chan []string, error) { - return nil, c.updateCh, nil -} - -func (c *collectionServiceMock) UnsubscribeFromCollection(collectionID string, subscriptionID string) { + *mock_subscription.MockCollectionService } func (c *collectionServiceMock) Name() string { @@ -336,9 +678,11 @@ func newFixture(t *testing.T) *fixture { fx.sender = &testapp.EventSender{F: func(e *pb.Event) { fx.events = append(fx.events, e) }} + collectionService := mock_subscription.NewMockCollectionService(t) + fx.collectionService = &collectionServiceMock{MockCollectionService: collectionService} a.Register(fx.Service) a.Register(fx.sender) - a.Register(&collectionServiceMock{updateCh: make(chan []string, 1)}) + a.Register(fx.collectionService) sbtProvider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) sbtProvider.EXPECT().Name().Return("sbtProvider") @@ -353,9 +697,10 @@ func newFixture(t *testing.T) *fixture { type fixture struct { Service - a *testapp.TestApp - ctrl *gomock.Controller - store *testMock.MockObjectStore - sender *testapp.EventSender - events []*pb.Event + a *testapp.TestApp + ctrl *gomock.Controller + store *testMock.MockObjectStore + sender *testapp.EventSender + events []*pb.Event + collectionService *collectionServiceMock } From 182bed57a0e9e3891eba4beb6edb80b1e4b602b9 Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 28 Sep 2023 12:30:02 +0500 Subject: [PATCH 02/22] GO-2130: Optimized way to upload files --- core/filestorage/filesync/upload.go | 155 +++++++++++++--------------- go.mod | 2 +- go.sum | 2 + 3 files changed, 73 insertions(+), 86 deletions(-) diff --git a/core/filestorage/filesync/upload.go b/core/filestorage/filesync/upload.go index 9dfe191ee..96bee8847 100644 --- a/core/filestorage/filesync/upload.go +++ b/core/filestorage/filesync/upload.go @@ -10,7 +10,6 @@ import ( "github.com/anyproto/any-sync/commonfile/fileproto" "github.com/anyproto/any-sync/commonfile/fileproto/fileprotoerr" "github.com/anyproto/any-sync/commonspace/syncstatus" - "github.com/cheggaaa/mb/v3" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -130,7 +129,6 @@ func (f *fileSync) tryToUpload() (string, error) { } return fileId, err } - log.Warn("done upload", zap.String("fileID", fileId)) if f.onUpload != nil { err := f.onUpload(spaceId, fileId) if err != nil { @@ -153,91 +151,42 @@ func isLimitReachedErr(err error) bool { return errors.Is(err, errReachedLimit) || strings.Contains(err.Error(), fileprotoerr.ErrSpaceLimitExceeded.Error()) } -func (f *fileSync) uploadFile(ctx context.Context, spaceId, fileId string) (err error) { +func (f *fileSync) uploadFile(ctx context.Context, spaceId, fileId string) error { log.Debug("uploading file", zap.String("fileId", fileId)) - var ( - batcher = mb.New[blocks.Block](10) - dagErr = make(chan error, 1) - bs []blocks.Block - ) - defer func() { - _ = batcher.Close() - }() - - blocksToUpload, err := f.prepareToUpload(ctx, spaceId, fileId) + fileSize, err := f.calculateFileSize(ctx, fileId) if err != nil { - return err + return fmt.Errorf("calculate file size: %w", err) } - - if len(blocksToUpload) == 0 { - return nil - } - - log.Info("start uploading file", zap.String("fileID", fileId), zap.Int("blocksCount", len(blocksToUpload))) - - go func() { - defer func() { - _ = batcher.Close() - }() - proc := func() error { - for _, b := range blocksToUpload { - if addErr := batcher.Add(ctx, b); addErr != nil { - return addErr - } - } - return nil - } - dagErr <- proc() - }() - - for { - if bs, err = batcher.Wait(ctx); err != nil { - if err == mb.ErrClosed { - err = nil - break - } else { - return err - } - } - - if err = f.rpcStore.AddToFile(ctx, spaceId, fileId, bs); err != nil { - return err - } - } - return <-dagErr -} - -func (f *fileSync) prepareToUpload(ctx context.Context, spaceId string, fileId string) ([]blocks.Block, error) { - fileBlocks, err := f.collectFileBlocks(ctx, fileId) - if err != nil { - return nil, fmt.Errorf("collect file blocks: %w", err) - } - - bytesToUpload, blocksToUpload, err := f.selectBlocksToUploadAndBindExisting(ctx, spaceId, fileId, fileBlocks) - if err != nil { - return nil, fmt.Errorf("select blocks to upload: %w", err) - } - - if len(blocksToUpload) > 0 { - log.Warn("collecting blocks to upload", - zap.String("fileID", fileId), - zap.Int("blocksToUpload", len(blocksToUpload)), - zap.Int("totalBlocks", len(fileBlocks)), - ) - } - stat, err := f.getAndUpdateSpaceStat(ctx, spaceId) if err != nil { - return nil, fmt.Errorf("get space stat: %w", err) + return fmt.Errorf("get space stat: %w", err) } bytesLeft := stat.BytesLimit - stat.BytesUsage - if len(blocksToUpload) > 0 && bytesToUpload > bytesLeft { - return nil, errReachedLimit + if fileSize > bytesLeft { + return errReachedLimit } - return blocksToUpload, nil + var totalBytesUploaded int + err = f.walkFileBlocks(ctx, fileId, func(fileBlocks []blocks.Block) error { + bytesToUpload, blocksToUpload, err := f.selectBlocksToUploadAndBindExisting(ctx, spaceId, fileId, fileBlocks) + if err != nil { + return fmt.Errorf("select blocks to upload: %w", err) + } + if err = f.rpcStore.AddToFile(ctx, spaceId, fileId, blocksToUpload); err != nil { + return err + } + totalBytesUploaded += bytesToUpload + return nil + }) + if err != nil { + return fmt.Errorf("walk file blocks: %w", err) + } + + log.Warn("done upload", zap.String("fileID", fileId), zap.Int("estimatedSize", fileSize), zap.Int("bytesUploaded", totalBytesUploaded)) + + return nil } func (f *fileSync) hasFileInStore(fileID string) (bool, error) { @@ -323,29 +272,65 @@ func (f *fileSync) selectBlocksToUploadAndBindExisting(ctx context.Context, spac return bytesToUpload, blocksToUpload, nil } -func (f *fileSync) collectFileBlocks(ctx context.Context, fileId string) (result []blocks.Block, err error) { - fileCid, err := cid.Parse(fileId) +func (f *fileSync) walkDAG(ctx context.Context, fileID string, visit func(node ipld.NavigableNode) error) error { + fileCid, err := cid.Parse(fileID) if err != nil { - return + return fmt.Errorf("parse CID %s: %w", fileID, err) } node, err := f.dagService.Get(ctx, fileCid) if err != nil { - return + return fmt.Errorf("get root node: %w", err) } walker := ipld.NewWalker(ctx, ipld.NewNavigableIPLDNode(node, f.dagService)) - err = walker.Iterate(func(node ipld.NavigableNode) error { + err = walker.Iterate(visit) + if errors.Is(err, ipld.EndOfDag) { + err = nil + } + return err +} + +func (f *fileSync) calculateFileSize(ctx context.Context, fileID string) (int, error) { + var size int + err := f.walkDAG(ctx, fileID, func(node ipld.NavigableNode) error { + raw := node.GetIPLDNode().RawData() + size += len(raw) + return nil + }) + return size, err +} + +const batchSize = 10 + +func (f *fileSync) walkFileBlocks(ctx context.Context, fileId string, proc func(fileBlocks []blocks.Block) error) error { + blocksBuf := make([]blocks.Block, 0, batchSize) + + err := f.walkDAG(ctx, fileId, func(node ipld.NavigableNode) error { b, err := blocks.NewBlockWithCid(node.GetIPLDNode().RawData(), node.GetIPLDNode().Cid()) if err != nil { return err } - result = append(result, b) + blocksBuf = append(blocksBuf, b) + if len(blocksBuf) == batchSize { + err = proc(blocksBuf) + if err != nil { + return fmt.Errorf("process batch: %w", err) + } + blocksBuf = blocksBuf[:0] + } return nil }) - if err == ipld.EndOfDag { - err = nil + if err != nil { + return fmt.Errorf("walk DAG: %w", err) } - return + + if len(blocksBuf) > 0 { + err = proc(blocksBuf) + if err != nil { + return fmt.Errorf("process batch: %w", err) + } + } + return nil } func (f *fileSync) HasUpload(spaceId, fileId string) (ok bool, err error) { diff --git a/go.mod b/go.mod index 260c1e4a1..816b6c8da 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-flatfs v0.5.1 - github.com/ipfs/go-ipld-format v0.5.0 + github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-log v1.0.5 github.com/joho/godotenv v1.5.1 github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e diff --git a/go.sum b/go.sum index d2eee2f4e..bfd838cb2 100644 --- a/go.sum +++ b/go.sum @@ -549,6 +549,8 @@ github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2PO github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= +github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From 5166e61f96fb3a16e3213042d9a2e12b14ea4170 Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 28 Sep 2023 12:56:12 +0500 Subject: [PATCH 03/22] GO-2130: Cache file size --- core/files/files.go | 14 ++++++++++++++ core/files/images.go | 6 ++++++ core/filestorage/filesync/upload.go | 18 +++++++++++++++--- pkg/lib/localstore/filestore/files.go | 13 +++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/core/files/files.go b/core/files/files.go index 9af6edff8..498fe5a99 100644 --- a/core/files/files.go +++ b/core/files/files.go @@ -139,9 +139,23 @@ func (s *service) fileAdd(ctx context.Context, opts AddOptions) (string, *storag return "", nil, err } + err = s.storeFileSize(nodeHash, node) + if err != nil { + return "", nil, fmt.Errorf("store file size: %w", err) + } + return nodeHash, fileInfo, nil } +func (s *service) storeFileSize(hash string, node ipld.Node) error { + // Size method returns the size of the whole tree with root at `node` + size, err := node.Size() + if err != nil { + return fmt.Errorf("fetch node size: %w", err) + } + return s.fileStore.SetFileSize(hash, int(size)) +} + // fileRestoreKeys restores file path=>key map from the IPFS DAG using the keys in the localStore func (s *service) fileRestoreKeys(ctx context.Context, hash string) (map[string]string, error) { links, err := helpers.LinksAtCid(ctx, s.dagService, hash) diff --git a/core/files/images.go b/core/files/images.go index cfd9ddafb..f4b80bdc9 100644 --- a/core/files/images.go +++ b/core/files/images.go @@ -111,5 +111,11 @@ func (s *service) imageAdd(ctx context.Context, opts AddOptions) (string, map[in variantsByWidth[int(v.GetNumberValue())] = f } } + + err = s.storeFileSize(nodeHash, node) + if err != nil { + return "", nil, fmt.Errorf("store file size: %w", err) + } + return nodeHash, variantsByWidth, nil } diff --git a/core/filestorage/filesync/upload.go b/core/filestorage/filesync/upload.go index 96bee8847..38892edf3 100644 --- a/core/filestorage/filesync/upload.go +++ b/core/filestorage/filesync/upload.go @@ -291,13 +291,25 @@ func (f *fileSync) walkDAG(ctx context.Context, fileID string, visit func(node i } func (f *fileSync) calculateFileSize(ctx context.Context, fileID string) (int, error) { - var size int - err := f.walkDAG(ctx, fileID, func(node ipld.NavigableNode) error { + size, err := f.fileStore.GetFileSize(fileID) + if err == nil { + return size, nil + } + + size = 0 + err = f.walkDAG(ctx, fileID, func(node ipld.NavigableNode) error { raw := node.GetIPLDNode().RawData() size += len(raw) return nil }) - return size, err + if err != nil { + return 0, fmt.Errorf("walk DAG: %w", err) + } + err = f.fileStore.SetFileSize(fileID, size) + if err != nil { + log.Error("can't store file size", zap.String("fileID", fileID), zap.Error(err)) + } + return size, nil } const batchSize = 10 diff --git a/pkg/lib/localstore/filestore/files.go b/pkg/lib/localstore/filestore/files.go index 5933814d8..56ac9166d 100644 --- a/pkg/lib/localstore/filestore/files.go +++ b/pkg/lib/localstore/filestore/files.go @@ -28,6 +28,7 @@ var ( filesKeysBase = dsCtx.NewKey("/" + filesPrefix + "/keys") chunksCountBase = dsCtx.NewKey("/" + filesPrefix + "/chunks_count") syncStatusBase = dsCtx.NewKey("/" + filesPrefix + "/sync_status") + fileSizeBase = dsCtx.NewKey("/" + filesPrefix + "/file_size") isImportedBase = dsCtx.NewKey("/" + filesPrefix + "/is_imported") indexMillSourceOpts = localstore.Index{ @@ -104,6 +105,8 @@ type FileStore interface { SetSyncStatus(hash string, syncStatus int) error IsFileImported(hash string) (bool, error) SetIsFileImported(hash string, isImported bool) error + SetFileSize(hash string, size int) error + GetFileSize(hash string) (int, error) } func New() FileStore { @@ -705,6 +708,16 @@ func (m *dsFileStore) SetIsFileImported(hash string, isImported bool) error { return m.setInt(key, raw) } +func (m *dsFileStore) GetFileSize(hash string) (int, error) { + key := fileSizeBase.ChildString(hash) + return m.getInt(key) +} + +func (m *dsFileStore) SetFileSize(hash string, status int) error { + key := fileSizeBase.ChildString(hash) + return m.setInt(key, status) +} + func (ls *dsFileStore) Close(ctx context.Context) (err error) { return nil } From cb0e54bf42e5bfcc086e20c5251cd87783da0db2 Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 28 Sep 2023 13:03:54 +0500 Subject: [PATCH 04/22] GO-2130: Add comment for future --- core/files/images.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/files/images.go b/core/files/images.go index f4b80bdc9..b322d682d 100644 --- a/core/files/images.go +++ b/core/files/images.go @@ -24,6 +24,9 @@ func (s *service) ImageByHash(ctx context.Context, hash string) (Image, error) { return nil, err } + // TODO Can we use FileByHash here? FileByHash contains important syncing logic. Yes, we use FileByHash before ImageByHash + // but it doesn't seem to be clear why we repeat file indexing process here + // check the image files count explicitly because we have a bug when the info can be cached not fully(only for some files) if len(files) < 4 || files[0].MetaHash == "" { // index image files info from ipfs From bb7002e3514e9df49eb7fb715b251e854693457d Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 28 Sep 2023 16:04:24 +0500 Subject: [PATCH 05/22] GO-2130: Fix tests and linter --- .../editor/file/block_service_mock_test.go | 14 ++-- core/block/editor/smartblock/indexer_mock.go | 18 +++-- core/block/import/mock.go | 10 ++- core/filestorage/filesync/filestore_mock.go | 79 +++++++++++++------ core/filestorage/filesync/filesync_test.go | 3 +- .../filesync/mock_filesync/filesync_mock.go | 32 ++++---- core/filestorage/filesync/upload.go | 20 ++--- .../rpcstore/mock_rpcstore/mock_rpcstore.go | 36 +++++---- pkg/lib/core/mock_core/service_mock.go | 16 ++-- space/mock_space/commonspace_space_mock.go | 79 ++++++++++--------- space/mock_space/service_mock.go | 22 +++--- util/testMock/anytype_mock.go | 16 ++-- util/testMock/file_service_mock.go | 50 ++++++------ util/testMock/history_mock.go | 8 +- .../builtintemplate_mock.go | 12 ++- util/testMock/mockCreator/creator_mock.go | 18 +++-- util/testMock/mockDetailsModifier/dm_mock.go | 10 ++- util/testMock/mockKanban/kanban_mock.go | 10 ++- util/testMock/mockRelation/relation_mock.go | 26 +++--- util/testMock/mockSource/source_mock.go | 24 +++--- util/testMock/mockSpace/space_mock.go | 22 +++--- util/testMock/mockStatus/status_mock.go | 18 +++-- util/testMock/objectstore_mock.go | 78 +++++++++--------- util/testMock/sbt_provider_mock.go | 12 ++- 24 files changed, 376 insertions(+), 257 deletions(-) diff --git a/core/block/editor/file/block_service_mock_test.go b/core/block/editor/file/block_service_mock_test.go index 18bb9b554..96004c3d4 100644 --- a/core/block/editor/file/block_service_mock_test.go +++ b/core/block/editor/file/block_service_mock_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/editor/file (interfaces: BlockService) - +// +// Generated by this command: +// +// mockgen -package file_test -destination block_service_mock_test.go github.com/anyproto/anytype-heart/core/block/editor/file BlockService +// // Package file_test is a generated GoMock package. package file_test @@ -49,7 +53,7 @@ func (m *MockBlockService) CreateLinkToTheNewObject(arg0 *session.Context, arg1 } // CreateLinkToTheNewObject indicates an expected call of CreateLinkToTheNewObject. -func (mr *MockBlockServiceMockRecorder) CreateLinkToTheNewObject(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBlockServiceMockRecorder) CreateLinkToTheNewObject(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLinkToTheNewObject", reflect.TypeOf((*MockBlockService)(nil).CreateLinkToTheNewObject), arg0, arg1) } @@ -63,7 +67,7 @@ func (m *MockBlockService) Do(arg0 string, arg1 func(smartblock.SmartBlock) erro } // Do indicates an expected call of Do. -func (mr *MockBlockServiceMockRecorder) Do(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBlockServiceMockRecorder) Do(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Do", reflect.TypeOf((*MockBlockService)(nil).Do), arg0, arg1) } @@ -77,7 +81,7 @@ func (m *MockBlockService) DoFile(arg0 string, arg1 func(file.File) error) error } // DoFile indicates an expected call of DoFile. -func (mr *MockBlockServiceMockRecorder) DoFile(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBlockServiceMockRecorder) DoFile(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DoFile", reflect.TypeOf((*MockBlockService)(nil).DoFile), arg0, arg1) } @@ -91,7 +95,7 @@ func (m *MockBlockService) ProcessAdd(arg0 process.Process) error { } // ProcessAdd indicates an expected call of ProcessAdd. -func (mr *MockBlockServiceMockRecorder) ProcessAdd(arg0 interface{}) *gomock.Call { +func (mr *MockBlockServiceMockRecorder) ProcessAdd(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProcessAdd", reflect.TypeOf((*MockBlockService)(nil).ProcessAdd), arg0) } diff --git a/core/block/editor/smartblock/indexer_mock.go b/core/block/editor/smartblock/indexer_mock.go index 9549bad8e..5c61956d3 100644 --- a/core/block/editor/smartblock/indexer_mock.go +++ b/core/block/editor/smartblock/indexer_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/editor/smartblock (interfaces: Indexer) - +// +// Generated by this command: +// +// mockgen -package smartblock -destination indexer_mock.go github.com/anyproto/anytype-heart/core/block/editor/smartblock Indexer +// // Package smartblock is a generated GoMock package. package smartblock @@ -44,7 +48,7 @@ func (m *MockIndexer) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockIndexerMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockIndexerMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIndexer)(nil).Close), arg0) } @@ -52,7 +56,7 @@ func (mr *MockIndexerMockRecorder) Close(arg0 interface{}) *gomock.Call { // Index mocks base method. func (m *MockIndexer) Index(arg0 context.Context, arg1 DocInfo, arg2 ...IndexOption) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} + varargs := []any{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } @@ -62,9 +66,9 @@ func (m *MockIndexer) Index(arg0 context.Context, arg1 DocInfo, arg2 ...IndexOpt } // Index indicates an expected call of Index. -func (mr *MockIndexerMockRecorder) Index(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +func (mr *MockIndexerMockRecorder) Index(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index", reflect.TypeOf((*MockIndexer)(nil).Index), varargs...) } @@ -77,7 +81,7 @@ func (m *MockIndexer) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockIndexerMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockIndexerMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockIndexer)(nil).Init), arg0) } @@ -105,7 +109,7 @@ func (m *MockIndexer) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockIndexerMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockIndexerMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockIndexer)(nil).Run), arg0) } diff --git a/core/block/import/mock.go b/core/block/import/mock.go index d404e22c1..b830d29ac 100644 --- a/core/block/import/mock.go +++ b/core/block/import/mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/import (interfaces: Creator,IDGetter) - +// +// Generated by this command: +// +// mockgen -package importer -destination mock.go github.com/anyproto/anytype-heart/core/block/import Creator,IDGetter +// // Package importer is a generated GoMock package. package importer @@ -49,7 +53,7 @@ func (m *MockCreator) Create(arg0 *session.Context, arg1 *converter.Snapshot, ar } // Create indicates an expected call of Create. -func (mr *MockCreatorMockRecorder) Create(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockCreatorMockRecorder) Create(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockCreator)(nil).Create), arg0, arg1, arg2, arg3, arg4) } @@ -88,7 +92,7 @@ func (m *MockIDGetter) Get(arg0 *session.Context, arg1 *converter.Snapshot, arg2 } // Get indicates an expected call of Get. -func (mr *MockIDGetterMockRecorder) Get(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockIDGetterMockRecorder) Get(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockIDGetter)(nil).Get), arg0, arg1, arg2, arg3) } diff --git a/core/filestorage/filesync/filestore_mock.go b/core/filestorage/filesync/filestore_mock.go index 89c3bd7a1..61235181c 100644 --- a/core/filestorage/filesync/filestore_mock.go +++ b/core/filestorage/filesync/filestore_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore (interfaces: FileStore) - +// +// Generated by this command: +// +// mockgen -package filesync -destination filestore_mock.go github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore FileStore +// // Package filesync is a generated GoMock package. package filesync @@ -47,7 +51,7 @@ func (m *MockFileStore) Add(arg0 *storage.FileInfo) error { } // Add indicates an expected call of Add. -func (mr *MockFileStoreMockRecorder) Add(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) Add(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockFileStore)(nil).Add), arg0) } @@ -55,7 +59,7 @@ func (mr *MockFileStoreMockRecorder) Add(arg0 interface{}) *gomock.Call { // AddFileKeys mocks base method. func (m *MockFileStore) AddFileKeys(arg0 ...filestore.FileKeys) error { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -65,7 +69,7 @@ func (m *MockFileStore) AddFileKeys(arg0 ...filestore.FileKeys) error { } // AddFileKeys indicates an expected call of AddFileKeys. -func (mr *MockFileStoreMockRecorder) AddFileKeys(arg0 ...interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) AddFileKeys(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFileKeys", reflect.TypeOf((*MockFileStore)(nil).AddFileKeys), arg0...) } @@ -73,7 +77,7 @@ func (mr *MockFileStoreMockRecorder) AddFileKeys(arg0 ...interface{}) *gomock.Ca // AddMulti mocks base method. func (m *MockFileStore) AddMulti(arg0 bool, arg1 ...*storage.FileInfo) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -83,9 +87,9 @@ func (m *MockFileStore) AddMulti(arg0 bool, arg1 ...*storage.FileInfo) error { } // AddMulti indicates an expected call of AddMulti. -func (mr *MockFileStoreMockRecorder) AddMulti(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) AddMulti(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddMulti", reflect.TypeOf((*MockFileStore)(nil).AddMulti), varargs...) } @@ -98,7 +102,7 @@ func (m *MockFileStore) AddTarget(arg0, arg1 string) error { } // AddTarget indicates an expected call of AddTarget. -func (mr *MockFileStoreMockRecorder) AddTarget(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) AddTarget(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTarget", reflect.TypeOf((*MockFileStore)(nil).AddTarget), arg0, arg1) } @@ -112,7 +116,7 @@ func (m *MockFileStore) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockFileStoreMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockFileStore)(nil).Close), arg0) } @@ -126,7 +130,7 @@ func (m *MockFileStore) DeleteFile(arg0 string) error { } // DeleteFile indicates an expected call of DeleteFile. -func (mr *MockFileStoreMockRecorder) DeleteFile(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) DeleteFile(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteFile", reflect.TypeOf((*MockFileStore)(nil).DeleteFile), arg0) } @@ -141,7 +145,7 @@ func (m *MockFileStore) GetByChecksum(arg0, arg1 string) (*storage.FileInfo, err } // GetByChecksum indicates an expected call of GetByChecksum. -func (mr *MockFileStoreMockRecorder) GetByChecksum(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) GetByChecksum(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByChecksum", reflect.TypeOf((*MockFileStore)(nil).GetByChecksum), arg0, arg1) } @@ -156,7 +160,7 @@ func (m *MockFileStore) GetByHash(arg0 string) (*storage.FileInfo, error) { } // GetByHash indicates an expected call of GetByHash. -func (mr *MockFileStoreMockRecorder) GetByHash(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) GetByHash(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByHash", reflect.TypeOf((*MockFileStore)(nil).GetByHash), arg0) } @@ -171,7 +175,7 @@ func (m *MockFileStore) GetBySource(arg0, arg1, arg2 string) (*storage.FileInfo, } // GetBySource indicates an expected call of GetBySource. -func (mr *MockFileStoreMockRecorder) GetBySource(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) GetBySource(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBySource", reflect.TypeOf((*MockFileStore)(nil).GetBySource), arg0, arg1, arg2) } @@ -186,7 +190,7 @@ func (m *MockFileStore) GetChunksCount(arg0 string) (int, error) { } // GetChunksCount indicates an expected call of GetChunksCount. -func (mr *MockFileStoreMockRecorder) GetChunksCount(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) GetChunksCount(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChunksCount", reflect.TypeOf((*MockFileStore)(nil).GetChunksCount), arg0) } @@ -201,11 +205,26 @@ func (m *MockFileStore) GetFileKeys(arg0 string) (map[string]string, error) { } // GetFileKeys indicates an expected call of GetFileKeys. -func (mr *MockFileStoreMockRecorder) GetFileKeys(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) GetFileKeys(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFileKeys", reflect.TypeOf((*MockFileStore)(nil).GetFileKeys), arg0) } +// GetFileSize mocks base method. +func (m *MockFileStore) GetFileSize(arg0 string) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFileSize", arg0) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFileSize indicates an expected call of GetFileSize. +func (mr *MockFileStoreMockRecorder) GetFileSize(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFileSize", reflect.TypeOf((*MockFileStore)(nil).GetFileSize), arg0) +} + // GetSyncStatus mocks base method. func (m *MockFileStore) GetSyncStatus(arg0 string) (int, error) { m.ctrl.T.Helper() @@ -216,7 +235,7 @@ func (m *MockFileStore) GetSyncStatus(arg0 string) (int, error) { } // GetSyncStatus indicates an expected call of GetSyncStatus. -func (mr *MockFileStoreMockRecorder) GetSyncStatus(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) GetSyncStatus(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSyncStatus", reflect.TypeOf((*MockFileStore)(nil).GetSyncStatus), arg0) } @@ -244,7 +263,7 @@ func (m *MockFileStore) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockFileStoreMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockFileStore)(nil).Init), arg0) } @@ -259,7 +278,7 @@ func (m *MockFileStore) IsFileImported(arg0 string) (bool, error) { } // IsFileImported indicates an expected call of IsFileImported. -func (mr *MockFileStoreMockRecorder) IsFileImported(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) IsFileImported(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsFileImported", reflect.TypeOf((*MockFileStore)(nil).IsFileImported), arg0) } @@ -289,7 +308,7 @@ func (m *MockFileStore) ListByTarget(arg0 string) ([]*storage.FileInfo, error) { } // ListByTarget indicates an expected call of ListByTarget. -func (mr *MockFileStoreMockRecorder) ListByTarget(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) ListByTarget(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListByTarget", reflect.TypeOf((*MockFileStore)(nil).ListByTarget), arg0) } @@ -346,7 +365,7 @@ func (m *MockFileStore) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockFileStoreMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockFileStore)(nil).Run), arg0) } @@ -360,11 +379,25 @@ func (m *MockFileStore) SetChunksCount(arg0 string, arg1 int) error { } // SetChunksCount indicates an expected call of SetChunksCount. -func (mr *MockFileStoreMockRecorder) SetChunksCount(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) SetChunksCount(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetChunksCount", reflect.TypeOf((*MockFileStore)(nil).SetChunksCount), arg0, arg1) } +// SetFileSize mocks base method. +func (m *MockFileStore) SetFileSize(arg0 string, arg1 int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetFileSize", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetFileSize indicates an expected call of SetFileSize. +func (mr *MockFileStoreMockRecorder) SetFileSize(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFileSize", reflect.TypeOf((*MockFileStore)(nil).SetFileSize), arg0, arg1) +} + // SetIsFileImported mocks base method. func (m *MockFileStore) SetIsFileImported(arg0 string, arg1 bool) error { m.ctrl.T.Helper() @@ -374,7 +407,7 @@ func (m *MockFileStore) SetIsFileImported(arg0 string, arg1 bool) error { } // SetIsFileImported indicates an expected call of SetIsFileImported. -func (mr *MockFileStoreMockRecorder) SetIsFileImported(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) SetIsFileImported(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetIsFileImported", reflect.TypeOf((*MockFileStore)(nil).SetIsFileImported), arg0, arg1) } @@ -388,7 +421,7 @@ func (m *MockFileStore) SetSyncStatus(arg0 string, arg1 int) error { } // SetSyncStatus indicates an expected call of SetSyncStatus. -func (mr *MockFileStoreMockRecorder) SetSyncStatus(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileStoreMockRecorder) SetSyncStatus(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSyncStatus", reflect.TypeOf((*MockFileStore)(nil).SetSyncStatus), arg0, arg1) } diff --git a/core/filestorage/filesync/filesync_test.go b/core/filestorage/filesync/filesync_test.go index b68dfa996..fb95d199a 100644 --- a/core/filestorage/filesync/filesync_test.go +++ b/core/filestorage/filesync/filesync_test.go @@ -49,7 +49,8 @@ func TestFileSync_AddFile(t *testing.T) { spaceId := "space1" fx.fileStoreMock.EXPECT().GetSyncStatus(fileId).Return(int(syncstatus.StatusNotSynced), nil) - + fx.fileStoreMock.EXPECT().GetFileSize(fileId).Return(0, fmt.Errorf("not found")) + fx.fileStoreMock.EXPECT().SetFileSize(fileId, gomock.Any()).Return(nil) fx.fileStoreMock.EXPECT().ListByTarget(fileId).Return([]*storage.FileInfo{ {}, // We can use just empty struct here, because we don't use any fields }, nil).AnyTimes() diff --git a/core/filestorage/filesync/mock_filesync/filesync_mock.go b/core/filestorage/filesync/mock_filesync/filesync_mock.go index 4a9df2a4a..b53843936 100644 --- a/core/filestorage/filesync/mock_filesync/filesync_mock.go +++ b/core/filestorage/filesync/mock_filesync/filesync_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/filestorage/filesync (interfaces: FileSync) - +// +// Generated by this command: +// +// mockgen -package mock_filesync -destination ./mock_filesync/filesync_mock.go github.com/anyproto/anytype-heart/core/filestorage/filesync FileSync +// // Package mock_filesync is a generated GoMock package. package mock_filesync @@ -47,7 +51,7 @@ func (m *MockFileSync) AddFile(arg0, arg1 string, arg2, arg3 bool) error { } // AddFile indicates an expected call of AddFile. -func (mr *MockFileSyncMockRecorder) AddFile(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) AddFile(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFile", reflect.TypeOf((*MockFileSync)(nil).AddFile), arg0, arg1, arg2, arg3) } @@ -73,7 +77,7 @@ func (m *MockFileSync) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockFileSyncMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockFileSync)(nil).Close), arg0) } @@ -88,7 +92,7 @@ func (m *MockFileSync) DebugQueue(arg0 *http.Request) (*filesync.QueueInfo, erro } // DebugQueue indicates an expected call of DebugQueue. -func (mr *MockFileSyncMockRecorder) DebugQueue(arg0 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) DebugQueue(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugQueue", reflect.TypeOf((*MockFileSync)(nil).DebugQueue), arg0) } @@ -103,7 +107,7 @@ func (m *MockFileSync) FetchChunksCount(arg0 context.Context, arg1 format.Node) } // FetchChunksCount indicates an expected call of FetchChunksCount. -func (mr *MockFileSyncMockRecorder) FetchChunksCount(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) FetchChunksCount(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchChunksCount", reflect.TypeOf((*MockFileSync)(nil).FetchChunksCount), arg0, arg1) } @@ -118,7 +122,7 @@ func (m *MockFileSync) FileListStats(arg0 context.Context, arg1 string, arg2 []s } // FileListStats indicates an expected call of FileListStats. -func (mr *MockFileSyncMockRecorder) FileListStats(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) FileListStats(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileListStats", reflect.TypeOf((*MockFileSync)(nil).FileListStats), arg0, arg1, arg2) } @@ -133,7 +137,7 @@ func (m *MockFileSync) FileStat(arg0 context.Context, arg1, arg2 string) (filesy } // FileStat indicates an expected call of FileStat. -func (mr *MockFileSyncMockRecorder) FileStat(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) FileStat(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileStat", reflect.TypeOf((*MockFileSync)(nil).FileStat), arg0, arg1, arg2) } @@ -148,7 +152,7 @@ func (m *MockFileSync) HasUpload(arg0, arg1 string) (bool, error) { } // HasUpload indicates an expected call of HasUpload. -func (mr *MockFileSyncMockRecorder) HasUpload(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) HasUpload(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasUpload", reflect.TypeOf((*MockFileSync)(nil).HasUpload), arg0, arg1) } @@ -162,7 +166,7 @@ func (m *MockFileSync) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockFileSyncMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockFileSync)(nil).Init), arg0) } @@ -177,7 +181,7 @@ func (m *MockFileSync) IsFileUploadLimited(arg0, arg1 string) (bool, error) { } // IsFileUploadLimited indicates an expected call of IsFileUploadLimited. -func (mr *MockFileSyncMockRecorder) IsFileUploadLimited(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) IsFileUploadLimited(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsFileUploadLimited", reflect.TypeOf((*MockFileSync)(nil).IsFileUploadLimited), arg0, arg1) } @@ -203,7 +207,7 @@ func (m *MockFileSync) OnUpload(arg0 func(string, string) error) { } // OnUpload indicates an expected call of OnUpload. -func (mr *MockFileSyncMockRecorder) OnUpload(arg0 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) OnUpload(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnUpload", reflect.TypeOf((*MockFileSync)(nil).OnUpload), arg0) } @@ -217,7 +221,7 @@ func (m *MockFileSync) RemoveFile(arg0, arg1 string) error { } // RemoveFile indicates an expected call of RemoveFile. -func (mr *MockFileSyncMockRecorder) RemoveFile(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) RemoveFile(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFile", reflect.TypeOf((*MockFileSync)(nil).RemoveFile), arg0, arg1) } @@ -231,7 +235,7 @@ func (m *MockFileSync) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockFileSyncMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockFileSync)(nil).Run), arg0) } @@ -258,7 +262,7 @@ func (m *MockFileSync) SpaceStat(arg0 context.Context, arg1 string) (filesync.Sp } // SpaceStat indicates an expected call of SpaceStat. -func (mr *MockFileSyncMockRecorder) SpaceStat(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileSyncMockRecorder) SpaceStat(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceStat", reflect.TypeOf((*MockFileSync)(nil).SpaceStat), arg0, arg1) } diff --git a/core/filestorage/filesync/upload.go b/core/filestorage/filesync/upload.go index 38892edf3..11dcb6d0e 100644 --- a/core/filestorage/filesync/upload.go +++ b/core/filestorage/filesync/upload.go @@ -151,14 +151,14 @@ func isLimitReachedErr(err error) bool { return errors.Is(err, errReachedLimit) || strings.Contains(err.Error(), fileprotoerr.ErrSpaceLimitExceeded.Error()) } -func (f *fileSync) uploadFile(ctx context.Context, spaceId, fileId string) error { - log.Debug("uploading file", zap.String("fileId", fileId)) +func (f *fileSync) uploadFile(ctx context.Context, spaceID string, fileID string) error { + log.Debug("uploading file", zap.String("fileID", fileID)) - fileSize, err := f.calculateFileSize(ctx, fileId) + fileSize, err := f.calculateFileSize(ctx, fileID) if err != nil { return fmt.Errorf("calculate file size: %w", err) } - stat, err := f.getAndUpdateSpaceStat(ctx, spaceId) + stat, err := f.getAndUpdateSpaceStat(ctx, spaceID) if err != nil { return fmt.Errorf("get space stat: %w", err) } @@ -169,12 +169,12 @@ func (f *fileSync) uploadFile(ctx context.Context, spaceId, fileId string) error } var totalBytesUploaded int - err = f.walkFileBlocks(ctx, fileId, func(fileBlocks []blocks.Block) error { - bytesToUpload, blocksToUpload, err := f.selectBlocksToUploadAndBindExisting(ctx, spaceId, fileId, fileBlocks) + err = f.walkFileBlocks(ctx, fileID, func(fileBlocks []blocks.Block) error { + bytesToUpload, blocksToUpload, err := f.selectBlocksToUploadAndBindExisting(ctx, spaceID, fileID, fileBlocks) if err != nil { return fmt.Errorf("select blocks to upload: %w", err) } - if err = f.rpcStore.AddToFile(ctx, spaceId, fileId, blocksToUpload); err != nil { + if err = f.rpcStore.AddToFile(ctx, spaceID, fileID, blocksToUpload); err != nil { return err } totalBytesUploaded += bytesToUpload @@ -184,7 +184,7 @@ func (f *fileSync) uploadFile(ctx context.Context, spaceId, fileId string) error return fmt.Errorf("walk file blocks: %w", err) } - log.Warn("done upload", zap.String("fileID", fileId), zap.Int("estimatedSize", fileSize), zap.Int("bytesUploaded", totalBytesUploaded)) + log.Warn("done upload", zap.String("fileID", fileID), zap.Int("estimatedSize", fileSize), zap.Int("bytesUploaded", totalBytesUploaded)) return nil } @@ -314,10 +314,10 @@ func (f *fileSync) calculateFileSize(ctx context.Context, fileID string) (int, e const batchSize = 10 -func (f *fileSync) walkFileBlocks(ctx context.Context, fileId string, proc func(fileBlocks []blocks.Block) error) error { +func (f *fileSync) walkFileBlocks(ctx context.Context, fileID string, proc func(fileBlocks []blocks.Block) error) error { blocksBuf := make([]blocks.Block, 0, batchSize) - err := f.walkDAG(ctx, fileId, func(node ipld.NavigableNode) error { + err := f.walkDAG(ctx, fileID, func(node ipld.NavigableNode) error { b, err := blocks.NewBlockWithCid(node.GetIPLDNode().RawData(), node.GetIPLDNode().Cid()) if err != nil { return err diff --git a/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go b/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go index 0ab552919..492224cd7 100644 --- a/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go +++ b/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/filestorage/rpcstore (interfaces: Service,RpcStore) - +// +// Generated by this command: +// +// mockgen -destination mock_rpcstore/mock_rpcstore.go github.com/anyproto/anytype-heart/core/filestorage/rpcstore Service,RpcStore +// // Package mock_rpcstore is a generated GoMock package. package mock_rpcstore @@ -48,7 +52,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -113,7 +117,7 @@ func (m *MockRpcStore) Add(arg0 context.Context, arg1 []blocks.Block) error { } // Add indicates an expected call of Add. -func (mr *MockRpcStoreMockRecorder) Add(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) Add(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockRpcStore)(nil).Add), arg0, arg1) } @@ -127,7 +131,7 @@ func (m *MockRpcStore) AddToFile(arg0 context.Context, arg1, arg2 string, arg3 [ } // AddToFile indicates an expected call of AddToFile. -func (mr *MockRpcStoreMockRecorder) AddToFile(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) AddToFile(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToFile", reflect.TypeOf((*MockRpcStore)(nil).AddToFile), arg0, arg1, arg2, arg3) } @@ -141,7 +145,7 @@ func (m *MockRpcStore) BindCids(arg0 context.Context, arg1, arg2 string, arg3 [] } // BindCids indicates an expected call of BindCids. -func (mr *MockRpcStoreMockRecorder) BindCids(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) BindCids(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindCids", reflect.TypeOf((*MockRpcStore)(nil).BindCids), arg0, arg1, arg2, arg3) } @@ -156,7 +160,7 @@ func (m *MockRpcStore) CheckAvailability(arg0 context.Context, arg1 string, arg2 } // CheckAvailability indicates an expected call of CheckAvailability. -func (mr *MockRpcStoreMockRecorder) CheckAvailability(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) CheckAvailability(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAvailability", reflect.TypeOf((*MockRpcStore)(nil).CheckAvailability), arg0, arg1, arg2) } @@ -170,7 +174,7 @@ func (m *MockRpcStore) Delete(arg0 context.Context, arg1 cid.Cid) error { } // Delete indicates an expected call of Delete. -func (mr *MockRpcStoreMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) Delete(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockRpcStore)(nil).Delete), arg0, arg1) } @@ -178,7 +182,7 @@ func (mr *MockRpcStoreMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call // DeleteFiles mocks base method. func (m *MockRpcStore) DeleteFiles(arg0 context.Context, arg1 string, arg2 ...string) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} + varargs := []any{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } @@ -188,16 +192,16 @@ func (m *MockRpcStore) DeleteFiles(arg0 context.Context, arg1 string, arg2 ...st } // DeleteFiles indicates an expected call of DeleteFiles. -func (mr *MockRpcStoreMockRecorder) DeleteFiles(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) DeleteFiles(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteFiles", reflect.TypeOf((*MockRpcStore)(nil).DeleteFiles), varargs...) } // FilesInfo mocks base method. func (m *MockRpcStore) FilesInfo(arg0 context.Context, arg1 string, arg2 ...string) ([]*fileproto.FileInfo, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} + varargs := []any{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } @@ -208,9 +212,9 @@ func (m *MockRpcStore) FilesInfo(arg0 context.Context, arg1 string, arg2 ...stri } // FilesInfo indicates an expected call of FilesInfo. -func (mr *MockRpcStoreMockRecorder) FilesInfo(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) FilesInfo(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FilesInfo", reflect.TypeOf((*MockRpcStore)(nil).FilesInfo), varargs...) } @@ -224,7 +228,7 @@ func (m *MockRpcStore) Get(arg0 context.Context, arg1 cid.Cid) (blocks.Block, er } // Get indicates an expected call of Get. -func (mr *MockRpcStoreMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) Get(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRpcStore)(nil).Get), arg0, arg1) } @@ -238,7 +242,7 @@ func (m *MockRpcStore) GetMany(arg0 context.Context, arg1 []cid.Cid) <-chan bloc } // GetMany indicates an expected call of GetMany. -func (mr *MockRpcStoreMockRecorder) GetMany(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) GetMany(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMany", reflect.TypeOf((*MockRpcStore)(nil).GetMany), arg0, arg1) } @@ -253,7 +257,7 @@ func (m *MockRpcStore) SpaceInfo(arg0 context.Context, arg1 string) (*fileproto. } // SpaceInfo indicates an expected call of SpaceInfo. -func (mr *MockRpcStoreMockRecorder) SpaceInfo(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRpcStoreMockRecorder) SpaceInfo(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceInfo", reflect.TypeOf((*MockRpcStore)(nil).SpaceInfo), arg0, arg1) } diff --git a/pkg/lib/core/mock_core/service_mock.go b/pkg/lib/core/mock_core/service_mock.go index 8acb6c899..3ffcdadb1 100644 --- a/pkg/lib/core/mock_core/service_mock.go +++ b/pkg/lib/core/mock_core/service_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/pkg/lib/core (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mock_core -destination ./mock_core/service_mock.go github.com/anyproto/anytype-heart/pkg/lib/core Service +// // Package mock_core is a generated GoMock package. package mock_core @@ -46,7 +50,7 @@ func (m *MockService) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) } @@ -60,7 +64,7 @@ func (m *MockService) EnsurePredefinedBlocks(arg0 context.Context) error { } // EnsurePredefinedBlocks indicates an expected call of EnsurePredefinedBlocks. -func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsurePredefinedBlocks", reflect.TypeOf((*MockService)(nil).EnsurePredefinedBlocks), arg0) } @@ -90,7 +94,7 @@ func (m *MockService) GetWorkspaceIdForObject(arg0 string) (string, error) { } // GetWorkspaceIdForObject indicates an expected call of GetWorkspaceIdForObject. -func (mr *MockServiceMockRecorder) GetWorkspaceIdForObject(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) GetWorkspaceIdForObject(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceIdForObject", reflect.TypeOf((*MockService)(nil).GetWorkspaceIdForObject), arg0) } @@ -104,7 +108,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -189,7 +193,7 @@ func (m *MockService) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) } diff --git a/space/mock_space/commonspace_space_mock.go b/space/mock_space/commonspace_space_mock.go index e1d73cd96..14d956c2a 100644 --- a/space/mock_space/commonspace_space_mock.go +++ b/space/mock_space/commonspace_space_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/any-sync/commonspace (interfaces: Space) - +// +// Generated by this command: +// +// mockgen -package mock_space -destination ./mock_space/commonspace_space_mock.go github.com/anyproto/any-sync/commonspace Space +// // Package mock_space is a generated GoMock package. package mock_space @@ -11,12 +15,13 @@ import ( commonspace "github.com/anyproto/any-sync/commonspace" headsync "github.com/anyproto/any-sync/commonspace/headsync" - treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + syncacl "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" objectsync "github.com/anyproto/any-sync/commonspace/objectsync" objecttreebuilder "github.com/anyproto/any-sync/commonspace/objecttreebuilder" spacestorage "github.com/anyproto/any-sync/commonspace/spacestorage" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" syncstatus "github.com/anyproto/any-sync/commonspace/syncstatus" + peer "github.com/anyproto/any-sync/net/peer" gomock "go.uber.org/mock/gomock" ) @@ -43,6 +48,20 @@ func (m *MockSpace) EXPECT() *MockSpaceMockRecorder { return m.recorder } +// Acl mocks base method. +func (m *MockSpace) Acl() syncacl.SyncAcl { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Acl") + ret0, _ := ret[0].(syncacl.SyncAcl) + return ret0 +} + +// Acl indicates an expected call of Acl. +func (mr *MockSpaceMockRecorder) Acl() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Acl", reflect.TypeOf((*MockSpace)(nil).Acl)) +} + // Close mocks base method. func (m *MockSpace) Close() error { m.ctrl.T.Helper() @@ -71,20 +90,6 @@ func (mr *MockSpaceMockRecorder) DebugAllHeads() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugAllHeads", reflect.TypeOf((*MockSpace)(nil).DebugAllHeads)) } -// DeleteSpace mocks base method. -func (m *MockSpace) DeleteSpace(arg0 context.Context, arg1 *treechangeproto.RawTreeChangeWithId) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteSpace", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteSpace indicates an expected call of DeleteSpace. -func (mr *MockSpaceMockRecorder) DeleteSpace(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSpace", reflect.TypeOf((*MockSpace)(nil).DeleteSpace), arg0, arg1) -} - // DeleteTree mocks base method. func (m *MockSpace) DeleteTree(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() @@ -94,7 +99,7 @@ func (m *MockSpace) DeleteTree(arg0 context.Context, arg1 string) error { } // DeleteTree indicates an expected call of DeleteTree. -func (mr *MockSpaceMockRecorder) DeleteTree(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSpaceMockRecorder) DeleteTree(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTree", reflect.TypeOf((*MockSpace)(nil).DeleteTree), arg0, arg1) } @@ -114,6 +119,21 @@ func (mr *MockSpaceMockRecorder) Description() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Description", reflect.TypeOf((*MockSpace)(nil).Description)) } +// GetNodePeers mocks base method. +func (m *MockSpace) GetNodePeers(arg0 context.Context) ([]peer.Peer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNodePeers", arg0) + ret0, _ := ret[0].([]peer.Peer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNodePeers indicates an expected call of GetNodePeers. +func (mr *MockSpaceMockRecorder) GetNodePeers(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodePeers", reflect.TypeOf((*MockSpace)(nil).GetNodePeers), arg0) +} + // HandleMessage mocks base method. func (m *MockSpace) HandleMessage(arg0 context.Context, arg1 objectsync.HandleMessage) error { m.ctrl.T.Helper() @@ -123,7 +143,7 @@ func (m *MockSpace) HandleMessage(arg0 context.Context, arg1 objectsync.HandleMe } // HandleMessage indicates an expected call of HandleMessage. -func (mr *MockSpaceMockRecorder) HandleMessage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSpaceMockRecorder) HandleMessage(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockSpace)(nil).HandleMessage), arg0, arg1) } @@ -138,7 +158,7 @@ func (m *MockSpace) HandleRangeRequest(arg0 context.Context, arg1 *spacesyncprot } // HandleRangeRequest indicates an expected call of HandleRangeRequest. -func (mr *MockSpaceMockRecorder) HandleRangeRequest(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSpaceMockRecorder) HandleRangeRequest(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleRangeRequest", reflect.TypeOf((*MockSpace)(nil).HandleRangeRequest), arg0, arg1) } @@ -153,7 +173,7 @@ func (m *MockSpace) HandleSyncRequest(arg0 context.Context, arg1 *spacesyncproto } // HandleSyncRequest indicates an expected call of HandleSyncRequest. -func (mr *MockSpaceMockRecorder) HandleSyncRequest(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSpaceMockRecorder) HandleSyncRequest(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleSyncRequest", reflect.TypeOf((*MockSpace)(nil).HandleSyncRequest), arg0, arg1) } @@ -181,26 +201,11 @@ func (m *MockSpace) Init(arg0 context.Context) error { } // Init indicates an expected call of Init. -func (mr *MockSpaceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockSpaceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockSpace)(nil).Init), arg0) } -// SpaceDeleteRawChange mocks base method. -func (m *MockSpace) SpaceDeleteRawChange(arg0 context.Context) (*treechangeproto.RawTreeChangeWithId, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SpaceDeleteRawChange", arg0) - ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SpaceDeleteRawChange indicates an expected call of SpaceDeleteRawChange. -func (mr *MockSpaceMockRecorder) SpaceDeleteRawChange(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceDeleteRawChange", reflect.TypeOf((*MockSpace)(nil).SpaceDeleteRawChange), arg0) -} - // Storage mocks base method. func (m *MockSpace) Storage() spacestorage.SpaceStorage { m.ctrl.T.Helper() @@ -267,7 +272,7 @@ func (m *MockSpace) TryClose(arg0 time.Duration) (bool, error) { } // TryClose indicates an expected call of TryClose. -func (mr *MockSpaceMockRecorder) TryClose(arg0 interface{}) *gomock.Call { +func (mr *MockSpaceMockRecorder) TryClose(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryClose", reflect.TypeOf((*MockSpace)(nil).TryClose), arg0) } diff --git a/space/mock_space/service_mock.go b/space/mock_space/service_mock.go index 2000dbb65..565e74216 100644 --- a/space/mock_space/service_mock.go +++ b/space/mock_space/service_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/space (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mock_space -destination ./mock_space/service_mock.go github.com/anyproto/anytype-heart/space Service +// // Package mock_space is a generated GoMock package. package mock_space @@ -62,7 +66,7 @@ func (m *MockService) AccountSpace(arg0 context.Context) (commonspace.Space, err } // AccountSpace indicates an expected call of AccountSpace. -func (mr *MockServiceMockRecorder) AccountSpace(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) AccountSpace(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountSpace", reflect.TypeOf((*MockService)(nil).AccountSpace), arg0) } @@ -76,7 +80,7 @@ func (m *MockService) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) } @@ -91,7 +95,7 @@ func (m *MockService) DeleteAccount(arg0 context.Context, arg1 bool) (space.Stat } // DeleteAccount indicates an expected call of DeleteAccount. -func (mr *MockServiceMockRecorder) DeleteAccount(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeleteAccount(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccount", reflect.TypeOf((*MockService)(nil).DeleteAccount), arg0, arg1) } @@ -106,7 +110,7 @@ func (m *MockService) DeleteSpace(arg0 context.Context, arg1 string, arg2 bool) } // DeleteSpace indicates an expected call of DeleteSpace. -func (mr *MockServiceMockRecorder) DeleteSpace(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeleteSpace(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSpace", reflect.TypeOf((*MockService)(nil).DeleteSpace), arg0, arg1, arg2) } @@ -121,7 +125,7 @@ func (m *MockService) DeriveSpace(arg0 context.Context, arg1 commonspace.SpaceDe } // DeriveSpace indicates an expected call of DeriveSpace. -func (mr *MockServiceMockRecorder) DeriveSpace(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeriveSpace(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeriveSpace", reflect.TypeOf((*MockService)(nil).DeriveSpace), arg0, arg1) } @@ -136,7 +140,7 @@ func (m *MockService) GetSpace(arg0 context.Context, arg1 string) (commonspace.S } // GetSpace indicates an expected call of GetSpace. -func (mr *MockServiceMockRecorder) GetSpace(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) GetSpace(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpace", reflect.TypeOf((*MockService)(nil).GetSpace), arg0, arg1) } @@ -150,7 +154,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -178,7 +182,7 @@ func (m *MockService) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) } diff --git a/util/testMock/anytype_mock.go b/util/testMock/anytype_mock.go index d3d6cd154..f020edf65 100644 --- a/util/testMock/anytype_mock.go +++ b/util/testMock/anytype_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/pkg/lib/core (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package testMock -destination anytype_mock.go github.com/anyproto/anytype-heart/pkg/lib/core Service +// // Package testMock is a generated GoMock package. package testMock @@ -46,7 +50,7 @@ func (m *MockService) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) } @@ -60,7 +64,7 @@ func (m *MockService) EnsurePredefinedBlocks(arg0 context.Context) error { } // EnsurePredefinedBlocks indicates an expected call of EnsurePredefinedBlocks. -func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsurePredefinedBlocks", reflect.TypeOf((*MockService)(nil).EnsurePredefinedBlocks), arg0) } @@ -90,7 +94,7 @@ func (m *MockService) GetWorkspaceIdForObject(arg0 string) (string, error) { } // GetWorkspaceIdForObject indicates an expected call of GetWorkspaceIdForObject. -func (mr *MockServiceMockRecorder) GetWorkspaceIdForObject(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) GetWorkspaceIdForObject(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceIdForObject", reflect.TypeOf((*MockService)(nil).GetWorkspaceIdForObject), arg0) } @@ -104,7 +108,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -189,7 +193,7 @@ func (m *MockService) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) } diff --git a/util/testMock/file_service_mock.go b/util/testMock/file_service_mock.go index 60039107a..e02da5ca3 100644 --- a/util/testMock/file_service_mock.go +++ b/util/testMock/file_service_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/files (interfaces: Service,Image,File) - +// +// Generated by this command: +// +// mockgen -package testMock -destination file_service_mock.go -mock_names Service=MockFileService github.com/anyproto/anytype-heart/core/files Service,Image,File +// // Package testMock is a generated GoMock package. package testMock @@ -44,7 +48,7 @@ func (m *MockFileService) EXPECT() *MockFileServiceMockRecorder { // FileAdd mocks base method. func (m *MockFileService) FileAdd(arg0 context.Context, arg1 ...files.AddOption) (files.File, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -55,9 +59,9 @@ func (m *MockFileService) FileAdd(arg0 context.Context, arg1 ...files.AddOption) } // FileAdd indicates an expected call of FileAdd. -func (mr *MockFileServiceMockRecorder) FileAdd(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileAdd(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileAdd", reflect.TypeOf((*MockFileService)(nil).FileAdd), varargs...) } @@ -71,7 +75,7 @@ func (m *MockFileService) FileByHash(arg0 context.Context, arg1 string) (files.F } // FileByHash indicates an expected call of FileByHash. -func (mr *MockFileServiceMockRecorder) FileByHash(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileByHash(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileByHash", reflect.TypeOf((*MockFileService)(nil).FileByHash), arg0, arg1) } @@ -86,7 +90,7 @@ func (m *MockFileService) FileGetKeys(arg0 string) (*files.FileKeys, error) { } // FileGetKeys indicates an expected call of FileGetKeys. -func (mr *MockFileServiceMockRecorder) FileGetKeys(arg0 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileGetKeys(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileGetKeys", reflect.TypeOf((*MockFileService)(nil).FileGetKeys), arg0) } @@ -102,7 +106,7 @@ func (m *MockFileService) FileListOffload(arg0 []string, arg1 bool) (uint64, uin } // FileListOffload indicates an expected call of FileListOffload. -func (mr *MockFileServiceMockRecorder) FileListOffload(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileListOffload(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileListOffload", reflect.TypeOf((*MockFileService)(nil).FileListOffload), arg0, arg1) } @@ -117,7 +121,7 @@ func (m *MockFileService) FileOffload(arg0 string, arg1 bool) (uint64, error) { } // FileOffload indicates an expected call of FileOffload. -func (mr *MockFileServiceMockRecorder) FileOffload(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileOffload(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileOffload", reflect.TypeOf((*MockFileService)(nil).FileOffload), arg0, arg1) } @@ -132,7 +136,7 @@ func (m *MockFileService) GetSpaceUsage(arg0 context.Context) (*pb.RpcFileSpaceU } // GetSpaceUsage indicates an expected call of GetSpaceUsage. -func (mr *MockFileServiceMockRecorder) GetSpaceUsage(arg0 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) GetSpaceUsage(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpaceUsage", reflect.TypeOf((*MockFileService)(nil).GetSpaceUsage), arg0) } @@ -140,7 +144,7 @@ func (mr *MockFileServiceMockRecorder) GetSpaceUsage(arg0 interface{}) *gomock.C // ImageAdd mocks base method. func (m *MockFileService) ImageAdd(arg0 context.Context, arg1 ...files.AddOption) (files.Image, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -151,9 +155,9 @@ func (m *MockFileService) ImageAdd(arg0 context.Context, arg1 ...files.AddOption } // ImageAdd indicates an expected call of ImageAdd. -func (mr *MockFileServiceMockRecorder) ImageAdd(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) ImageAdd(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageAdd", reflect.TypeOf((*MockFileService)(nil).ImageAdd), varargs...) } @@ -167,7 +171,7 @@ func (m *MockFileService) ImageByHash(arg0 context.Context, arg1 string) (files. } // ImageByHash indicates an expected call of ImageByHash. -func (mr *MockFileServiceMockRecorder) ImageByHash(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) ImageByHash(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageByHash", reflect.TypeOf((*MockFileService)(nil).ImageByHash), arg0, arg1) } @@ -181,7 +185,7 @@ func (m *MockFileService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockFileServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockFileService)(nil).Init), arg0) } @@ -203,7 +207,7 @@ func (mr *MockFileServiceMockRecorder) Name() *gomock.Call { // StoreFileKeys mocks base method. func (m *MockFileService) StoreFileKeys(arg0 ...files.FileKeys) error { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -213,7 +217,7 @@ func (m *MockFileService) StoreFileKeys(arg0 ...files.FileKeys) error { } // StoreFileKeys indicates an expected call of StoreFileKeys. -func (mr *MockFileServiceMockRecorder) StoreFileKeys(arg0 ...interface{}) *gomock.Call { +func (mr *MockFileServiceMockRecorder) StoreFileKeys(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreFileKeys", reflect.TypeOf((*MockFileService)(nil).StoreFileKeys), arg0...) } @@ -251,7 +255,7 @@ func (m *MockImage) Details(arg0 context.Context) (*types.Struct, error) { } // Details indicates an expected call of Details. -func (mr *MockImageMockRecorder) Details(arg0 interface{}) *gomock.Call { +func (mr *MockImageMockRecorder) Details(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Details", reflect.TypeOf((*MockImage)(nil).Details), arg0) } @@ -266,7 +270,7 @@ func (m *MockImage) Exif(arg0 context.Context) (*mill.ImageExifSchema, error) { } // Exif indicates an expected call of Exif. -func (mr *MockImageMockRecorder) Exif(arg0 interface{}) *gomock.Call { +func (mr *MockImageMockRecorder) Exif(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exif", reflect.TypeOf((*MockImage)(nil).Exif), arg0) } @@ -281,7 +285,7 @@ func (m *MockImage) GetFileForLargestWidth(arg0 context.Context) (files.File, er } // GetFileForLargestWidth indicates an expected call of GetFileForLargestWidth. -func (mr *MockImageMockRecorder) GetFileForLargestWidth(arg0 interface{}) *gomock.Call { +func (mr *MockImageMockRecorder) GetFileForLargestWidth(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFileForLargestWidth", reflect.TypeOf((*MockImage)(nil).GetFileForLargestWidth), arg0) } @@ -296,7 +300,7 @@ func (m *MockImage) GetFileForWidth(arg0 context.Context, arg1 int) (files.File, } // GetFileForWidth indicates an expected call of GetFileForWidth. -func (mr *MockImageMockRecorder) GetFileForWidth(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockImageMockRecorder) GetFileForWidth(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFileForWidth", reflect.TypeOf((*MockImage)(nil).GetFileForWidth), arg0, arg1) } @@ -311,7 +315,7 @@ func (m *MockImage) GetOriginalFile(arg0 context.Context) (files.File, error) { } // GetOriginalFile indicates an expected call of GetOriginalFile. -func (mr *MockImageMockRecorder) GetOriginalFile(arg0 interface{}) *gomock.Call { +func (mr *MockImageMockRecorder) GetOriginalFile(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOriginalFile", reflect.TypeOf((*MockImage)(nil).GetOriginalFile), arg0) } @@ -363,7 +367,7 @@ func (m *MockFile) Details(arg0 context.Context) (*types.Struct, error) { } // Details indicates an expected call of Details. -func (mr *MockFileMockRecorder) Details(arg0 interface{}) *gomock.Call { +func (mr *MockFileMockRecorder) Details(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Details", reflect.TypeOf((*MockFile)(nil).Details), arg0) } @@ -420,7 +424,7 @@ func (m *MockFile) Reader(arg0 context.Context) (io.ReadSeeker, error) { } // Reader indicates an expected call of Reader. -func (mr *MockFileMockRecorder) Reader(arg0 interface{}) *gomock.Call { +func (mr *MockFileMockRecorder) Reader(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reader", reflect.TypeOf((*MockFile)(nil).Reader), arg0) } diff --git a/util/testMock/history_mock.go b/util/testMock/history_mock.go index 604a7232a..d89e05210 100644 --- a/util/testMock/history_mock.go +++ b/util/testMock/history_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/undo (interfaces: History) - +// +// Generated by this command: +// +// mockgen -package testMock -destination history_mock.go github.com/anyproto/anytype-heart/core/block/undo History +// // Package testMock is a generated GoMock package. package testMock @@ -41,7 +45,7 @@ func (m *MockHistory) Add(arg0 undo.Action) { } // Add indicates an expected call of Add. -func (mr *MockHistoryMockRecorder) Add(arg0 interface{}) *gomock.Call { +func (mr *MockHistoryMockRecorder) Add(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockHistory)(nil).Add), arg0) } diff --git a/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go b/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go index 1f39f3d37..b82119fe2 100644 --- a/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go +++ b/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/util/builtintemplate (interfaces: BuiltinTemplate) - +// +// Generated by this command: +// +// mockgen -package mockBuiltinTemplate -destination builtintemplate_mock.go github.com/anyproto/anytype-heart/util/builtintemplate BuiltinTemplate +// // Package mockBuiltinTemplate is a generated GoMock package. package mockBuiltinTemplate @@ -44,7 +48,7 @@ func (m *MockBuiltinTemplate) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockBuiltinTemplateMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockBuiltinTemplateMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockBuiltinTemplate)(nil).Close), arg0) } @@ -72,7 +76,7 @@ func (m *MockBuiltinTemplate) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockBuiltinTemplateMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockBuiltinTemplateMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockBuiltinTemplate)(nil).Init), arg0) } @@ -100,7 +104,7 @@ func (m *MockBuiltinTemplate) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockBuiltinTemplateMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockBuiltinTemplateMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockBuiltinTemplate)(nil).Run), arg0) } diff --git a/util/testMock/mockCreator/creator_mock.go b/util/testMock/mockCreator/creator_mock.go index 63e1a7da1..5cc2cd631 100644 --- a/util/testMock/mockCreator/creator_mock.go +++ b/util/testMock/mockCreator/creator_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/object/objectcreator (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mockCreator -destination creator_mock.go github.com/anyproto/anytype-heart/core/block/object/objectcreator Service +// // Package mockCreator is a generated GoMock package. package mockCreator @@ -50,7 +54,7 @@ func (m *MockService) CreateSet(arg0 *pb.RpcObjectCreateSetRequest) (string, *ty } // CreateSet indicates an expected call of CreateSet. -func (mr *MockServiceMockRecorder) CreateSet(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) CreateSet(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSet", reflect.TypeOf((*MockService)(nil).CreateSet), arg0) } @@ -66,7 +70,7 @@ func (m *MockService) CreateSmartBlockFromState(arg0 context.Context, arg1 smart } // CreateSmartBlockFromState indicates an expected call of CreateSmartBlockFromState. -func (mr *MockServiceMockRecorder) CreateSmartBlockFromState(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) CreateSmartBlockFromState(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSmartBlockFromState", reflect.TypeOf((*MockService)(nil).CreateSmartBlockFromState), arg0, arg1, arg2, arg3) } @@ -82,7 +86,7 @@ func (m *MockService) CreateSmartBlockFromTemplate(arg0 context.Context, arg1 sm } // CreateSmartBlockFromTemplate indicates an expected call of CreateSmartBlockFromTemplate. -func (mr *MockServiceMockRecorder) CreateSmartBlockFromTemplate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) CreateSmartBlockFromTemplate(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSmartBlockFromTemplate", reflect.TypeOf((*MockService)(nil).CreateSmartBlockFromTemplate), arg0, arg1, arg2, arg3) } @@ -98,7 +102,7 @@ func (m *MockService) CreateSubObjectInWorkspace(arg0 *types.Struct, arg1 string } // CreateSubObjectInWorkspace indicates an expected call of CreateSubObjectInWorkspace. -func (mr *MockServiceMockRecorder) CreateSubObjectInWorkspace(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) CreateSubObjectInWorkspace(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSubObjectInWorkspace", reflect.TypeOf((*MockService)(nil).CreateSubObjectInWorkspace), arg0, arg1) } @@ -114,7 +118,7 @@ func (m *MockService) CreateSubObjectsInWorkspace(arg0 []*types.Struct) ([]strin } // CreateSubObjectsInWorkspace indicates an expected call of CreateSubObjectsInWorkspace. -func (mr *MockServiceMockRecorder) CreateSubObjectsInWorkspace(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) CreateSubObjectsInWorkspace(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSubObjectsInWorkspace", reflect.TypeOf((*MockService)(nil).CreateSubObjectsInWorkspace), arg0) } @@ -128,7 +132,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } diff --git a/util/testMock/mockDetailsModifier/dm_mock.go b/util/testMock/mockDetailsModifier/dm_mock.go index 4e77b71ae..5fdd3758e 100644 --- a/util/testMock/mockDetailsModifier/dm_mock.go +++ b/util/testMock/mockDetailsModifier/dm_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/editor (interfaces: DetailsModifier) - +// +// Generated by this command: +// +// mockgen -package mockDetailsModifier -destination dm_mock.go github.com/anyproto/anytype-heart/core/block/editor DetailsModifier +// // Package mockDetailsModifier is a generated GoMock package. package mockDetailsModifier @@ -43,7 +47,7 @@ func (m *MockDetailsModifier) ModifyDetails(arg0 string, arg1 func(*types.Struct } // ModifyDetails indicates an expected call of ModifyDetails. -func (mr *MockDetailsModifierMockRecorder) ModifyDetails(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDetailsModifierMockRecorder) ModifyDetails(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDetails", reflect.TypeOf((*MockDetailsModifier)(nil).ModifyDetails), arg0, arg1) } @@ -57,7 +61,7 @@ func (m *MockDetailsModifier) ModifyLocalDetails(arg0 string, arg1 func(*types.S } // ModifyLocalDetails indicates an expected call of ModifyLocalDetails. -func (mr *MockDetailsModifierMockRecorder) ModifyLocalDetails(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDetailsModifierMockRecorder) ModifyLocalDetails(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyLocalDetails", reflect.TypeOf((*MockDetailsModifier)(nil).ModifyLocalDetails), arg0, arg1) } diff --git a/util/testMock/mockKanban/kanban_mock.go b/util/testMock/mockKanban/kanban_mock.go index 635c439f1..21c5a4f6c 100644 --- a/util/testMock/mockKanban/kanban_mock.go +++ b/util/testMock/mockKanban/kanban_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/kanban (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mockKanban -destination kanban_mock.go github.com/anyproto/anytype-heart/core/kanban Service +// // Package mockKanban is a generated GoMock package. package mockKanban @@ -45,7 +49,7 @@ func (m *MockService) Grouper(arg0 string) (kanban.Grouper, error) { } // Grouper indicates an expected call of Grouper. -func (mr *MockServiceMockRecorder) Grouper(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Grouper(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Grouper", reflect.TypeOf((*MockService)(nil).Grouper), arg0) } @@ -59,7 +63,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } diff --git a/util/testMock/mockRelation/relation_mock.go b/util/testMock/mockRelation/relation_mock.go index 7ad6aa462..5e392986e 100644 --- a/util/testMock/mockRelation/relation_mock.go +++ b/util/testMock/mockRelation/relation_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/relation (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mockRelation -destination relation_mock.go github.com/anyproto/anytype-heart/core/relation Service +// // Package mockRelation is a generated GoMock package. package mockRelation @@ -41,7 +45,7 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { // FetchKey mocks base method. func (m *MockService) FetchKey(arg0 string, arg1 ...relation.FetchOption) (*relationutils.Relation, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -52,16 +56,16 @@ func (m *MockService) FetchKey(arg0 string, arg1 ...relation.FetchOption) (*rela } // FetchKey indicates an expected call of FetchKey. -func (mr *MockServiceMockRecorder) FetchKey(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FetchKey(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchKey", reflect.TypeOf((*MockService)(nil).FetchKey), varargs...) } // FetchKeys mocks base method. func (m *MockService) FetchKeys(arg0 ...string) (relationutils.Relations, error) { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -72,7 +76,7 @@ func (m *MockService) FetchKeys(arg0 ...string) (relationutils.Relations, error) } // FetchKeys indicates an expected call of FetchKeys. -func (mr *MockServiceMockRecorder) FetchKeys(arg0 ...interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FetchKeys(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchKeys", reflect.TypeOf((*MockService)(nil).FetchKeys), arg0...) } @@ -87,7 +91,7 @@ func (m *MockService) FetchLinks(arg0 pbtypes.RelationLinks) (relationutils.Rela } // FetchLinks indicates an expected call of FetchLinks. -func (mr *MockServiceMockRecorder) FetchLinks(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) FetchLinks(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchLinks", reflect.TypeOf((*MockService)(nil).FetchLinks), arg0) } @@ -101,7 +105,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -109,7 +113,7 @@ func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { // ListAll mocks base method. func (m *MockService) ListAll(arg0 ...relation.FetchOption) (relationutils.Relations, error) { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -120,7 +124,7 @@ func (m *MockService) ListAll(arg0 ...relation.FetchOption) (relationutils.Relat } // ListAll indicates an expected call of ListAll. -func (mr *MockServiceMockRecorder) ListAll(arg0 ...interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) ListAll(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAll", reflect.TypeOf((*MockService)(nil).ListAll), arg0...) } @@ -148,7 +152,7 @@ func (m *MockService) ValidateFormat(arg0 string, arg1 *types.Value) error { } // ValidateFormat indicates an expected call of ValidateFormat. -func (mr *MockServiceMockRecorder) ValidateFormat(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) ValidateFormat(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateFormat", reflect.TypeOf((*MockService)(nil).ValidateFormat), arg0, arg1) } diff --git a/util/testMock/mockSource/source_mock.go b/util/testMock/mockSource/source_mock.go index 38c0c5afe..9514248bf 100644 --- a/util/testMock/mockSource/source_mock.go +++ b/util/testMock/mockSource/source_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/block/source (interfaces: Service,Source) - +// +// Generated by this command: +// +// mockgen -package mockSource -destination source_mock.go github.com/anyproto/anytype-heart/core/block/source Service,Source +// // Package mockSource is a generated GoMock package. package mockSource @@ -51,7 +55,7 @@ func (m *MockService) DetailsFromIdBasedSource(arg0 string) (*types.Struct, erro } // DetailsFromIdBasedSource indicates an expected call of DetailsFromIdBasedSource. -func (mr *MockServiceMockRecorder) DetailsFromIdBasedSource(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DetailsFromIdBasedSource(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetailsFromIdBasedSource", reflect.TypeOf((*MockService)(nil).DetailsFromIdBasedSource), arg0) } @@ -66,7 +70,7 @@ func (m *MockService) IDsListerBySmartblockType(arg0 smartblock.SmartBlockType) } // IDsListerBySmartblockType indicates an expected call of IDsListerBySmartblockType. -func (mr *MockServiceMockRecorder) IDsListerBySmartblockType(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) IDsListerBySmartblockType(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDsListerBySmartblockType", reflect.TypeOf((*MockService)(nil).IDsListerBySmartblockType), arg0) } @@ -80,7 +84,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -109,7 +113,7 @@ func (m *MockService) NewSource(arg0 context.Context, arg1, arg2 string, arg3 so } // NewSource indicates an expected call of NewSource. -func (mr *MockServiceMockRecorder) NewSource(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) NewSource(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewSource", reflect.TypeOf((*MockService)(nil).NewSource), arg0, arg1, arg2, arg3) } @@ -123,7 +127,7 @@ func (m *MockService) NewStaticSource(arg0 string, arg1 model.SmartBlockType, ar } // NewStaticSource indicates an expected call of NewStaticSource. -func (mr *MockServiceMockRecorder) NewStaticSource(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) NewStaticSource(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStaticSource", reflect.TypeOf((*MockService)(nil).NewStaticSource), arg0, arg1, arg2, arg3) } @@ -135,7 +139,7 @@ func (m *MockService) RegisterStaticSource(arg0 string, arg1 source.Source) { } // RegisterStaticSource indicates an expected call of RegisterStaticSource. -func (mr *MockServiceMockRecorder) RegisterStaticSource(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) RegisterStaticSource(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterStaticSource", reflect.TypeOf((*MockService)(nil).RegisterStaticSource), arg0, arg1) } @@ -147,7 +151,7 @@ func (m *MockService) RemoveStaticSource(arg0 string) { } // RemoveStaticSource indicates an expected call of RemoveStaticSource. -func (mr *MockServiceMockRecorder) RemoveStaticSource(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) RemoveStaticSource(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveStaticSource", reflect.TypeOf((*MockService)(nil).RemoveStaticSource), arg0) } @@ -241,7 +245,7 @@ func (m *MockSource) PushChange(arg0 source.PushChangeParams) (string, error) { } // PushChange indicates an expected call of PushChange. -func (mr *MockSourceMockRecorder) PushChange(arg0 interface{}) *gomock.Call { +func (mr *MockSourceMockRecorder) PushChange(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushChange", reflect.TypeOf((*MockSource)(nil).PushChange), arg0) } @@ -256,7 +260,7 @@ func (m *MockSource) ReadDoc(arg0 context.Context, arg1 source.ChangeReceiver, a } // ReadDoc indicates an expected call of ReadDoc. -func (mr *MockSourceMockRecorder) ReadDoc(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSourceMockRecorder) ReadDoc(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDoc", reflect.TypeOf((*MockSource)(nil).ReadDoc), arg0, arg1, arg2) } diff --git a/util/testMock/mockSpace/space_mock.go b/util/testMock/mockSpace/space_mock.go index 54a394db5..00cfb74f9 100644 --- a/util/testMock/mockSpace/space_mock.go +++ b/util/testMock/mockSpace/space_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/space (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mockSpace -destination space_mock.go github.com/anyproto/anytype-heart/space Service +// // Package mockSpace is a generated GoMock package. package mockSpace @@ -62,7 +66,7 @@ func (m *MockService) AccountSpace(arg0 context.Context) (commonspace.Space, err } // AccountSpace indicates an expected call of AccountSpace. -func (mr *MockServiceMockRecorder) AccountSpace(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) AccountSpace(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountSpace", reflect.TypeOf((*MockService)(nil).AccountSpace), arg0) } @@ -76,7 +80,7 @@ func (m *MockService) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) } @@ -91,7 +95,7 @@ func (m *MockService) DeleteAccount(arg0 context.Context, arg1 bool) (space.Stat } // DeleteAccount indicates an expected call of DeleteAccount. -func (mr *MockServiceMockRecorder) DeleteAccount(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeleteAccount(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccount", reflect.TypeOf((*MockService)(nil).DeleteAccount), arg0, arg1) } @@ -106,7 +110,7 @@ func (m *MockService) DeleteSpace(arg0 context.Context, arg1 string, arg2 bool) } // DeleteSpace indicates an expected call of DeleteSpace. -func (mr *MockServiceMockRecorder) DeleteSpace(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeleteSpace(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSpace", reflect.TypeOf((*MockService)(nil).DeleteSpace), arg0, arg1, arg2) } @@ -121,7 +125,7 @@ func (m *MockService) DeriveSpace(arg0 context.Context, arg1 commonspace.SpaceDe } // DeriveSpace indicates an expected call of DeriveSpace. -func (mr *MockServiceMockRecorder) DeriveSpace(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) DeriveSpace(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeriveSpace", reflect.TypeOf((*MockService)(nil).DeriveSpace), arg0, arg1) } @@ -136,7 +140,7 @@ func (m *MockService) GetSpace(arg0 context.Context, arg1 string) (commonspace.S } // GetSpace indicates an expected call of GetSpace. -func (mr *MockServiceMockRecorder) GetSpace(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) GetSpace(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpace", reflect.TypeOf((*MockService)(nil).GetSpace), arg0, arg1) } @@ -150,7 +154,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -178,7 +182,7 @@ func (m *MockService) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) } diff --git a/util/testMock/mockStatus/status_mock.go b/util/testMock/mockStatus/status_mock.go index f26cd6983..55f722303 100644 --- a/util/testMock/mockStatus/status_mock.go +++ b/util/testMock/mockStatus/status_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/core/syncstatus (interfaces: Service) - +// +// Generated by this command: +// +// mockgen -package mockStatus -destination status_mock.go github.com/anyproto/anytype-heart/core/syncstatus Service +// // Package mockStatus is a generated GoMock package. package mockStatus @@ -44,7 +48,7 @@ func (m *MockService) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) } @@ -58,7 +62,7 @@ func (m *MockService) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) } @@ -86,7 +90,7 @@ func (m *MockService) OnFileUpload(arg0, arg1 string) error { } // OnFileUpload indicates an expected call of OnFileUpload. -func (mr *MockServiceMockRecorder) OnFileUpload(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) OnFileUpload(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnFileUpload", reflect.TypeOf((*MockService)(nil).OnFileUpload), arg0, arg1) } @@ -100,7 +104,7 @@ func (m *MockService) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) } @@ -112,7 +116,7 @@ func (m *MockService) Unwatch(arg0 string) { } // Unwatch indicates an expected call of Unwatch. -func (mr *MockServiceMockRecorder) Unwatch(arg0 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Unwatch(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unwatch", reflect.TypeOf((*MockService)(nil).Unwatch), arg0) } @@ -127,7 +131,7 @@ func (m *MockService) Watch(arg0 string, arg1 func() []string) (bool, error) { } // Watch indicates an expected call of Watch. -func (mr *MockServiceMockRecorder) Watch(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockServiceMockRecorder) Watch(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockService)(nil).Watch), arg0, arg1) } diff --git a/util/testMock/objectstore_mock.go b/util/testMock/objectstore_mock.go index a6e31dfd8..eb157563e 100644 --- a/util/testMock/objectstore_mock.go +++ b/util/testMock/objectstore_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore (interfaces: ObjectStore) - +// +// Generated by this command: +// +// mockgen -package testMock -destination objectstore_mock.go github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore ObjectStore +// // Package testMock is a generated GoMock package. package testMock @@ -51,7 +55,7 @@ func (m *MockObjectStore) AddToIndexQueue(arg0 string) error { } // AddToIndexQueue indicates an expected call of AddToIndexQueue. -func (mr *MockObjectStoreMockRecorder) AddToIndexQueue(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) AddToIndexQueue(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToIndexQueue", reflect.TypeOf((*MockObjectStore)(nil).AddToIndexQueue), arg0) } @@ -65,7 +69,7 @@ func (m *MockObjectStore) Close(arg0 context.Context) error { } // Close indicates an expected call of Close. -func (mr *MockObjectStoreMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockObjectStore)(nil).Close), arg0) } @@ -79,7 +83,7 @@ func (m *MockObjectStore) DeleteDetails(arg0 string) error { } // DeleteDetails indicates an expected call of DeleteDetails. -func (mr *MockObjectStoreMockRecorder) DeleteDetails(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) DeleteDetails(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDetails", reflect.TypeOf((*MockObjectStore)(nil).DeleteDetails), arg0) } @@ -93,7 +97,7 @@ func (m *MockObjectStore) DeleteObject(arg0 string) error { } // DeleteObject indicates an expected call of DeleteObject. -func (mr *MockObjectStoreMockRecorder) DeleteObject(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) DeleteObject(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObject", reflect.TypeOf((*MockObjectStore)(nil).DeleteObject), arg0) } @@ -151,7 +155,7 @@ func (m *MockObjectStore) GetAggregatedOptions(arg0 string) ([]*model.RelationOp } // GetAggregatedOptions indicates an expected call of GetAggregatedOptions. -func (mr *MockObjectStoreMockRecorder) GetAggregatedOptions(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetAggregatedOptions(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAggregatedOptions", reflect.TypeOf((*MockObjectStore)(nil).GetAggregatedOptions), arg0) } @@ -159,7 +163,7 @@ func (mr *MockObjectStoreMockRecorder) GetAggregatedOptions(arg0 interface{}) *g // GetByIDs mocks base method. func (m *MockObjectStore) GetByIDs(arg0 ...string) ([]*model.ObjectInfo, error) { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -170,7 +174,7 @@ func (m *MockObjectStore) GetByIDs(arg0 ...string) ([]*model.ObjectInfo, error) } // GetByIDs indicates an expected call of GetByIDs. -func (mr *MockObjectStoreMockRecorder) GetByIDs(arg0 ...interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetByIDs(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockObjectStore)(nil).GetByIDs), arg0...) } @@ -215,7 +219,7 @@ func (m *MockObjectStore) GetDetails(arg0 string) (*model.ObjectDetails, error) } // GetDetails indicates an expected call of GetDetails. -func (mr *MockObjectStoreMockRecorder) GetDetails(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetDetails(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDetails", reflect.TypeOf((*MockObjectStore)(nil).GetDetails), arg0) } @@ -230,7 +234,7 @@ func (m *MockObjectStore) GetInboundLinksByID(arg0 string) ([]string, error) { } // GetInboundLinksByID indicates an expected call of GetInboundLinksByID. -func (mr *MockObjectStoreMockRecorder) GetInboundLinksByID(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetInboundLinksByID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInboundLinksByID", reflect.TypeOf((*MockObjectStore)(nil).GetInboundLinksByID), arg0) } @@ -245,7 +249,7 @@ func (m *MockObjectStore) GetLastIndexedHeadsHash(arg0 string) (string, error) { } // GetLastIndexedHeadsHash indicates an expected call of GetLastIndexedHeadsHash. -func (mr *MockObjectStoreMockRecorder) GetLastIndexedHeadsHash(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetLastIndexedHeadsHash(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).GetLastIndexedHeadsHash), arg0) } @@ -260,7 +264,7 @@ func (m *MockObjectStore) GetObjectType(arg0 string) (*model.ObjectType, error) } // GetObjectType indicates an expected call of GetObjectType. -func (mr *MockObjectStoreMockRecorder) GetObjectType(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetObjectType(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectType", reflect.TypeOf((*MockObjectStore)(nil).GetObjectType), arg0) } @@ -275,7 +279,7 @@ func (m *MockObjectStore) GetObjectTypes(arg0 []string) ([]*model.ObjectType, er } // GetObjectTypes indicates an expected call of GetObjectTypes. -func (mr *MockObjectStoreMockRecorder) GetObjectTypes(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetObjectTypes(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTypes", reflect.TypeOf((*MockObjectStore)(nil).GetObjectTypes), arg0) } @@ -290,7 +294,7 @@ func (m *MockObjectStore) GetOutboundLinksByID(arg0 string) ([]string, error) { } // GetOutboundLinksByID indicates an expected call of GetOutboundLinksByID. -func (mr *MockObjectStoreMockRecorder) GetOutboundLinksByID(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetOutboundLinksByID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOutboundLinksByID", reflect.TypeOf((*MockObjectStore)(nil).GetOutboundLinksByID), arg0) } @@ -305,7 +309,7 @@ func (m *MockObjectStore) GetRelationByID(arg0 string) (*model.Relation, error) } // GetRelationByID indicates an expected call of GetRelationByID. -func (mr *MockObjectStoreMockRecorder) GetRelationByID(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetRelationByID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByID", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByID), arg0) } @@ -320,7 +324,7 @@ func (m *MockObjectStore) GetRelationByKey(arg0 string) (*model.Relation, error) } // GetRelationByKey indicates an expected call of GetRelationByKey. -func (mr *MockObjectStoreMockRecorder) GetRelationByKey(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetRelationByKey(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByKey), arg0) } @@ -335,7 +339,7 @@ func (m *MockObjectStore) GetWithLinksInfoByID(arg0 string) (*model.ObjectInfoWi } // GetWithLinksInfoByID indicates an expected call of GetWithLinksInfoByID. -func (mr *MockObjectStoreMockRecorder) GetWithLinksInfoByID(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetWithLinksInfoByID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWithLinksInfoByID", reflect.TypeOf((*MockObjectStore)(nil).GetWithLinksInfoByID), arg0) } @@ -343,7 +347,7 @@ func (mr *MockObjectStoreMockRecorder) GetWithLinksInfoByID(arg0 interface{}) *g // HasIDs mocks base method. func (m *MockObjectStore) HasIDs(arg0 ...string) ([]string, error) { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -354,7 +358,7 @@ func (m *MockObjectStore) HasIDs(arg0 ...string) ([]string, error) { } // HasIDs indicates an expected call of HasIDs. -func (mr *MockObjectStoreMockRecorder) HasIDs(arg0 ...interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) HasIDs(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasIDs", reflect.TypeOf((*MockObjectStore)(nil).HasIDs), arg0...) } @@ -369,7 +373,7 @@ func (m *MockObjectStore) HasObjectType(arg0 string) (bool, error) { } // HasObjectType indicates an expected call of HasObjectType. -func (mr *MockObjectStoreMockRecorder) HasObjectType(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) HasObjectType(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasObjectType", reflect.TypeOf((*MockObjectStore)(nil).HasObjectType), arg0) } @@ -383,7 +387,7 @@ func (m *MockObjectStore) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockObjectStoreMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockObjectStore)(nil).Init), arg0) } @@ -458,7 +462,7 @@ func (m *MockObjectStore) Query(arg0 schema.Schema, arg1 database.Query) ([]data } // Query indicates an expected call of Query. -func (mr *MockObjectStoreMockRecorder) Query(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) Query(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockObjectStore)(nil).Query), arg0, arg1) } @@ -473,7 +477,7 @@ func (m *MockObjectStore) QueryByID(arg0 []string) ([]database.Record, error) { } // QueryByID indicates an expected call of QueryByID. -func (mr *MockObjectStoreMockRecorder) QueryByID(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) QueryByID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryByID", reflect.TypeOf((*MockObjectStore)(nil).QueryByID), arg0) } @@ -489,7 +493,7 @@ func (m *MockObjectStore) QueryByIDAndSubscribeForChanges(arg0 []string, arg1 da } // QueryByIDAndSubscribeForChanges indicates an expected call of QueryByIDAndSubscribeForChanges. -func (mr *MockObjectStoreMockRecorder) QueryByIDAndSubscribeForChanges(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) QueryByIDAndSubscribeForChanges(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryByIDAndSubscribeForChanges", reflect.TypeOf((*MockObjectStore)(nil).QueryByIDAndSubscribeForChanges), arg0, arg1) } @@ -505,7 +509,7 @@ func (m *MockObjectStore) QueryObjectIDs(arg0 database.Query, arg1 []smartblock. } // QueryObjectIDs indicates an expected call of QueryObjectIDs. -func (mr *MockObjectStoreMockRecorder) QueryObjectIDs(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) QueryObjectIDs(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryObjectIDs", reflect.TypeOf((*MockObjectStore)(nil).QueryObjectIDs), arg0, arg1) } @@ -520,7 +524,7 @@ func (m *MockObjectStore) QueryRaw(arg0 *database.Filters, arg1, arg2 int) ([]da } // QueryRaw indicates an expected call of QueryRaw. -func (mr *MockObjectStoreMockRecorder) QueryRaw(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) QueryRaw(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryRaw", reflect.TypeOf((*MockObjectStore)(nil).QueryRaw), arg0, arg1, arg2) } @@ -546,7 +550,7 @@ func (m *MockObjectStore) RemoveIDsFromFullTextQueue(arg0 []string) { } // RemoveIDsFromFullTextQueue indicates an expected call of RemoveIDsFromFullTextQueue. -func (mr *MockObjectStoreMockRecorder) RemoveIDsFromFullTextQueue(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) RemoveIDsFromFullTextQueue(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveIDsFromFullTextQueue", reflect.TypeOf((*MockObjectStore)(nil).RemoveIDsFromFullTextQueue), arg0) } @@ -560,7 +564,7 @@ func (m *MockObjectStore) Run(arg0 context.Context) error { } // Run indicates an expected call of Run. -func (mr *MockObjectStoreMockRecorder) Run(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) Run(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockObjectStore)(nil).Run), arg0) } @@ -574,7 +578,7 @@ func (m *MockObjectStore) SaveAccountStatus(arg0 *coordinatorproto.SpaceStatusPa } // SaveAccountStatus indicates an expected call of SaveAccountStatus. -func (mr *MockObjectStoreMockRecorder) SaveAccountStatus(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) SaveAccountStatus(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveAccountStatus", reflect.TypeOf((*MockObjectStore)(nil).SaveAccountStatus), arg0) } @@ -588,7 +592,7 @@ func (m *MockObjectStore) SaveChecksums(arg0 *model.ObjectStoreChecksums) error } // SaveChecksums indicates an expected call of SaveChecksums. -func (mr *MockObjectStoreMockRecorder) SaveChecksums(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) SaveChecksums(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveChecksums", reflect.TypeOf((*MockObjectStore)(nil).SaveChecksums), arg0) } @@ -602,7 +606,7 @@ func (m *MockObjectStore) SaveLastIndexedHeadsHash(arg0, arg1 string) error { } // SaveLastIndexedHeadsHash indicates an expected call of SaveLastIndexedHeadsHash. -func (mr *MockObjectStoreMockRecorder) SaveLastIndexedHeadsHash(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) SaveLastIndexedHeadsHash(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).SaveLastIndexedHeadsHash), arg0, arg1) } @@ -616,7 +620,7 @@ func (m *MockObjectStore) SetCurrentWorkspaceID(arg0 string) error { } // SetCurrentWorkspaceID indicates an expected call of SetCurrentWorkspaceID. -func (mr *MockObjectStoreMockRecorder) SetCurrentWorkspaceID(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) SetCurrentWorkspaceID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentWorkspaceID", reflect.TypeOf((*MockObjectStore)(nil).SetCurrentWorkspaceID), arg0) } @@ -628,7 +632,7 @@ func (m *MockObjectStore) SubscribeForAll(arg0 func(database.Record)) { } // SubscribeForAll indicates an expected call of SubscribeForAll. -func (mr *MockObjectStoreMockRecorder) SubscribeForAll(arg0 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) SubscribeForAll(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeForAll", reflect.TypeOf((*MockObjectStore)(nil).SubscribeForAll), arg0) } @@ -642,7 +646,7 @@ func (m *MockObjectStore) UpdateObjectDetails(arg0 string, arg1 *types.Struct) e } // UpdateObjectDetails indicates an expected call of UpdateObjectDetails. -func (mr *MockObjectStoreMockRecorder) UpdateObjectDetails(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) UpdateObjectDetails(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectDetails", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectDetails), arg0, arg1) } @@ -656,7 +660,7 @@ func (m *MockObjectStore) UpdateObjectLinks(arg0 string, arg1 []string) error { } // UpdateObjectLinks indicates an expected call of UpdateObjectLinks. -func (mr *MockObjectStoreMockRecorder) UpdateObjectLinks(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) UpdateObjectLinks(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectLinks", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectLinks), arg0, arg1) } @@ -670,7 +674,7 @@ func (m *MockObjectStore) UpdateObjectSnippet(arg0, arg1 string) error { } // UpdateObjectSnippet indicates an expected call of UpdateObjectSnippet. -func (mr *MockObjectStoreMockRecorder) UpdateObjectSnippet(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) UpdateObjectSnippet(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectSnippet", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectSnippet), arg0, arg1) } @@ -684,7 +688,7 @@ func (m *MockObjectStore) UpdatePendingLocalDetails(arg0 string, arg1 func(*type } // UpdatePendingLocalDetails indicates an expected call of UpdatePendingLocalDetails. -func (mr *MockObjectStoreMockRecorder) UpdatePendingLocalDetails(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) UpdatePendingLocalDetails(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePendingLocalDetails", reflect.TypeOf((*MockObjectStore)(nil).UpdatePendingLocalDetails), arg0, arg1) } diff --git a/util/testMock/sbt_provider_mock.go b/util/testMock/sbt_provider_mock.go index f8d3b4e72..32aec2c3c 100644 --- a/util/testMock/sbt_provider_mock.go +++ b/util/testMock/sbt_provider_mock.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/anyproto/anytype-heart/space/typeprovider (interfaces: SmartBlockTypeProvider) - +// +// Generated by this command: +// +// mockgen -package testMock -destination sbt_provider_mock.go github.com/anyproto/anytype-heart/space/typeprovider SmartBlockTypeProvider +// // Package testMock is a generated GoMock package. package testMock @@ -44,7 +48,7 @@ func (m *MockSmartBlockTypeProvider) Init(arg0 *app.App) error { } // Init indicates an expected call of Init. -func (mr *MockSmartBlockTypeProviderMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockSmartBlockTypeProviderMockRecorder) Init(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Init), arg0) } @@ -70,7 +74,7 @@ func (m *MockSmartBlockTypeProvider) RegisterStaticType(arg0 string, arg1 smartb } // RegisterStaticType indicates an expected call of RegisterStaticType. -func (mr *MockSmartBlockTypeProviderMockRecorder) RegisterStaticType(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSmartBlockTypeProviderMockRecorder) RegisterStaticType(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterStaticType", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).RegisterStaticType), arg0, arg1) } @@ -85,7 +89,7 @@ func (m *MockSmartBlockTypeProvider) Type(arg0 string) (smartblock.SmartBlockTyp } // Type indicates an expected call of Type. -func (mr *MockSmartBlockTypeProviderMockRecorder) Type(arg0 interface{}) *gomock.Call { +func (mr *MockSmartBlockTypeProviderMockRecorder) Type(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Type), arg0) } From 3e7b7c1481d23023acd0c492487ddf68d2aaa16f Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 28 Sep 2023 16:04:54 +0500 Subject: [PATCH 06/22] GO-2130: Fix GCI --- core/block/editor/file/block_service_mock_test.go | 3 ++- core/block/import/mock.go | 5 +++-- core/filestorage/filesync/filestore_mock.go | 3 ++- core/filestorage/filesync/filesync_test.go | 2 +- core/filestorage/filesync/mock_filesync/filesync_mock.go | 3 ++- core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go | 3 ++- pkg/lib/core/mock_core/service_mock.go | 3 ++- space/mock_space/service_mock.go | 3 ++- util/testMock/anytype_mock.go | 3 ++- util/testMock/file_service_mock.go | 5 +++-- util/testMock/history_mock.go | 3 ++- util/testMock/mockCreator/creator_mock.go | 5 +++-- util/testMock/mockKanban/kanban_mock.go | 3 ++- util/testMock/mockRelation/relation_mock.go | 5 +++-- util/testMock/mockSource/source_mock.go | 5 +++-- util/testMock/mockSpace/space_mock.go | 3 ++- util/testMock/objectstore_mock.go | 5 +++-- util/testMock/sbt_provider_mock.go | 3 ++- 18 files changed, 41 insertions(+), 24 deletions(-) diff --git a/core/block/editor/file/block_service_mock_test.go b/core/block/editor/file/block_service_mock_test.go index 96004c3d4..07aecd6ea 100644 --- a/core/block/editor/file/block_service_mock_test.go +++ b/core/block/editor/file/block_service_mock_test.go @@ -11,12 +11,13 @@ package file_test import ( reflect "reflect" + gomock "go.uber.org/mock/gomock" + file "github.com/anyproto/anytype-heart/core/block/editor/file" smartblock "github.com/anyproto/anytype-heart/core/block/editor/smartblock" process "github.com/anyproto/anytype-heart/core/block/process" session "github.com/anyproto/anytype-heart/core/session" pb "github.com/anyproto/anytype-heart/pb" - gomock "go.uber.org/mock/gomock" ) // MockBlockService is a mock of BlockService interface. diff --git a/core/block/import/mock.go b/core/block/import/mock.go index b830d29ac..627eb7aed 100644 --- a/core/block/import/mock.go +++ b/core/block/import/mock.go @@ -13,10 +13,11 @@ import ( time "time" treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" - converter "github.com/anyproto/anytype-heart/core/block/import/converter" - session "github.com/anyproto/anytype-heart/core/session" types "github.com/gogo/protobuf/types" gomock "go.uber.org/mock/gomock" + + converter "github.com/anyproto/anytype-heart/core/block/import/converter" + session "github.com/anyproto/anytype-heart/core/session" ) // MockCreator is a mock of Creator interface. diff --git a/core/filestorage/filesync/filestore_mock.go b/core/filestorage/filesync/filestore_mock.go index 61235181c..831d9dff1 100644 --- a/core/filestorage/filesync/filestore_mock.go +++ b/core/filestorage/filesync/filestore_mock.go @@ -13,10 +13,11 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + gomock "go.uber.org/mock/gomock" + localstore "github.com/anyproto/anytype-heart/pkg/lib/localstore" filestore "github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore" storage "github.com/anyproto/anytype-heart/pkg/lib/pb/storage" - gomock "go.uber.org/mock/gomock" ) // MockFileStore is a mock of FileStore interface. diff --git a/core/filestorage/filesync/filesync_test.go b/core/filestorage/filesync/filesync_test.go index fb95d199a..0c9030024 100644 --- a/core/filestorage/filesync/filesync_test.go +++ b/core/filestorage/filesync/filesync_test.go @@ -22,6 +22,7 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/samber/lo" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -32,7 +33,6 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore" "github.com/anyproto/anytype-heart/pkg/lib/pb/storage" "github.com/anyproto/anytype-heart/space/mock_space" - "github.com/stretchr/testify/mock" ) var ctx = context.Background() diff --git a/core/filestorage/filesync/mock_filesync/filesync_mock.go b/core/filestorage/filesync/mock_filesync/filesync_mock.go index b53843936..65caa5ac9 100644 --- a/core/filestorage/filesync/mock_filesync/filesync_mock.go +++ b/core/filestorage/filesync/mock_filesync/filesync_mock.go @@ -14,9 +14,10 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" - filesync "github.com/anyproto/anytype-heart/core/filestorage/filesync" format "github.com/ipfs/go-ipld-format" gomock "go.uber.org/mock/gomock" + + filesync "github.com/anyproto/anytype-heart/core/filestorage/filesync" ) // MockFileSync is a mock of FileSync interface. diff --git a/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go b/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go index 492224cd7..6240c53b0 100644 --- a/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go +++ b/core/filestorage/rpcstore/mock_rpcstore/mock_rpcstore.go @@ -14,10 +14,11 @@ import ( app "github.com/anyproto/any-sync/app" fileproto "github.com/anyproto/any-sync/commonfile/fileproto" - rpcstore "github.com/anyproto/anytype-heart/core/filestorage/rpcstore" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" gomock "go.uber.org/mock/gomock" + + rpcstore "github.com/anyproto/anytype-heart/core/filestorage/rpcstore" ) // MockService is a mock of Service interface. diff --git a/pkg/lib/core/mock_core/service_mock.go b/pkg/lib/core/mock_core/service_mock.go index 3ffcdadb1..258b44f04 100644 --- a/pkg/lib/core/mock_core/service_mock.go +++ b/pkg/lib/core/mock_core/service_mock.go @@ -13,9 +13,10 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + gomock "go.uber.org/mock/gomock" + core "github.com/anyproto/anytype-heart/pkg/lib/core" threads "github.com/anyproto/anytype-heart/pkg/lib/threads" - gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/space/mock_space/service_mock.go b/space/mock_space/service_mock.go index 565e74216..3091ee63f 100644 --- a/space/mock_space/service_mock.go +++ b/space/mock_space/service_mock.go @@ -15,8 +15,9 @@ import ( app "github.com/anyproto/any-sync/app" commonspace "github.com/anyproto/any-sync/commonspace" streampool "github.com/anyproto/any-sync/net/streampool" - space "github.com/anyproto/anytype-heart/space" gomock "go.uber.org/mock/gomock" + + space "github.com/anyproto/anytype-heart/space" ) // MockService is a mock of Service interface. diff --git a/util/testMock/anytype_mock.go b/util/testMock/anytype_mock.go index f020edf65..551d23700 100644 --- a/util/testMock/anytype_mock.go +++ b/util/testMock/anytype_mock.go @@ -13,9 +13,10 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + gomock "go.uber.org/mock/gomock" + core "github.com/anyproto/anytype-heart/pkg/lib/core" threads "github.com/anyproto/anytype-heart/pkg/lib/threads" - gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/util/testMock/file_service_mock.go b/util/testMock/file_service_mock.go index e02da5ca3..4827033d9 100644 --- a/util/testMock/file_service_mock.go +++ b/util/testMock/file_service_mock.go @@ -14,12 +14,13 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + types "github.com/gogo/protobuf/types" + gomock "go.uber.org/mock/gomock" + files "github.com/anyproto/anytype-heart/core/files" pb "github.com/anyproto/anytype-heart/pb" mill "github.com/anyproto/anytype-heart/pkg/lib/mill" storage "github.com/anyproto/anytype-heart/pkg/lib/pb/storage" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" ) // MockFileService is a mock of Service interface. diff --git a/util/testMock/history_mock.go b/util/testMock/history_mock.go index d89e05210..7fed7aa57 100644 --- a/util/testMock/history_mock.go +++ b/util/testMock/history_mock.go @@ -11,8 +11,9 @@ package testMock import ( reflect "reflect" - undo "github.com/anyproto/anytype-heart/core/block/undo" gomock "go.uber.org/mock/gomock" + + undo "github.com/anyproto/anytype-heart/core/block/undo" ) // MockHistory is a mock of History interface. diff --git a/util/testMock/mockCreator/creator_mock.go b/util/testMock/mockCreator/creator_mock.go index 5cc2cd631..e7a89b09a 100644 --- a/util/testMock/mockCreator/creator_mock.go +++ b/util/testMock/mockCreator/creator_mock.go @@ -13,11 +13,12 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + types "github.com/gogo/protobuf/types" + gomock "go.uber.org/mock/gomock" + state "github.com/anyproto/anytype-heart/core/block/editor/state" pb "github.com/anyproto/anytype-heart/pb" smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/util/testMock/mockKanban/kanban_mock.go b/util/testMock/mockKanban/kanban_mock.go index 21c5a4f6c..79a5c0463 100644 --- a/util/testMock/mockKanban/kanban_mock.go +++ b/util/testMock/mockKanban/kanban_mock.go @@ -12,8 +12,9 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" - kanban "github.com/anyproto/anytype-heart/core/kanban" gomock "go.uber.org/mock/gomock" + + kanban "github.com/anyproto/anytype-heart/core/kanban" ) // MockService is a mock of Service interface. diff --git a/util/testMock/mockRelation/relation_mock.go b/util/testMock/mockRelation/relation_mock.go index 5e392986e..9a6ced1ae 100644 --- a/util/testMock/mockRelation/relation_mock.go +++ b/util/testMock/mockRelation/relation_mock.go @@ -12,11 +12,12 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + types "github.com/gogo/protobuf/types" + gomock "go.uber.org/mock/gomock" + relation "github.com/anyproto/anytype-heart/core/relation" relationutils "github.com/anyproto/anytype-heart/core/relation/relationutils" pbtypes "github.com/anyproto/anytype-heart/util/pbtypes" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/util/testMock/mockSource/source_mock.go b/util/testMock/mockSource/source_mock.go index 9514248bf..15b4f51cb 100644 --- a/util/testMock/mockSource/source_mock.go +++ b/util/testMock/mockSource/source_mock.go @@ -13,13 +13,14 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" + types "github.com/gogo/protobuf/types" + gomock "go.uber.org/mock/gomock" + state "github.com/anyproto/anytype-heart/core/block/editor/state" source "github.com/anyproto/anytype-heart/core/block/source" pb "github.com/anyproto/anytype-heart/pb" smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/util/testMock/mockSpace/space_mock.go b/util/testMock/mockSpace/space_mock.go index 00cfb74f9..d82a1218c 100644 --- a/util/testMock/mockSpace/space_mock.go +++ b/util/testMock/mockSpace/space_mock.go @@ -15,8 +15,9 @@ import ( app "github.com/anyproto/any-sync/app" commonspace "github.com/anyproto/any-sync/commonspace" streampool "github.com/anyproto/any-sync/net/streampool" - space "github.com/anyproto/anytype-heart/space" gomock "go.uber.org/mock/gomock" + + space "github.com/anyproto/anytype-heart/space" ) // MockService is a mock of Service interface. diff --git a/util/testMock/objectstore_mock.go b/util/testMock/objectstore_mock.go index eb157563e..50864cf3c 100644 --- a/util/testMock/objectstore_mock.go +++ b/util/testMock/objectstore_mock.go @@ -14,13 +14,14 @@ import ( app "github.com/anyproto/any-sync/app" coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" + types "github.com/gogo/protobuf/types" + gomock "go.uber.org/mock/gomock" + smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" database "github.com/anyproto/anytype-heart/pkg/lib/database" ftsearch "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" schema "github.com/anyproto/anytype-heart/pkg/lib/schema" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" ) // MockObjectStore is a mock of ObjectStore interface. diff --git a/util/testMock/sbt_provider_mock.go b/util/testMock/sbt_provider_mock.go index 32aec2c3c..cc5856195 100644 --- a/util/testMock/sbt_provider_mock.go +++ b/util/testMock/sbt_provider_mock.go @@ -12,8 +12,9 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" - smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" gomock "go.uber.org/mock/gomock" + + smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" ) // MockSmartBlockTypeProvider is a mock of SmartBlockTypeProvider interface. From c4bfb7c21b06fd405ec297f0230253b475c04a47 Mon Sep 17 00:00:00 2001 From: Sergey Date: Fri, 29 Sep 2023 14:45:17 +0500 Subject: [PATCH 07/22] GO-2130: Don't walk the same nodes twice or more --- core/files/files.go | 12 +++----- core/files/images.go | 2 +- core/filestorage/filesync/filesync.go | 1 + .../filesync/mock_filesync/filesync_mock.go | 15 ++++++++++ core/filestorage/filesync/upload.go | 30 ++++++++++++------- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/core/files/files.go b/core/files/files.go index a33401829..b41d98d37 100644 --- a/core/files/files.go +++ b/core/files/files.go @@ -139,7 +139,7 @@ func (s *service) fileAdd(ctx context.Context, opts AddOptions) (string, *storag return "", nil, err } - err = s.storeFileSize(nodeHash, node) + err = s.storeFileSize(nodeHash) if err != nil { return "", nil, fmt.Errorf("store file size: %w", err) } @@ -147,13 +147,9 @@ func (s *service) fileAdd(ctx context.Context, opts AddOptions) (string, *storag return nodeHash, fileInfo, nil } -func (s *service) storeFileSize(hash string, node ipld.Node) error { - // Size method returns the size of the whole tree with root at `node` - size, err := node.Size() - if err != nil { - return fmt.Errorf("fetch node size: %w", err) - } - return s.fileStore.SetFileSize(hash, int(size)) +func (s *service) storeFileSize(hash string) error { + _, err := s.fileSync.CalculateFileSize(context.Background(), hash) + return err } // fileRestoreKeys restores file path=>key map from the IPFS DAG using the keys in the localStore diff --git a/core/files/images.go b/core/files/images.go index b322d682d..f62e138cd 100644 --- a/core/files/images.go +++ b/core/files/images.go @@ -115,7 +115,7 @@ func (s *service) imageAdd(ctx context.Context, opts AddOptions) (string, map[in } } - err = s.storeFileSize(nodeHash, node) + err = s.storeFileSize(nodeHash) if err != nil { return "", nil, fmt.Errorf("store file size: %w", err) } diff --git a/core/filestorage/filesync/filesync.go b/core/filestorage/filesync/filesync.go index 9b48e9bb3..98c753b32 100644 --- a/core/filestorage/filesync/filesync.go +++ b/core/filestorage/filesync/filesync.go @@ -45,6 +45,7 @@ type FileSync interface { DebugQueue(*http.Request) (*QueueInfo, error) SendImportEvents() ClearImportEvents() + CalculateFileSize(ctx context.Context, fileID string) (int, error) app.ComponentRunnable } diff --git a/core/filestorage/filesync/mock_filesync/filesync_mock.go b/core/filestorage/filesync/mock_filesync/filesync_mock.go index 65caa5ac9..1a69c2296 100644 --- a/core/filestorage/filesync/mock_filesync/filesync_mock.go +++ b/core/filestorage/filesync/mock_filesync/filesync_mock.go @@ -57,6 +57,21 @@ func (mr *MockFileSyncMockRecorder) AddFile(arg0, arg1, arg2, arg3 any) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFile", reflect.TypeOf((*MockFileSync)(nil).AddFile), arg0, arg1, arg2, arg3) } +// CalculateFileSize mocks base method. +func (m *MockFileSync) CalculateFileSize(arg0 context.Context, arg1 string) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CalculateFileSize", arg0, arg1) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CalculateFileSize indicates an expected call of CalculateFileSize. +func (mr *MockFileSyncMockRecorder) CalculateFileSize(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateFileSize", reflect.TypeOf((*MockFileSync)(nil).CalculateFileSize), arg0, arg1) +} + // ClearImportEvents mocks base method. func (m *MockFileSync) ClearImportEvents() { m.ctrl.T.Helper() diff --git a/core/filestorage/filesync/upload.go b/core/filestorage/filesync/upload.go index 11dcb6d0e..92817b7d9 100644 --- a/core/filestorage/filesync/upload.go +++ b/core/filestorage/filesync/upload.go @@ -154,7 +154,7 @@ func isLimitReachedErr(err error) bool { func (f *fileSync) uploadFile(ctx context.Context, spaceID string, fileID string) error { log.Debug("uploading file", zap.String("fileID", fileID)) - fileSize, err := f.calculateFileSize(ctx, fileID) + fileSize, err := f.CalculateFileSize(ctx, fileID) if err != nil { return fmt.Errorf("calculate file size: %w", err) } @@ -272,34 +272,42 @@ func (f *fileSync) selectBlocksToUploadAndBindExisting(ctx context.Context, spac return bytesToUpload, blocksToUpload, nil } -func (f *fileSync) walkDAG(ctx context.Context, fileID string, visit func(node ipld.NavigableNode) error) error { +func (f *fileSync) walkDAG(ctx context.Context, fileID string, visit func(node ipld.Node) error) error { fileCid, err := cid.Parse(fileID) if err != nil { return fmt.Errorf("parse CID %s: %w", fileID, err) } - node, err := f.dagService.Get(ctx, fileCid) + rootNode, err := f.dagService.Get(ctx, fileCid) if err != nil { return fmt.Errorf("get root node: %w", err) } - walker := ipld.NewWalker(ctx, ipld.NewNavigableIPLDNode(node, f.dagService)) - err = walker.Iterate(visit) + visited := map[cid.Cid]struct{}{} + walker := ipld.NewWalker(ctx, ipld.NewNavigableIPLDNode(rootNode, f.dagService)) + err = walker.Iterate(func(navNode ipld.NavigableNode) error { + node := navNode.GetIPLDNode() + if _, ok := visited[node.Cid()]; !ok { + visited[node.Cid()] = struct{}{} + return visit(node) + } + return nil + }) if errors.Is(err, ipld.EndOfDag) { err = nil } return err } -func (f *fileSync) calculateFileSize(ctx context.Context, fileID string) (int, error) { +// CalculateFileSize calculates or gets already calculated file size +func (f *fileSync) CalculateFileSize(ctx context.Context, fileID string) (int, error) { size, err := f.fileStore.GetFileSize(fileID) if err == nil { return size, nil } size = 0 - err = f.walkDAG(ctx, fileID, func(node ipld.NavigableNode) error { - raw := node.GetIPLDNode().RawData() - size += len(raw) + err = f.walkDAG(ctx, fileID, func(node ipld.Node) error { + size += len(node.RawData()) return nil }) if err != nil { @@ -317,8 +325,8 @@ const batchSize = 10 func (f *fileSync) walkFileBlocks(ctx context.Context, fileID string, proc func(fileBlocks []blocks.Block) error) error { blocksBuf := make([]blocks.Block, 0, batchSize) - err := f.walkDAG(ctx, fileID, func(node ipld.NavigableNode) error { - b, err := blocks.NewBlockWithCid(node.GetIPLDNode().RawData(), node.GetIPLDNode().Cid()) + err := f.walkDAG(ctx, fileID, func(node ipld.Node) error { + b, err := blocks.NewBlockWithCid(node.RawData(), node.Cid()) if err != nil { return err } From 9b3731b5d27f3cbf07115d6716b397f9018d56c9 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 13:08:27 +0500 Subject: [PATCH 08/22] Refactor sub-objects iterator --- core/block/editor/workspaces.go | 66 +++++++++++++++------------------ 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index ee534eec2..e3d6acf70 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -1,11 +1,20 @@ package editor import ( + "context" + "fmt" + + "github.com/gogo/protobuf/types" + "github.com/anyproto/anytype-heart/core/anytype/config" + "github.com/anyproto/anytype-heart/core/block/editor/basic" "github.com/anyproto/anytype-heart/core/block/editor/converter" + "github.com/anyproto/anytype-heart/core/block/editor/dataview" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/editor/stext" "github.com/anyproto/anytype-heart/core/block/editor/template" + "github.com/anyproto/anytype-heart/core/block/migration" "github.com/anyproto/anytype-heart/core/block/source" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/event" @@ -13,18 +22,11 @@ import ( "github.com/anyproto/anytype-heart/metrics" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core" + smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/typeprovider" "github.com/anyproto/anytype-heart/util/pbtypes" - "context" - "github.com/gogo/protobuf/types" - "github.com/anyproto/anytype-heart/core/block/migration" - "fmt" - smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/core/block/editor/stext" - "github.com/anyproto/anytype-heart/core/block/editor/basic" - "github.com/anyproto/anytype-heart/core/block/editor/dataview" ) type Workspaces struct { @@ -153,16 +155,15 @@ func (w *Workspaces) StateMigrations() migration.Migrations { func (w *Workspaces) migrateSubObjects(_ *state.State) { w.iterateAllSubObjects( - func(info smartblock.DocInfo) bool { + func(info smartblock.DocInfo) { uniqueKeyRaw := pbtypes.GetString(info.Details, bundle.RelationKeyUniqueKey.String()) id, err := w.migrateSubObject(context.Background(), uniqueKeyRaw, info.Details, info.Type) if err != nil { log.Errorf("failed to index subobject %s: %s", info.Id, err) log.With("objectID", id).Errorf("failed to migrate subobject: %v", err) - return true + } else { + log.With("objectId", id, "uniqueKey", uniqueKeyRaw).Warnf("migrated sub-object") } - log.With("objectId", id, "uniqueKey", uniqueKeyRaw).Warnf("migrated sub-object") - return true }, ) } @@ -215,43 +216,36 @@ func collectionKeyToTypeKey(collKey string) (domain.TypeKey, bool) { return "", false } -func (w *Workspaces) iterateAllSubObjects(proc func(smartblock.DocInfo) bool) { +func (w *Workspaces) iterateAllSubObjects(proc func(smartblock.DocInfo)) { st := w.NewState() - for _, coll := range objectTypeToCollection { - data := st.GetSubObjectCollection(coll) - if data == nil { - continue - } - tk, ok := collectionKeyToTypeKey(coll) - if !ok { - log.With("collection", coll).Errorf("subobject migration: collection is invalid") + for typeKey, coll := range objectTypeToCollection { + collection := st.GetSubObjectCollection(coll) + if collection == nil { continue } - for subId, d := range data.GetFields() { - if st, ok := d.Kind.(*types.Value_StructValue); !ok { - log.Errorf("got invalid value for %s.%s:%t", coll, subId, d.Kind) - continue - } else { - uk, err := w.getUniqueKey(coll, subId) + for subObjectId, subObjectStruct := range collection.GetFields() { + if v, ok := subObjectStruct.Kind.(*types.Value_StructValue); ok { + uk, err := w.getUniqueKey(coll, subObjectId) if err != nil { log.With("collection", coll).Errorf("subobject migration: failed to get uniqueKey: %s", err.Error()) continue } - d := st.StructValue - d.Fields[bundle.RelationKeyUniqueKey.String()] = pbtypes.String(uk.Marshal()) + details := v.StructValue + details.Fields[bundle.RelationKeyUniqueKey.String()] = pbtypes.String(uk.Marshal()) - if !proc(smartblock.DocInfo{ + proc(smartblock.DocInfo{ SpaceID: w.SpaceID(), Links: nil, FileHashes: nil, Heads: nil, - Type: tk, - Details: d, - }) { - return - } + Type: typeKey, + Details: details, + }) + } else { + log.Errorf("got invalid value for %s.%s:%t", coll, subObjectId, subObjectStruct.Kind) + continue } } } @@ -273,7 +267,7 @@ func (w *Workspaces) getUniqueKey(collection, key string) (domain.UniqueKey, err case bundle.TypeKeyRelationOption: sbt = smartblock2.SmartBlockTypeRelationOption default: - return nil, fmt.Errorf("unknown collection %s", collection) + return nil, fmt.Errorf("unknown type key %s", typeKey) } return domain.NewUniqueKey(sbt, key) From 496055f3380110ec3974b8fc986d6ba24c30a972 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 13:09:30 +0500 Subject: [PATCH 09/22] Debug: add build tag for security reasons --- core/debug/handler.go | 9 +++++++++ core/debug/handler_anydebug.go | 34 ++++++++++++++++++++++++++++++++++ core/debug/service.go | 21 +-------------------- docs/Debug.md | 5 ++++- 4 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 core/debug/handler.go create mode 100644 core/debug/handler_anydebug.go diff --git a/core/debug/handler.go b/core/debug/handler.go new file mode 100644 index 000000000..1a46e0e58 --- /dev/null +++ b/core/debug/handler.go @@ -0,0 +1,9 @@ +//go:build !anydebug + +package debug + +import "github.com/anyproto/any-sync/app" + +func (d *debug) initHandlers(a *app.App) { + // no-op +} diff --git a/core/debug/handler_anydebug.go b/core/debug/handler_anydebug.go new file mode 100644 index 000000000..7307be4a0 --- /dev/null +++ b/core/debug/handler_anydebug.go @@ -0,0 +1,34 @@ +//go:build anydebug + +package debug + +import ( + "os" + "github.com/go-chi/chi/v5" + "github.com/anyproto/any-sync/app" + "fmt" + "net/http" +) + +func (d *debug) initHandlers(a *app.App) { + if addr, ok := os.LookupEnv("ANYDEBUG"); ok && addr != "" { + r := chi.NewRouter() + a.IterateComponents(func(c app.Component) { + if d, ok := c.(Debuggable); ok { + fmt.Println("debug router registered for component: ", c.Name()) + r.Route("/debug/"+c.Name(), d.DebugRouter) + } + }) + routes := r.Routes() + r.Get("/debug", func(w http.ResponseWriter, req *http.Request) { + err := renderLinksList(w, "/", routes) + if err != nil { + logger.Error("failed to render links list", err) + } + }) + d.server = &http.Server{ + Addr: addr, + Handler: r, + } + } +} diff --git a/core/debug/service.go b/core/debug/service.go index 00e902984..a571c98cd 100644 --- a/core/debug/service.go +++ b/core/debug/service.go @@ -60,26 +60,7 @@ func (d *debug) Init(a *app.App) (err error) { d.block = a.MustComponent(block.CName).(*block.Service) d.spaceService = app.MustComponent[space.Service](a) - if addr, ok := os.LookupEnv("ANYDEBUG"); ok && addr != "" { - r := chi.NewRouter() - a.IterateComponents(func(c app.Component) { - if d, ok := c.(Debuggable); ok { - fmt.Println("debug router registered for component: ", c.Name()) - r.Route("/debug/"+c.Name(), d.DebugRouter) - } - }) - routes := r.Routes() - r.Get("/debug", func(w http.ResponseWriter, req *http.Request) { - err := renderLinksList(w, "/", routes) - if err != nil { - logger.Error("failed to render links list", err) - } - }) - d.server = &http.Server{ - Addr: addr, - Handler: r, - } - } + d.initHandlers(a) return nil } diff --git a/docs/Debug.md b/docs/Debug.md index 783f9ff5e..afc80f78a 100644 --- a/docs/Debug.md +++ b/docs/Debug.md @@ -14,6 +14,9 @@ If you want to change the default port(9999): ## Useful tools for debug ### Debug server + +Firstly, build anytype-heart with build tag `-anydebug` + Use env var ANYDEBUG=address to enable debugging HTTP server. For example: `ANYDEBUG=:6061` will start debug server on port 6061 You can find all endpoints in `/debug` page. For example: http://localhost:6061/debug @@ -86,4 +89,4 @@ echo '{"details": {"name": "hello there", "type": "ot-page"}}' | grpcurl -import - use `ANYTYPE_PROM=0.0.0.0:9094` when running middleware to enable metrics collection. Client commands metrics available only in gRPC mode - open http://127.0.0.1:3000 to view collected metrics in Grafana. You can find several dashboards there: - **MW** internal middleware metrics such as changes, added and created threads histograms - - **MW commands server** metrics for clients commands. Works only in grpc-server mode \ No newline at end of file + - **MW commands server** metrics for clients commands. Works only in grpc-server mode From 186df201993d782edd33f9b2d3138b40f20c42bd Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 13:09:49 +0500 Subject: [PATCH 10/22] Debug: add objects dump handler --- core/block/debug.go | 63 +++++++++++++++++++++++++++++ tests/blockbuilder/block_render.go | 65 ++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 core/block/debug.go create mode 100644 tests/blockbuilder/block_render.go diff --git a/core/block/debug.go b/core/block/debug.go new file mode 100644 index 000000000..88a71dbe9 --- /dev/null +++ b/core/block/debug.go @@ -0,0 +1,63 @@ +package block + +import ( + "github.com/anyproto/anytype-heart/util/debug" + "github.com/go-chi/chi/v5" + "net/http" + "github.com/anyproto/anytype-heart/tests/blockbuilder" + "fmt" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "encoding/json" + "github.com/gogo/protobuf/jsonpb" +) + +func (s *Service) DebugRouter(r chi.Router) { + r.Get("/objects", debug.JSONHandler(s.debugObjects)) +} + +type debugObject struct { + ID string + Details json.RawMessage + Store *json.RawMessage + Blocks *blockbuilder.Block +} + +func (s *Service) debugObjects(req *http.Request) ([]debugObject, error) { + ids, err := s.objectStore.ListIds() + if err != nil { + return nil, fmt.Errorf("list ids: %w", err) + } + result := make([]debugObject, 0, len(ids)) + marshaller := jsonpb.Marshaler{} + for _, id := range ids { + err = Do(s, id, func(sb smartblock.SmartBlock) error { + st := sb.NewState() + root := blockbuilder.BuildAST(st.Blocks()) + detailsRaw, err := marshaller.MarshalToString(st.CombinedDetails()) + if err != nil { + return fmt.Errorf("marshal details: %w", err) + } + + var storeRaw *json.RawMessage + if store := st.Store(); store != nil { + raw, err := marshaller.MarshalToString(st.Store()) + if err != nil { + return fmt.Errorf("marshal store: %w", err) + } + rawMessage := json.RawMessage(raw) + storeRaw = &rawMessage + } + result = append(result, debugObject{ + ID: id, + Store: storeRaw, + Details: json.RawMessage(detailsRaw), + Blocks: root, + }) + return nil + }) + if err != nil { + return nil, fmt.Errorf("can't get object %s: %w", id, err) + } + } + return result, nil +} diff --git a/tests/blockbuilder/block_render.go b/tests/blockbuilder/block_render.go new file mode 100644 index 000000000..6c3c27525 --- /dev/null +++ b/tests/blockbuilder/block_render.go @@ -0,0 +1,65 @@ +package blockbuilder + +import ( + "encoding/json" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/gogo/protobuf/jsonpb" + "fmt" + "github.com/gogo/protobuf/proto" +) + +type blockView struct { + Id string + Fields *json.RawMessage `json:"Fields,omitempty"` + Children []*Block `json:"Children,omitempty"` + Restrictions *model.BlockRestrictions `json:"Restrictions,omitempty"` + BackgroundColor string `json:"BackgroundColor,omitempty"` + Align model.BlockAlign `json:"Align,omitempty"` + VerticalAlign model.BlockVerticalAlign `json:"VerticalAlign,omitempty"` + Content *json.RawMessage `json:"Content"` +} + +func marshalProtoMessage(pbMessage proto.Message) (*json.RawMessage, error) { + marshaller := &jsonpb.Marshaler{} + raw, err := marshaller.MarshalToString(pbMessage) + if err != nil { + return nil, fmt.Errorf("marshal content: %w", err) + } + rawMessage := json.RawMessage(raw) + return &rawMessage, nil +} + +func (b *Block) MarshalJSON() ([]byte, error) { + var ( + err error + rawContent *json.RawMessage + ) + if content := b.block.Content; content != nil { + contentWrapper := &model.Block{ + Content: content, + } + rawContent, err = marshalProtoMessage(contentWrapper) + if err != nil { + return nil, fmt.Errorf("marshal content: %w", err) + } + } + var rawFields *json.RawMessage + if fields := b.block.Fields; fields != nil { + rawFields, err = marshalProtoMessage(b.block.Fields) + if err != nil { + return nil, fmt.Errorf("marshal fields: %w", err) + } + } + + v := blockView{ + Id: b.block.Id, + Fields: rawFields, + Children: b.children, + Restrictions: b.block.Restrictions, + BackgroundColor: b.block.BackgroundColor, + Align: b.block.Align, + VerticalAlign: b.block.VerticalAlign, + Content: rawContent, + } + return json.Marshal(v) +} From 23cb8f9527f72d4249f83185b7dafd4379cc5a07 Mon Sep 17 00:00:00 2001 From: kirillston Date: Mon, 2 Oct 2023 10:33:55 +0200 Subject: [PATCH 11/22] GO-2012 Allow set and collection as defaultType --- core/block/collection/service.go | 2 +- core/block/collection/service_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/block/collection/service.go b/core/block/collection/service.go index 4260626ab..cbeec9b2c 100644 --- a/core/block/collection/service.go +++ b/core/block/collection/service.go @@ -254,5 +254,5 @@ func setDefaultObjectTypeToViews(st *state.State) { } func isNotCreatableType(key bundle.TypeKey) bool { - return lo.Contains(append(bundle.InternalTypes, bundle.TypeKeyObjectType, bundle.TypeKeySet, bundle.TypeKeyCollection), key) + return lo.Contains(append(bundle.InternalTypes, bundle.TypeKeyObjectType), key) } diff --git a/core/block/collection/service_test.go b/core/block/collection/service_test.go index 94be33add..74f639a10 100644 --- a/core/block/collection/service_test.go +++ b/core/block/collection/service_test.go @@ -189,7 +189,7 @@ func TestSetObjectTypeToViews(t *testing.T) { t.Run("object is a set by not creatable type", func(t *testing.T) { // given - st := generateState(bundle.TypeKeySet.URL(), bundle.TypeKeyCollection.URL()) + st := generateState(bundle.TypeKeySet.URL(), bundle.TypeKeyObjectType.URL()) // when setDefaultObjectTypeToViews(st) From 7769d64500bd6b4c07dc098e7b052f36062a9477 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 13:46:27 +0500 Subject: [PATCH 12/22] Refactor: extract migration from Workspace --- core/block/editor/factory.go | 3 - core/block/editor/sub_objects_migration.go | 142 +++++++++++++++++++ core/block/editor/workspaces.go | 156 ++------------------- 3 files changed, 150 insertions(+), 151 deletions(-) diff --git a/core/block/editor/factory.go b/core/block/editor/factory.go index 9b1d8916c..b91f90842 100644 --- a/core/block/editor/factory.go +++ b/core/block/editor/factory.go @@ -38,7 +38,6 @@ type ObjectFactory struct { sbtProvider typeprovider.SmartBlockTypeProvider sourceService source.Service tempDirProvider core.TempDirProvider - templateCloner templateCloner fileService files.Service config *config.Config picker getblock.Picker @@ -61,7 +60,6 @@ func (f *ObjectFactory) Init(a *app.App) (err error) { f.systemObjectService = app.MustComponent[system_object.Service](a) f.restrictionService = app.MustComponent[restriction.Service](a) f.sourceService = app.MustComponent[source.Service](a) - f.templateCloner = app.MustComponent[templateCloner](a) f.fileService = app.MustComponent[files.Service](a) f.config = app.MustComponent[*config.Config](a) f.tempDirProvider = app.MustComponent[core.TempDirProvider](a) @@ -212,7 +210,6 @@ func (f *ObjectFactory) New(sbType coresb.SmartBlockType) (smartblock.SmartBlock f.detailsModifier, f.sbtProvider, f.layoutConverter, - f.templateCloner, f.config, f.eventSender, f.objectDeriver, diff --git a/core/block/editor/sub_objects_migration.go b/core/block/editor/sub_objects_migration.go index 323df60b3..439d69a54 100644 --- a/core/block/editor/sub_objects_migration.go +++ b/core/block/editor/sub_objects_migration.go @@ -1 +1,143 @@ package editor + +import ( + "github.com/anyproto/anytype-heart/core/domain" + "fmt" + smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/util/pbtypes" + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/gogo/protobuf/types" + "context" +) + +type objectDeriver interface { + DeriveTreeObjectWithUniqueKey(ctx context.Context, spaceID string, key domain.UniqueKey, initFunc smartblock.InitFunc) (sb smartblock.SmartBlock, err error) +} + +// Migrate legacy sub-objects to ordinary objects +type subObjectsMigration struct { + workspace *Workspaces + objectDeriver objectDeriver +} + +func (m *subObjectsMigration) migrateSubObjects(_ *state.State) { + m.iterateAllSubObjects( + func(info smartblock.DocInfo) { + uniqueKeyRaw := pbtypes.GetString(info.Details, bundle.RelationKeyUniqueKey.String()) + id, err := m.migrateSubObject(context.Background(), uniqueKeyRaw, info.Details, info.Type) + if err != nil { + log.Errorf("failed to index subobject %s: %s", info.Id, err) + log.With("objectID", id).Errorf("failed to migrate subobject: %v", err) + } else { + log.With("objectId", id, "uniqueKey", uniqueKeyRaw).Warnf("migrated sub-object") + } + }, + ) +} + +func (m *subObjectsMigration) migrateSubObject( + ctx context.Context, + uniqueKeyRaw string, + details *types.Struct, + typeKey domain.TypeKey, +) (id string, err error) { + uniqueKey, err := domain.UnmarshalUniqueKey(uniqueKeyRaw) + if err != nil { + return "", fmt.Errorf("unmarshal unique key: %w", err) + } + sb, err := m.objectDeriver.DeriveTreeObjectWithUniqueKey(ctx, m.workspace.SpaceID(), uniqueKey, func(id string) *smartblock.InitContext { + st := state.NewDocWithUniqueKey(id, nil, uniqueKey).NewState() + st.SetDetails(details) + st.SetObjectTypeKey(typeKey) + return &smartblock.InitContext{ + IsNewObject: true, + State: st, + SpaceID: m.workspace.SpaceID(), + } + }) + if err != nil { + return "", err + } + + return sb.Id(), nil +} + +const ( + collectionKeyRelationOptions = "opt" + collectionKeyRelations = "rel" + collectionKeyObjectTypes = "ot" +) + +var objectTypeToCollection = map[domain.TypeKey]string{ + bundle.TypeKeyObjectType: collectionKeyObjectTypes, + bundle.TypeKeyRelation: collectionKeyRelations, + bundle.TypeKeyRelationOption: collectionKeyRelationOptions, +} + +func collectionKeyToTypeKey(collKey string) (domain.TypeKey, bool) { + for ot, v := range objectTypeToCollection { + if v == collKey { + return ot, true + } + } + return "", false +} + +func (m *subObjectsMigration) iterateAllSubObjects(proc func(smartblock.DocInfo)) { + st := m.workspace.NewState() + for typeKey, coll := range objectTypeToCollection { + collection := st.GetSubObjectCollection(coll) + if collection == nil { + continue + } + + for subObjectId, subObjectStruct := range collection.GetFields() { + if v, ok := subObjectStruct.Kind.(*types.Value_StructValue); ok { + uk, err := m.getUniqueKey(coll, subObjectId) + if err != nil { + log.With("collection", coll).Errorf("subobject migration: failed to get uniqueKey: %s", err.Error()) + continue + } + + details := v.StructValue + details.Fields[bundle.RelationKeyUniqueKey.String()] = pbtypes.String(uk.Marshal()) + + proc(smartblock.DocInfo{ + SpaceID: m.workspace.SpaceID(), + Links: nil, + FileHashes: nil, + Heads: nil, + Type: typeKey, + Details: details, + }) + } else { + log.Errorf("got invalid value for %s.%s:%t", coll, subObjectId, subObjectStruct.Kind) + continue + } + } + } + return +} + +func (m *subObjectsMigration) getUniqueKey(collection, key string) (domain.UniqueKey, error) { + typeKey, ok := collectionKeyToTypeKey(collection) + if !ok { + return nil, fmt.Errorf("unknown collection %s", collection) + } + + var sbt smartblock2.SmartBlockType + switch typeKey { + case bundle.TypeKeyRelation: + sbt = smartblock2.SmartBlockTypeRelation + case bundle.TypeKeyObjectType: + sbt = smartblock2.SmartBlockTypeObjectType + case bundle.TypeKeyRelationOption: + sbt = smartblock2.SmartBlockTypeRelationOption + default: + return nil, fmt.Errorf("unknown type key %s", typeKey) + } + + return domain.NewUniqueKey(sbt, key) +} diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index e3d6acf70..88c4dee4a 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -1,11 +1,6 @@ package editor import ( - "context" - "fmt" - - "github.com/gogo/protobuf/types" - "github.com/anyproto/anytype-heart/core/anytype/config" "github.com/anyproto/anytype-heart/core/block/editor/basic" "github.com/anyproto/anytype-heart/core/block/editor/converter" @@ -22,7 +17,6 @@ import ( "github.com/anyproto/anytype-heart/metrics" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core" - smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/typeprovider" @@ -37,7 +31,6 @@ type Workspaces struct { stext.Text DetailsModifier DetailsModifier - templateCloner templateCloner sourceService source.Service anytype core.Service objectStore objectstore.ObjectStore @@ -54,7 +47,6 @@ func NewWorkspace( modifier DetailsModifier, sbtProvider typeprovider.SmartBlockTypeProvider, layoutConverter converter.LayoutConverter, - templateCloner templateCloner, config *config.Config, eventSender event.Sender, objectDeriver objectDeriver, @@ -79,16 +71,11 @@ func NewWorkspace( anytype: anytype, objectStore: objectStore, sourceService: sourceService, - templateCloner: templateCloner, config: config, objectDeriver: objectDeriver, } } -type objectDeriver interface { - DeriveTreeObjectWithUniqueKey(ctx context.Context, spaceID string, key domain.UniqueKey, initFunc smartblock.InitFunc) (sb smartblock.SmartBlock, err error) -} - func (w *Workspaces) Init(ctx *smartblock.InitContext) (err error) { err = w.SmartBlock.Init(ctx) if err != nil { @@ -121,19 +108,6 @@ func (w *Workspaces) initTemplate(ctx *smartblock.InitContext) { ) } -type templateCloner interface { - TemplateClone(spaceID string, id string) (templateID string, err error) -} - -type WorkspaceParameters struct { - IsHighlighted bool - WorkspaceId string -} - -func (wp *WorkspaceParameters) Equal(other *WorkspaceParameters) bool { - return wp.IsHighlighted == other.IsHighlighted -} - func (w *Workspaces) CreationStateMigration(ctx *smartblock.InitContext) migration.Migration { // TODO Maybe move init logic here? return migration.Migration{ @@ -148,127 +122,13 @@ func (w *Workspaces) StateMigrations() migration.Migrations { return migration.MakeMigrations([]migration.Migration{ { Version: 1, - Proc: w.migrateSubObjects, - }, - }) -} - -func (w *Workspaces) migrateSubObjects(_ *state.State) { - w.iterateAllSubObjects( - func(info smartblock.DocInfo) { - uniqueKeyRaw := pbtypes.GetString(info.Details, bundle.RelationKeyUniqueKey.String()) - id, err := w.migrateSubObject(context.Background(), uniqueKeyRaw, info.Details, info.Type) - if err != nil { - log.Errorf("failed to index subobject %s: %s", info.Id, err) - log.With("objectID", id).Errorf("failed to migrate subobject: %v", err) - } else { - log.With("objectId", id, "uniqueKey", uniqueKeyRaw).Warnf("migrated sub-object") - } - }, - ) -} - -func (w *Workspaces) migrateSubObject( - ctx context.Context, - uniqueKeyRaw string, - details *types.Struct, - typeKey domain.TypeKey, -) (id string, err error) { - uniqueKey, err := domain.UnmarshalUniqueKey(uniqueKeyRaw) - if err != nil { - return "", fmt.Errorf("unmarshal unique key: %w", err) - } - sb, err := w.objectDeriver.DeriveTreeObjectWithUniqueKey(ctx, w.SpaceID(), uniqueKey, func(id string) *smartblock.InitContext { - st := state.NewDocWithUniqueKey(id, nil, uniqueKey).NewState() - st.SetDetails(details) - st.SetObjectTypeKey(typeKey) - return &smartblock.InitContext{ - IsNewObject: true, - State: st, - SpaceID: w.SpaceID(), - } - }) - if err != nil { - return "", err - } - - return sb.Id(), nil -} - -const ( - collectionKeyRelationOptions = "opt" - collectionKeyRelations = "rel" - collectionKeyObjectTypes = "ot" -) - -var objectTypeToCollection = map[domain.TypeKey]string{ - bundle.TypeKeyObjectType: collectionKeyObjectTypes, - bundle.TypeKeyRelation: collectionKeyRelations, - bundle.TypeKeyRelationOption: collectionKeyRelationOptions, -} - -func collectionKeyToTypeKey(collKey string) (domain.TypeKey, bool) { - for ot, v := range objectTypeToCollection { - if v == collKey { - return ot, true - } - } - return "", false -} - -func (w *Workspaces) iterateAllSubObjects(proc func(smartblock.DocInfo)) { - st := w.NewState() - for typeKey, coll := range objectTypeToCollection { - collection := st.GetSubObjectCollection(coll) - if collection == nil { - continue - } - - for subObjectId, subObjectStruct := range collection.GetFields() { - if v, ok := subObjectStruct.Kind.(*types.Value_StructValue); ok { - uk, err := w.getUniqueKey(coll, subObjectId) - if err != nil { - log.With("collection", coll).Errorf("subobject migration: failed to get uniqueKey: %s", err.Error()) - continue + Proc: func(st *state.State) { + subObjectMigration := subObjectsMigration{ + workspace: w, + objectDeriver: w.objectDeriver, } - - details := v.StructValue - details.Fields[bundle.RelationKeyUniqueKey.String()] = pbtypes.String(uk.Marshal()) - - proc(smartblock.DocInfo{ - SpaceID: w.SpaceID(), - Links: nil, - FileHashes: nil, - Heads: nil, - Type: typeKey, - Details: details, - }) - } else { - log.Errorf("got invalid value for %s.%s:%t", coll, subObjectId, subObjectStruct.Kind) - continue - } - } - } - return -} - -func (w *Workspaces) getUniqueKey(collection, key string) (domain.UniqueKey, error) { - typeKey, ok := collectionKeyToTypeKey(collection) - if !ok { - return nil, fmt.Errorf("unknown collection %s", collection) - } - - var sbt smartblock2.SmartBlockType - switch typeKey { - case bundle.TypeKeyRelation: - sbt = smartblock2.SmartBlockTypeRelation - case bundle.TypeKeyObjectType: - sbt = smartblock2.SmartBlockTypeObjectType - case bundle.TypeKeyRelationOption: - sbt = smartblock2.SmartBlockTypeRelationOption - default: - return nil, fmt.Errorf("unknown type key %s", typeKey) - } - - return domain.NewUniqueKey(sbt, key) + subObjectMigration.migrateSubObjects(st) + }, + }, + }) } From e077f31189e9e7e922ba0e2dd051b858da80357d Mon Sep 17 00:00:00 2001 From: kirillston Date: Mon, 2 Oct 2023 10:55:30 +0200 Subject: [PATCH 13/22] GO-2012 Remove Source rel from diary set --- util/builtinobjects/data/notes_diary.zip | Bin 166521 -> 166519 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/util/builtinobjects/data/notes_diary.zip b/util/builtinobjects/data/notes_diary.zip index 8169447f0b16fb06d60daacb7a6a27736e5d7345..ad948ed5d1010ed5b9b9f6486a9ac56c51c241be 100644 GIT binary patch delta 152322 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

)Fk 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�UHAu8zD1naWYQ@y-E4w}My?B1q48ddHOH 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�VphduUQo19UX+rUjHH&=* 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 E07MxHF8}}l delta 152423 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

H=%6F}!`lvIY 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¬@Igt!DuKy_uje@0ZtEF!At?_{`Evaer_;&ln6O9c?&4V4Mu_}3)Q;87%AJI z35oK8B66Sz$QAq7vjpwB!5Ao;UFMr*0Dv6;KnwqRbRceb7&Y?s4gc4WhC7TDaRjn; zhcTj{-A#?Eh7#RjBxuEahzKs89MC%t7#ZcZD+RF@P(K#f;#Kt%p&54=4NB)@V-7b6 z(E~<;NhS8HptFl7H0l8(rgS&f%g_T_bOJ3vSN`?%K#BV04rb8&8(gfJ_-+16O6Nx-r4$^O;9)$ z)PA*JTcAx(pfIc>T*3yz_W}xkg|2(S=&v)C2p&s=4s`#g1Eb7;N%yw1v~q!x?!$;c z`bQWA4AC0O^n#I7Zs#rgyaBJIr@+Xr_Ffq@;su6mT~1Q@8I%+N>Z*iry}_{GJoWc3 z0!73@5#a9rdLBW_-Y_~8C=C`m0l9jEA}&zWWs%935$2a$15W=7?Zx}P> zYv@yP6#!TQ0GM-sJ;4x?4~&VD<8;@u7XWGj0QlFx9w$iJ2gXIso%`m)vq2F_P~_@Vx&w9lf({z^@WN#S0Nwz=RfA)O z5dDC~t=BT$8v}qU0Jz#gs*so;Q2U;*vH5oZxO_2R9Y_->5CD)@VrGY-SwEmuEY#=+ z)a<8}-5LD-n-pjt{DyM00%y7($fyG{t`1W=#O)87zExDuamn0r`4+pXW&vO~0&40n zM>>23fI|QPPW-Q@04n!~vE8&ZE)vfNfCv9nF;s|%;BMu}VQJ-I;cn*&b-2OEm>E-v zGTH##3Ba#9hN_bPz+Iew&zkklm(Owm^!7ixl|T*wz{4@H?YRHPk|Utv02l*xW^cRc zWf&DEn59>>wWvmfoT?GYp^E@uGqf^W+T{Re_K)afh&2$1erba&_Y%4r2s+mvvJQk@ zM~Tp55^05!z;BS88xbMbMnqDmEfC0(Sl{a^1+p}Ntg8d*0(}bv16je6)Ol&?r2s(k zR|g^>=s`DwU^gfawh}aF0N~OTu8y=h$_)nX3v6s+9R+~$f3(YkW`lut%KklTm!^LCqQBZhRS*bRWuhd@jvc&A ziWmm~S7%cPbPo<@6BTn?!YTla{3D?TO1qRWI}~*>1puD_;A$U#f+pcGu#rw?a@oo` z@OO}H<*(;(5fR#1M7#$1hJaI5W*WtTb;Lt(U(f70Xuz||Q=4rPSG zXqbN`9|LW_bj4QzM#sN3b~bnVHRY)P@o%5|Cr=HSXJBFW z*K-?E3xjc>{3mNi7??i|(33D2J!>4rb#8HVi_XM*;Ichj6un(pN&NLP)<0E1No8%78(hM zk;2f3pw(~~3)Lk*<}|2{4zz~uueKl{pprst5wKg7zZeJs0s>O64kHib8v$dc{=@GE z09WmcfeHrEQ^BtN>Nx5@Oj!VTwc}`LVGtcHj1r=V1fPt*7=|FONYFl31{lQ206us> zcmQwnhu;MVxH>{IP(mc^I^{3c44~@ee7*{hhDI&{e@FxX;Hp9KLj+O4pnk<-0|}R( zBv%`22PsDZoBcajmGnw~*+Owqu$#am{3pT>NVxh|Nri@^z+2@{92EduokY11Ry25( z{fa|@xTAsn1VZxBU>^Lr(hrJUZC5fB8x6Zo{r7ce@+(?JO2VK-Nf-sR91VK#&m~bH z=;~0lLj*A}R+Qg2@g!qF-9wOW40w(Hy6Xgb~hOI-pT7z+Lrs&!I=L zpu7HTp98?vNuLjm#)9vMKYNb=aMkY@LYNPL-~W5J=BgRgKq?Pl%&1M~KmmmR2OhWr Ai~s-t From e2559181ae066b5a7ada8de89c3ed8189b49db15 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 15:24:59 +0500 Subject: [PATCH 14/22] Refactor and fix migration --- core/block/debug.go | 14 ++-- .../editor/sub_object_links_migration.go | 73 +++++++++++-------- .../sub_object_links_migration_test.go} | 8 +- core/block/editor/sub_objects_migration.go | 18 +++-- core/block/simple/bookmark/bookmark.go | 9 +-- core/block/simple/dataview/dataview.go | 9 +-- core/block/simple/link/link.go | 9 +-- core/block/simple/simple.go | 2 +- core/block/simple/text/text.go | 9 +-- core/debug/handler_anydebug.go | 7 +- core/domain/uniquekey.go | 19 ----- tests/blockbuilder/block_render.go | 6 +- 12 files changed, 85 insertions(+), 98 deletions(-) rename core/{domain/uniquekey_test.go => block/editor/sub_object_links_migration_test.go} (87%) diff --git a/core/block/debug.go b/core/block/debug.go index 88a71dbe9..4ec4b3a45 100644 --- a/core/block/debug.go +++ b/core/block/debug.go @@ -1,14 +1,16 @@ package block import ( - "github.com/anyproto/anytype-heart/util/debug" - "github.com/go-chi/chi/v5" - "net/http" - "github.com/anyproto/anytype-heart/tests/blockbuilder" - "fmt" - "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "encoding/json" + "fmt" + "net/http" + + "github.com/go-chi/chi/v5" "github.com/gogo/protobuf/jsonpb" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/tests/blockbuilder" + "github.com/anyproto/anytype-heart/util/debug" ) func (s *Service) DebugRouter(r chi.Router) { diff --git a/core/block/editor/sub_object_links_migration.go b/core/block/editor/sub_object_links_migration.go index 8135a9934..a48e4fbc8 100644 --- a/core/block/editor/sub_object_links_migration.go +++ b/core/block/editor/sub_object_links_migration.go @@ -4,14 +4,17 @@ import ( "context" "fmt" + "github.com/globalsign/mgo/bson" + "github.com/anyproto/anytype-heart/core/block/editor/state" "github.com/anyproto/anytype-heart/core/block/simple" dataview2 "github.com/anyproto/anytype-heart/core/block/simple/dataview" + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/system_object" "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" - "github.com/anyproto/anytype-heart/core/domain" ) // Migrate old relation (rel-name, etc.) and object type (ot-page, etc.) IDs to new ones (just ordinary object IDs) @@ -28,22 +31,20 @@ func newSubObjectsLinksMigration(spaceID string, systemObjectService system_obje } } -// TODO Refactor func (m *subObjectsLinksMigration) replaceSubObjectLinksInDetails(s *state.State) { for _, rel := range s.GetRelationLinks() { - if rel.Format == model.RelationFormat_object || rel.Format == model.RelationFormat_tag || rel.Format == model.RelationFormat_status { - vals := pbtypes.GetStringList(s.Details(), rel.Key) + if m.canRelationContainObjectValues(rel.Format) { + ids := pbtypes.GetStringList(s.Details(), rel.Key) changed := false - for i := range vals { - newId, replaced := m.migrateSubObjectId(vals[i]) - if !replaced { - continue + for i, oldId := range ids { + newId := m.migrateSubObjectId(oldId) + if oldId != newId { + ids[i] = newId + changed = true } - vals[i] = newId - changed = true } if changed { - s.SetDetail(rel.Key, pbtypes.StringList(vals)) + s.SetDetail(rel.Key, pbtypes.StringList(ids)) } } } @@ -60,30 +61,45 @@ func (m *subObjectsLinksMigration) migrate(s *state.State) { m.migrateFilters(dv) } - if v, ok := block.(simple.ObjectLinkReplacer); ok { - // TODO Analyze this method (ReplaceSmartIds) - // TODO Looks like we should just map here: oldId OR newId - v.ReplaceSmartIds(m.migrateSubObjectId) + if _, ok := block.(simple.ObjectLinkReplacer); ok { + // Mark block as mutable + b := s.Get(block.Model().Id) + replacer := b.(simple.ObjectLinkReplacer) + replacer.ReplaceLinkIds(m.migrateSubObjectId) } return true }) } -func (m *subObjectsLinksMigration) migrateSubObjectId(id string) (newID string, migrated bool) { - // this should be replaced by the persisted state migration - // TODO Smells like SubObjectIdToUniqueKey should be here in-place, not in domain package! - uk, valid := domain.SubObjectIdToUniqueKey(id) +func (m *subObjectsLinksMigration) migrateSubObjectId(oldId string) (newId string) { + uniqueKey, valid := subObjectIdToUniqueKey(oldId) if !valid { - return "", false + return oldId } - newID, err := m.systemObjectService.GetObjectIdByUniqueKey(context.Background(), m.spaceID, uk) + newId, err := m.systemObjectService.GetObjectIdByUniqueKey(context.Background(), m.spaceID, uniqueKey) if err != nil { - log.With("uk", uk.Marshal()).Errorf("failed to derive id: %s", err.Error()) - return "", false + log.With("uniqueKey", uniqueKey.Marshal()).Errorf("failed to derive id: %s", err) + return oldId } - return newID, true + return newId +} + +// subObjectIdToUniqueKey converts legacy sub-object id to uniqueKey +// if id is not supported subObjectId, it will return nil, false +// suppose to be used only for migration and almost free to use +func subObjectIdToUniqueKey(id string) (uniqueKey domain.UniqueKey, valid bool) { + // historically, we don't have the prefix for the options, + // so we need to handled it this ugly way + if bson.IsObjectIdHex(id) { + return domain.MustUniqueKey(smartblock.SmartBlockTypeRelationOption, id), true + } + uniqueKey, err := domain.UnmarshalUniqueKey(id) + if err != nil { + return nil, false + } + return uniqueKey, true } func (m *subObjectsLinksMigration) migrateFilters(dv dataview2.Block) { @@ -103,7 +119,7 @@ func (m *subObjectsLinksMigration) migrateFilter(filter *model.BlockContentDatav return fmt.Errorf("failed to get relation by key %s: %w", filter.RelationKey, err) } - if m.canRelationContainObjectValues(relation) { + if m.canRelationContainObjectValues(relation.Format) { if oldID := filter.Value.GetStringValue(); oldID != "" { newID, err := m.migrateID(oldID) if err != nil { @@ -163,13 +179,12 @@ func (m *subObjectsLinksMigration) migrateID(id string) (string, error) { return id, nil } -func (m *subObjectsLinksMigration) canRelationContainObjectValues(relation *model.Relation) bool { - switch relation.Format { +func (m *subObjectsLinksMigration) canRelationContainObjectValues(format model.RelationFormat) bool { + switch format { case model.RelationFormat_status, model.RelationFormat_tag, - model.RelationFormat_object, - model.RelationFormat_relations: + model.RelationFormat_object: return true default: return false diff --git a/core/domain/uniquekey_test.go b/core/block/editor/sub_object_links_migration_test.go similarity index 87% rename from core/domain/uniquekey_test.go rename to core/block/editor/sub_object_links_migration_test.go index 27059a964..19bbd2952 100644 --- a/core/domain/uniquekey_test.go +++ b/core/block/editor/sub_object_links_migration_test.go @@ -1,7 +1,9 @@ -package domain +package editor import ( "testing" + + "github.com/anyproto/anytype-heart/core/domain" ) func TestSubObjectIdToUniqueKey(t *testing.T) { @@ -25,7 +27,7 @@ func TestSubObjectIdToUniqueKey(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotUk, gotValid := SubObjectIdToUniqueKey(tt.args.id) + gotUk, gotValid := subObjectIdToUniqueKey(tt.args.id) if gotValid != tt.wantValid { t.Errorf("SubObjectIdToUniqueKey() gotValid = %v, want %v", gotValid, tt.wantValid) t.Fail() @@ -35,7 +37,7 @@ func TestSubObjectIdToUniqueKey(t *testing.T) { return } - wantUk, err := UnmarshalUniqueKey(tt.wantUk) + wantUk, err := domain.UnmarshalUniqueKey(tt.wantUk) if err != nil { t.Errorf("SubObjectIdToUniqueKey() error = %v", err) t.Fail() diff --git a/core/block/editor/sub_objects_migration.go b/core/block/editor/sub_objects_migration.go index 439d69a54..8122baf6a 100644 --- a/core/block/editor/sub_objects_migration.go +++ b/core/block/editor/sub_objects_migration.go @@ -1,15 +1,17 @@ package editor import ( - "github.com/anyproto/anytype-heart/core/domain" - "fmt" - smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/core/block/editor/smartblock" - "github.com/anyproto/anytype-heart/util/pbtypes" - "github.com/anyproto/anytype-heart/core/block/editor/state" - "github.com/gogo/protobuf/types" "context" + "fmt" + + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + "github.com/anyproto/anytype-heart/util/pbtypes" ) type objectDeriver interface { diff --git a/core/block/simple/bookmark/bookmark.go b/core/block/simple/bookmark/bookmark.go index cf099e410..503b9ab44 100644 --- a/core/block/simple/bookmark/bookmark.go +++ b/core/block/simple/bookmark/bookmark.go @@ -176,15 +176,10 @@ func (b *Bookmark) FillFileHashes(hashes []string) []string { return hashes } -func (l *Bookmark) ReplaceSmartIds(f func(id string) (newId string, replaced bool)) (anyReplaced bool) { +func (l *Bookmark) ReplaceLinkIds(replacer func(oldId string) (newId string)) { if l.content.TargetObjectId != "" { - newId, replaced := f(l.content.TargetObjectId) - if replaced { - l.content.TargetObjectId = newId - anyReplaced = true - } + l.content.TargetObjectId = replacer(l.content.TargetObjectId) } - return } diff --git a/core/block/simple/dataview/dataview.go b/core/block/simple/dataview/dataview.go index efdfefad7..e19cc1faf 100644 --- a/core/block/simple/dataview/dataview.go +++ b/core/block/simple/dataview/dataview.go @@ -226,15 +226,10 @@ func (l *Dataview) FillSmartIds(ids []string) []string { return ids } -func (l *Dataview) ReplaceSmartIds(f func(id string) (newId string, replaced bool)) (anyReplaced bool) { +func (l *Dataview) ReplaceLinkIds(replacer func(oldId string) (newId string)) { if l.content.TargetObjectId != "" { - newId, replaced := f(l.content.TargetObjectId) - if replaced { - l.content.TargetObjectId = newId - return true - } + l.content.TargetObjectId = replacer(l.content.TargetObjectId) } - return } diff --git a/core/block/simple/link/link.go b/core/block/simple/link/link.go index 70238cbd7..2899ea0bc 100644 --- a/core/block/simple/link/link.go +++ b/core/block/simple/link/link.go @@ -114,15 +114,10 @@ func (l *Link) Diff(b simple.Block) (msgs []simple.EventMessage, err error) { return } -func (l *Link) ReplaceSmartIds(f func(id string) (newId string, replaced bool)) (anyReplaced bool) { +func (l *Link) ReplaceLinkIds(replacer func(oldId string) (newId string)) { if l.content.TargetBlockId != "" { - newId, replaced := f(l.content.TargetBlockId) - if replaced { - l.content.TargetBlockId = newId - return true - } + l.content.TargetBlockId = replacer(l.content.TargetBlockId) } - return } diff --git a/core/block/simple/simple.go b/core/block/simple/simple.go index 1179e742f..e7fec80d2 100644 --- a/core/block/simple/simple.go +++ b/core/block/simple/simple.go @@ -49,7 +49,7 @@ type DetailsHandler interface { } type ObjectLinkReplacer interface { - ReplaceSmartIds(f func(id string) (newId string, replaced bool)) (anyReplaced bool) + ReplaceLinkIds(replacer func(oldId string) (newId string)) } type EventMessage struct { diff --git a/core/block/simple/text/text.go b/core/block/simple/text/text.go index 2777e83bf..fa6db5c83 100644 --- a/core/block/simple/text/text.go +++ b/core/block/simple/text/text.go @@ -651,16 +651,13 @@ func (t *Text) FillSmartIds(ids []string) []string { return ids } -func (t *Text) ReplaceSmartIds(f func(id string) (newId string, replaced bool)) (anyReplaced bool) { +func (t *Text) ReplaceLinkIds(replacer func(oldId string) (newId string)) { if t.content.Marks != nil { for _, m := range t.content.Marks.Marks { if (m.Type == model.BlockContentTextMark_Mention || m.Type == model.BlockContentTextMark_Object) && m.Param != "" { - newId, replaced := f(m.Param) - if replaced { - m.Param = newId - anyReplaced = true - } + + m.Param = replacer(m.Param) } } } diff --git a/core/debug/handler_anydebug.go b/core/debug/handler_anydebug.go index 7307be4a0..45e8fc1c6 100644 --- a/core/debug/handler_anydebug.go +++ b/core/debug/handler_anydebug.go @@ -3,11 +3,12 @@ package debug import ( - "os" - "github.com/go-chi/chi/v5" - "github.com/anyproto/any-sync/app" "fmt" "net/http" + "os" + + "github.com/anyproto/any-sync/app" + "github.com/go-chi/chi/v5" ) func (d *debug) initHandlers(a *app.App) { diff --git a/core/domain/uniquekey.go b/core/domain/uniquekey.go index 7ac7fc83f..1a3a1c5e1 100644 --- a/core/domain/uniquekey.go +++ b/core/domain/uniquekey.go @@ -5,8 +5,6 @@ import ( "fmt" "strings" - "github.com/globalsign/mgo/bson" - "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" ) @@ -107,20 +105,3 @@ func GetTypeKeyFromRawUniqueKey(raw string) (TypeKey, error) { } return TypeKey(uk.InternalKey()), nil } - -// SubObjectIdToUniqueKey converts legacy subobject id to uniqueKey -// if id is not supported subObjectId, it will return nil, false -// suppose to be used only for migration and almost free to use -func SubObjectIdToUniqueKey(id string) (uk UniqueKey, valid bool) { - if bson.IsObjectIdHex(id) { - // historically, we don't have the prefix for the options - // so we need to handled it this ugly way - id = smartBlockTypeToKey[smartblock.SmartBlockTypeRelationOption] + uniqueKeySeparator + id - } - uk, err := UnmarshalUniqueKey(id) - if err != nil { - return nil, false - } - - return uk, true -} diff --git a/tests/blockbuilder/block_render.go b/tests/blockbuilder/block_render.go index 6c3c27525..8f8b8d7ac 100644 --- a/tests/blockbuilder/block_render.go +++ b/tests/blockbuilder/block_render.go @@ -2,10 +2,12 @@ package blockbuilder import ( "encoding/json" - "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - "github.com/gogo/protobuf/jsonpb" "fmt" + + "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" + + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) type blockView struct { From 05e188a853f80bda9c070340f3a6e4c778d96a9e Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 18:07:10 +0500 Subject: [PATCH 15/22] Fix after merge --- .../editor/file/block_service_mock_test.go | 39 +-- core/block/import/mock.go | 12 +- core/files/files.go | 6 +- core/files/images.go | 2 +- core/filestorage/filesync/filesync.go | 2 +- .../filesync/mock_filesync/filesync_mock.go | 299 ------------------ .../filesync/mock_filesync/mock_FileSync.go | 54 ++++ core/filestorage/filesync/upload.go | 16 +- core/subscription/fixture_test.go | 17 +- .../mock_CollectionService.go | 11 +- core/subscription/service_test.go | 58 ++-- .../mock_system_object/mock_Service.go | 54 ++++ pkg/lib/core/mock_core/service_mock.go | 214 ------------- util/testMock/anytype_mock.go | 142 ++++++--- util/testMock/file_service_mock.go | 58 ++-- util/testMock/mockDetailsModifier/dm_mock.go | 10 +- util/testMock/mockKanban/kanban_mock.go | 8 +- util/testMock/mockRelation/relation_mock.go | 159 ---------- util/testMock/mockSource/source_mock.go | 40 ++- util/testMock/objectstore_mock.go | 170 +--------- util/testMock/sbt_provider_mock.go | 23 +- 21 files changed, 370 insertions(+), 1024 deletions(-) delete mode 100644 core/filestorage/filesync/mock_filesync/filesync_mock.go delete mode 100644 pkg/lib/core/mock_core/service_mock.go delete mode 100644 util/testMock/mockRelation/relation_mock.go diff --git a/core/block/editor/file/block_service_mock_test.go b/core/block/editor/file/block_service_mock_test.go index 07aecd6ea..121fdfc33 100644 --- a/core/block/editor/file/block_service_mock_test.go +++ b/core/block/editor/file/block_service_mock_test.go @@ -9,12 +9,11 @@ package file_test import ( + context "context" reflect "reflect" gomock "go.uber.org/mock/gomock" - file "github.com/anyproto/anytype-heart/core/block/editor/file" - smartblock "github.com/anyproto/anytype-heart/core/block/editor/smartblock" process "github.com/anyproto/anytype-heart/core/block/process" session "github.com/anyproto/anytype-heart/core/session" pb "github.com/anyproto/anytype-heart/pb" @@ -44,9 +43,9 @@ func (m *MockBlockService) EXPECT() *MockBlockServiceMockRecorder { } // CreateLinkToTheNewObject mocks base method. -func (m *MockBlockService) CreateLinkToTheNewObject(arg0 *session.Context, arg1 *pb.RpcBlockLinkCreateWithObjectRequest) (string, string, error) { +func (m *MockBlockService) CreateLinkToTheNewObject(arg0 context.Context, arg1 session.Context, arg2 *pb.RpcBlockLinkCreateWithObjectRequest) (string, string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateLinkToTheNewObject", arg0, arg1) + ret := m.ctrl.Call(m, "CreateLinkToTheNewObject", arg0, arg1, arg2) ret0, _ := ret[0].(string) ret1, _ := ret[1].(string) ret2, _ := ret[2].(error) @@ -54,37 +53,9 @@ func (m *MockBlockService) CreateLinkToTheNewObject(arg0 *session.Context, arg1 } // CreateLinkToTheNewObject indicates an expected call of CreateLinkToTheNewObject. -func (mr *MockBlockServiceMockRecorder) CreateLinkToTheNewObject(arg0, arg1 any) *gomock.Call { +func (mr *MockBlockServiceMockRecorder) CreateLinkToTheNewObject(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLinkToTheNewObject", reflect.TypeOf((*MockBlockService)(nil).CreateLinkToTheNewObject), arg0, arg1) -} - -// Do mocks base method. -func (m *MockBlockService) Do(arg0 string, arg1 func(smartblock.SmartBlock) error) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Do", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// Do indicates an expected call of Do. -func (mr *MockBlockServiceMockRecorder) Do(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Do", reflect.TypeOf((*MockBlockService)(nil).Do), arg0, arg1) -} - -// DoFile mocks base method. -func (m *MockBlockService) DoFile(arg0 string, arg1 func(file.File) error) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DoFile", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// DoFile indicates an expected call of DoFile. -func (mr *MockBlockServiceMockRecorder) DoFile(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DoFile", reflect.TypeOf((*MockBlockService)(nil).DoFile), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLinkToTheNewObject", reflect.TypeOf((*MockBlockService)(nil).CreateLinkToTheNewObject), arg0, arg1, arg2) } // ProcessAdd mocks base method. diff --git a/core/block/import/mock.go b/core/block/import/mock.go index 627eb7aed..86e483c8d 100644 --- a/core/block/import/mock.go +++ b/core/block/import/mock.go @@ -9,6 +9,7 @@ package importer import ( + context "context" reflect "reflect" time "time" @@ -17,7 +18,6 @@ import ( gomock "go.uber.org/mock/gomock" converter "github.com/anyproto/anytype-heart/core/block/import/converter" - session "github.com/anyproto/anytype-heart/core/session" ) // MockCreator is a mock of Creator interface. @@ -44,9 +44,9 @@ func (m *MockCreator) EXPECT() *MockCreatorMockRecorder { } // Create mocks base method. -func (m *MockCreator) Create(arg0 *session.Context, arg1 *converter.Snapshot, arg2 map[string]string, arg3 map[string]treestorage.TreeStorageCreatePayload, arg4 []string) (*types.Struct, string, error) { +func (m *MockCreator) Create(arg0 context.Context, arg1 string, arg2 *converter.Snapshot, arg3 map[string]string, arg4 map[string]treestorage.TreeStorageCreatePayload, arg5 []string) (*types.Struct, string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(*types.Struct) ret1, _ := ret[1].(string) ret2, _ := ret[2].(error) @@ -54,9 +54,9 @@ func (m *MockCreator) Create(arg0 *session.Context, arg1 *converter.Snapshot, ar } // Create indicates an expected call of Create. -func (mr *MockCreatorMockRecorder) Create(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { +func (mr *MockCreatorMockRecorder) Create(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockCreator)(nil).Create), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockCreator)(nil).Create), arg0, arg1, arg2, arg3, arg4, arg5) } // MockIDGetter is a mock of IDGetter interface. @@ -83,7 +83,7 @@ func (m *MockIDGetter) EXPECT() *MockIDGetterMockRecorder { } // Get mocks base method. -func (m *MockIDGetter) Get(arg0 *session.Context, arg1 *converter.Snapshot, arg2 time.Time, arg3 bool) (string, treestorage.TreeStorageCreatePayload, error) { +func (m *MockIDGetter) Get(arg0 string, arg1 *converter.Snapshot, arg2 time.Time, arg3 bool) (string, treestorage.TreeStorageCreatePayload, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(string) diff --git a/core/files/files.go b/core/files/files.go index f1e613323..13b519d52 100644 --- a/core/files/files.go +++ b/core/files/files.go @@ -142,7 +142,7 @@ func (s *service) fileAdd(ctx context.Context, spaceID string, opts AddOptions) return "", nil, err } - err = s.storeFileSize(nodeHash) + err = s.storeFileSize(spaceID, nodeHash) if err != nil { return "", nil, fmt.Errorf("store file size: %w", err) } @@ -150,8 +150,8 @@ func (s *service) fileAdd(ctx context.Context, spaceID string, opts AddOptions) return nodeHash, fileInfo, nil } -func (s *service) storeFileSize(hash string) error { - _, err := s.fileSync.CalculateFileSize(context.Background(), hash) +func (s *service) storeFileSize(spaceId string, hash string) error { + _, err := s.fileSync.CalculateFileSize(context.Background(), spaceId, hash) return err } diff --git a/core/files/images.go b/core/files/images.go index 9614fb982..5b62efe86 100644 --- a/core/files/images.go +++ b/core/files/images.go @@ -118,7 +118,7 @@ func (s *service) imageAdd(ctx context.Context, spaceID string, opts AddOptions) } } - err = s.storeFileSize(nodeHash) + err = s.storeFileSize(spaceID, nodeHash) if err != nil { return "", nil, fmt.Errorf("store file size: %w", err) } diff --git a/core/filestorage/filesync/filesync.go b/core/filestorage/filesync/filesync.go index 5b2e66595..119234f7a 100644 --- a/core/filestorage/filesync/filesync.go +++ b/core/filestorage/filesync/filesync.go @@ -44,7 +44,7 @@ type FileSync interface { DebugQueue(*http.Request) (*QueueInfo, error) SendImportEvents() ClearImportEvents() - CalculateFileSize(ctx context.Context, fileID string) (int, error) + CalculateFileSize(ctx context.Context, spaceId string, fileID string) (int, error) app.ComponentRunnable } diff --git a/core/filestorage/filesync/mock_filesync/filesync_mock.go b/core/filestorage/filesync/mock_filesync/filesync_mock.go deleted file mode 100644 index 1a69c2296..000000000 --- a/core/filestorage/filesync/mock_filesync/filesync_mock.go +++ /dev/null @@ -1,299 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/filestorage/filesync (interfaces: FileSync) -// -// Generated by this command: -// -// mockgen -package mock_filesync -destination ./mock_filesync/filesync_mock.go github.com/anyproto/anytype-heart/core/filestorage/filesync FileSync -// -// Package mock_filesync is a generated GoMock package. -package mock_filesync - -import ( - context "context" - http "net/http" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - format "github.com/ipfs/go-ipld-format" - gomock "go.uber.org/mock/gomock" - - filesync "github.com/anyproto/anytype-heart/core/filestorage/filesync" -) - -// MockFileSync is a mock of FileSync interface. -type MockFileSync struct { - ctrl *gomock.Controller - recorder *MockFileSyncMockRecorder -} - -// MockFileSyncMockRecorder is the mock recorder for MockFileSync. -type MockFileSyncMockRecorder struct { - mock *MockFileSync -} - -// NewMockFileSync creates a new mock instance. -func NewMockFileSync(ctrl *gomock.Controller) *MockFileSync { - mock := &MockFileSync{ctrl: ctrl} - mock.recorder = &MockFileSyncMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockFileSync) EXPECT() *MockFileSyncMockRecorder { - return m.recorder -} - -// AddFile mocks base method. -func (m *MockFileSync) AddFile(arg0, arg1 string, arg2, arg3 bool) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddFile", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(error) - return ret0 -} - -// AddFile indicates an expected call of AddFile. -func (mr *MockFileSyncMockRecorder) AddFile(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFile", reflect.TypeOf((*MockFileSync)(nil).AddFile), arg0, arg1, arg2, arg3) -} - -// CalculateFileSize mocks base method. -func (m *MockFileSync) CalculateFileSize(arg0 context.Context, arg1 string) (int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CalculateFileSize", arg0, arg1) - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CalculateFileSize indicates an expected call of CalculateFileSize. -func (mr *MockFileSyncMockRecorder) CalculateFileSize(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateFileSize", reflect.TypeOf((*MockFileSync)(nil).CalculateFileSize), arg0, arg1) -} - -// ClearImportEvents mocks base method. -func (m *MockFileSync) ClearImportEvents() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ClearImportEvents") -} - -// ClearImportEvents indicates an expected call of ClearImportEvents. -func (mr *MockFileSyncMockRecorder) ClearImportEvents() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearImportEvents", reflect.TypeOf((*MockFileSync)(nil).ClearImportEvents)) -} - -// Close mocks base method. -func (m *MockFileSync) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockFileSyncMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockFileSync)(nil).Close), arg0) -} - -// DebugQueue mocks base method. -func (m *MockFileSync) DebugQueue(arg0 *http.Request) (*filesync.QueueInfo, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DebugQueue", arg0) - ret0, _ := ret[0].(*filesync.QueueInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DebugQueue indicates an expected call of DebugQueue. -func (mr *MockFileSyncMockRecorder) DebugQueue(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugQueue", reflect.TypeOf((*MockFileSync)(nil).DebugQueue), arg0) -} - -// FetchChunksCount mocks base method. -func (m *MockFileSync) FetchChunksCount(arg0 context.Context, arg1 format.Node) (int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchChunksCount", arg0, arg1) - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchChunksCount indicates an expected call of FetchChunksCount. -func (mr *MockFileSyncMockRecorder) FetchChunksCount(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchChunksCount", reflect.TypeOf((*MockFileSync)(nil).FetchChunksCount), arg0, arg1) -} - -// FileListStats mocks base method. -func (m *MockFileSync) FileListStats(arg0 context.Context, arg1 string, arg2 []string) ([]filesync.FileStat, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileListStats", arg0, arg1, arg2) - ret0, _ := ret[0].([]filesync.FileStat) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FileListStats indicates an expected call of FileListStats. -func (mr *MockFileSyncMockRecorder) FileListStats(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileListStats", reflect.TypeOf((*MockFileSync)(nil).FileListStats), arg0, arg1, arg2) -} - -// FileStat mocks base method. -func (m *MockFileSync) FileStat(arg0 context.Context, arg1, arg2 string) (filesync.FileStat, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileStat", arg0, arg1, arg2) - ret0, _ := ret[0].(filesync.FileStat) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FileStat indicates an expected call of FileStat. -func (mr *MockFileSyncMockRecorder) FileStat(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileStat", reflect.TypeOf((*MockFileSync)(nil).FileStat), arg0, arg1, arg2) -} - -// HasUpload mocks base method. -func (m *MockFileSync) HasUpload(arg0, arg1 string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HasUpload", arg0, arg1) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// HasUpload indicates an expected call of HasUpload. -func (mr *MockFileSyncMockRecorder) HasUpload(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasUpload", reflect.TypeOf((*MockFileSync)(nil).HasUpload), arg0, arg1) -} - -// Init mocks base method. -func (m *MockFileSync) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockFileSyncMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockFileSync)(nil).Init), arg0) -} - -// IsFileUploadLimited mocks base method. -func (m *MockFileSync) IsFileUploadLimited(arg0, arg1 string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsFileUploadLimited", arg0, arg1) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsFileUploadLimited indicates an expected call of IsFileUploadLimited. -func (mr *MockFileSyncMockRecorder) IsFileUploadLimited(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsFileUploadLimited", reflect.TypeOf((*MockFileSync)(nil).IsFileUploadLimited), arg0, arg1) -} - -// Name mocks base method. -func (m *MockFileSync) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockFileSyncMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockFileSync)(nil).Name)) -} - -// OnUpload mocks base method. -func (m *MockFileSync) OnUpload(arg0 func(string, string) error) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "OnUpload", arg0) -} - -// OnUpload indicates an expected call of OnUpload. -func (mr *MockFileSyncMockRecorder) OnUpload(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnUpload", reflect.TypeOf((*MockFileSync)(nil).OnUpload), arg0) -} - -// RemoveFile mocks base method. -func (m *MockFileSync) RemoveFile(arg0, arg1 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoveFile", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// RemoveFile indicates an expected call of RemoveFile. -func (mr *MockFileSyncMockRecorder) RemoveFile(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFile", reflect.TypeOf((*MockFileSync)(nil).RemoveFile), arg0, arg1) -} - -// Run mocks base method. -func (m *MockFileSync) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockFileSyncMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockFileSync)(nil).Run), arg0) -} - -// SendImportEvents mocks base method. -func (m *MockFileSync) SendImportEvents() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SendImportEvents") -} - -// SendImportEvents indicates an expected call of SendImportEvents. -func (mr *MockFileSyncMockRecorder) SendImportEvents() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendImportEvents", reflect.TypeOf((*MockFileSync)(nil).SendImportEvents)) -} - -// SpaceStat mocks base method. -func (m *MockFileSync) SpaceStat(arg0 context.Context, arg1 string) (filesync.SpaceStat, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SpaceStat", arg0, arg1) - ret0, _ := ret[0].(filesync.SpaceStat) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SpaceStat indicates an expected call of SpaceStat. -func (mr *MockFileSyncMockRecorder) SpaceStat(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceStat", reflect.TypeOf((*MockFileSync)(nil).SpaceStat), arg0, arg1) -} - -// SyncStatus mocks base method. -func (m *MockFileSync) SyncStatus() (filesync.SyncStatus, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SyncStatus") - ret0, _ := ret[0].(filesync.SyncStatus) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SyncStatus indicates an expected call of SyncStatus. -func (mr *MockFileSyncMockRecorder) SyncStatus() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncStatus", reflect.TypeOf((*MockFileSync)(nil).SyncStatus)) -} diff --git a/core/filestorage/filesync/mock_filesync/mock_FileSync.go b/core/filestorage/filesync/mock_filesync/mock_FileSync.go index 95dbc5364..eae6f7d48 100644 --- a/core/filestorage/filesync/mock_filesync/mock_FileSync.go +++ b/core/filestorage/filesync/mock_filesync/mock_FileSync.go @@ -70,6 +70,60 @@ func (_c *MockFileSync_AddFile_Call) RunAndReturn(run func(string, string, bool, return _c } +// CalculateFileSize provides a mock function with given fields: ctx, spaceId, fileID +func (_m *MockFileSync) CalculateFileSize(ctx context.Context, spaceId string, fileID string) (int, error) { + ret := _m.Called(ctx, spaceId, fileID) + + var r0 int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (int, error)); ok { + return rf(ctx, spaceId, fileID) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) int); ok { + r0 = rf(ctx, spaceId, fileID) + } else { + r0 = ret.Get(0).(int) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, spaceId, fileID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockFileSync_CalculateFileSize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CalculateFileSize' +type MockFileSync_CalculateFileSize_Call struct { + *mock.Call +} + +// CalculateFileSize is a helper method to define mock.On call +// - ctx context.Context +// - spaceId string +// - fileID string +func (_e *MockFileSync_Expecter) CalculateFileSize(ctx interface{}, spaceId interface{}, fileID interface{}) *MockFileSync_CalculateFileSize_Call { + return &MockFileSync_CalculateFileSize_Call{Call: _e.mock.On("CalculateFileSize", ctx, spaceId, fileID)} +} + +func (_c *MockFileSync_CalculateFileSize_Call) Run(run func(ctx context.Context, spaceId string, fileID string)) *MockFileSync_CalculateFileSize_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(string)) + }) + return _c +} + +func (_c *MockFileSync_CalculateFileSize_Call) Return(_a0 int, _a1 error) *MockFileSync_CalculateFileSize_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockFileSync_CalculateFileSize_Call) RunAndReturn(run func(context.Context, string, string) (int, error)) *MockFileSync_CalculateFileSize_Call { + _c.Call.Return(run) + return _c +} + // ClearImportEvents provides a mock function with given fields: func (_m *MockFileSync) ClearImportEvents() { _m.Called() diff --git a/core/filestorage/filesync/upload.go b/core/filestorage/filesync/upload.go index af7a817d3..97076c3a0 100644 --- a/core/filestorage/filesync/upload.go +++ b/core/filestorage/filesync/upload.go @@ -154,7 +154,7 @@ func isLimitReachedErr(err error) bool { func (f *fileSync) uploadFile(ctx context.Context, spaceID string, fileID string) error { log.Debug("uploading file", zap.String("fileID", fileID)) - fileSize, err := f.CalculateFileSize(ctx, fileID) + fileSize, err := f.CalculateFileSize(ctx, spaceID, fileID) if err != nil { return fmt.Errorf("calculate file size: %w", err) } @@ -169,7 +169,7 @@ func (f *fileSync) uploadFile(ctx context.Context, spaceID string, fileID string } var totalBytesUploaded int - err = f.walkFileBlocks(ctx, fileID, func(fileBlocks []blocks.Block) error { + err = f.walkFileBlocks(ctx, spaceID, fileID, func(fileBlocks []blocks.Block) error { bytesToUpload, blocksToUpload, err := f.selectBlocksToUploadAndBindExisting(ctx, spaceID, fileID, fileBlocks) if err != nil { return fmt.Errorf("select blocks to upload: %w", err) @@ -272,12 +272,12 @@ func (f *fileSync) selectBlocksToUploadAndBindExisting(ctx context.Context, spac return bytesToUpload, blocksToUpload, nil } -func (f *fileSync) walkDAG(ctx context.Context, fileID string, visit func(node ipld.Node) error) error { +func (f *fileSync) walkDAG(ctx context.Context, spaceId string, fileID string, visit func(node ipld.Node) error) error { fileCid, err := cid.Parse(fileID) if err != nil { return fmt.Errorf("parse CID %s: %w", fileID, err) } - dagService := f.dagServiceForSpace(spaceID) + dagService := f.dagServiceForSpace(spaceId) rootNode, err := dagService.Get(ctx, fileCid) if err != nil { return fmt.Errorf("get root node: %w", err) @@ -300,14 +300,14 @@ func (f *fileSync) walkDAG(ctx context.Context, fileID string, visit func(node i } // CalculateFileSize calculates or gets already calculated file size -func (f *fileSync) CalculateFileSize(ctx context.Context, fileID string) (int, error) { +func (f *fileSync) CalculateFileSize(ctx context.Context, spaceId string, fileID string) (int, error) { size, err := f.fileStore.GetFileSize(fileID) if err == nil { return size, nil } size = 0 - err = f.walkDAG(ctx, fileID, func(node ipld.Node) error { + err = f.walkDAG(ctx, spaceId, fileID, func(node ipld.Node) error { size += len(node.RawData()) return nil }) @@ -323,10 +323,10 @@ func (f *fileSync) CalculateFileSize(ctx context.Context, fileID string) (int, e const batchSize = 10 -func (f *fileSync) walkFileBlocks(ctx context.Context, fileID string, proc func(fileBlocks []blocks.Block) error) error { +func (f *fileSync) walkFileBlocks(ctx context.Context, spaceId string, fileID string, proc func(fileBlocks []blocks.Block) error) error { blocksBuf := make([]blocks.Block, 0, batchSize) - err := f.walkDAG(ctx, fileID, func(node ipld.Node) error { + err := f.walkDAG(ctx, spaceId, fileID, func(node ipld.Node) error { b, err := blocks.NewBlockWithCid(node.RawData(), node.Cid()) if err != nil { return err diff --git a/core/subscription/fixture_test.go b/core/subscription/fixture_test.go index a80e98c51..25d43e3a4 100644 --- a/core/subscription/fixture_test.go +++ b/core/subscription/fixture_test.go @@ -15,6 +15,7 @@ import ( "github.com/anyproto/anytype-heart/core/event" "github.com/anyproto/anytype-heart/core/event/mock_event" + "github.com/anyproto/anytype-heart/core/subscription/mock_subscription" "github.com/anyproto/anytype-heart/core/system_object/mock_system_object" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" @@ -24,15 +25,14 @@ import ( ) type collectionServiceMock struct { - updateCh chan []string + *mock_subscription.MockCollectionService } -func (c *collectionServiceMock) SubscribeForCollection(collectionID string, subscriptionID string) ([]string, <-chan []string, error) { - return nil, c.updateCh, nil +func (c *collectionServiceMock) Name() string { + return "collectionService" } -func (c *collectionServiceMock) UnsubscribeFromCollection(collectionID string, subscriptionID string) { -} +func (c *collectionServiceMock) Init(a *app.App) error { return nil } type fixture struct { Service @@ -42,6 +42,7 @@ type fixture struct { systemObjectService *mock_system_object.MockService sender *mock_event.MockSender events []*pb.Event + collectionService *collectionServiceMock } func newFixture(t *testing.T) *fixture { @@ -49,7 +50,6 @@ func newFixture(t *testing.T) *fixture { a := new(app.App) testMock.RegisterMockObjectStore(ctrl, a) testMock.RegisterMockKanban(ctrl, a) - a.Register(&collectionServiceMock{}) sbtProvider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) sbtProvider.EXPECT().Name().Return("smartBlockTypeProvider") sbtProvider.EXPECT().Init(mock.Anything).Return(nil) @@ -57,12 +57,17 @@ func newFixture(t *testing.T) *fixture { systemObjectService := mock_system_object.NewMockService(t) a.Register(testutil.PrepareMock(a, systemObjectService)) + + collectionService := &collectionServiceMock{MockCollectionService: mock_subscription.NewMockCollectionService(t)} + a.Register(collectionService) + fx := &fixture{ Service: New(), a: a, ctrl: ctrl, store: a.MustComponent(objectstore.CName).(*testMock.MockObjectStore), systemObjectService: systemObjectService, + collectionService: collectionService, } sender := mock_event.NewMockSender(t) sender.EXPECT().Init(mock.Anything).Return(nil) diff --git a/core/subscription/mock_subscription/mock_CollectionService.go b/core/subscription/mock_subscription/mock_CollectionService.go index 67e368aef..196c8c73e 100644 --- a/core/subscription/mock_subscription/mock_CollectionService.go +++ b/core/subscription/mock_subscription/mock_CollectionService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.26.1. DO NOT EDIT. package mock_subscription @@ -115,12 +115,13 @@ func (_c *MockCollectionService_UnsubscribeFromCollection_Call) RunAndReturn(run return _c } -// NewMockCollectionService creates a new instance of MockCollectionService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockCollectionService(t interface { +type mockConstructorTestingTNewMockCollectionService interface { mock.TestingT Cleanup(func()) -}) *MockCollectionService { +} + +// NewMockCollectionService creates a new instance of MockCollectionService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockCollectionService(t mockConstructorTestingTNewMockCollectionService) *MockCollectionService { mock := &MockCollectionService{} mock.Mock.Test(t) diff --git a/core/subscription/service_test.go b/core/subscription/service_test.go index d17853076..949a0a7c9 100644 --- a/core/subscription/service_test.go +++ b/core/subscription/service_test.go @@ -2,15 +2,14 @@ package subscription import ( "context" + "fmt" "testing" - "github.com/anyproto/any-sync/app" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" - "testing" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" @@ -359,14 +358,14 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ Key: bundle.RelationKeyName.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + }, nil).Maybe() + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ Key: bundle.RelationKeyId.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + }, nil).Maybe() var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ SubId: subscriptionID, @@ -409,14 +408,14 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ Key: bundle.RelationKeyName.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + }, nil).Maybe() + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ Key: bundle.RelationKeyId.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + }, nil).Maybe() var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ SubId: subscriptionID, @@ -466,14 +465,14 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ Key: bundle.RelationKeyName.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + }, nil).Maybe() + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ Key: bundle.RelationKeyId.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + }, nil).Maybe() var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ SubId: subscriptionID, @@ -516,15 +515,15 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ Key: bundle.RelationKeyName.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + }, nil).Maybe() - fx.store.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ Key: testRelationKey, Format: model.RelationFormat_object, - }, nil).AnyTimes() + }, nil).Maybe() s := fx.Service.(*service) s.ds = newDependencyService(s) @@ -571,15 +570,15 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ Key: bundle.RelationKeyName.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + }, nil).Maybe() - fx.store.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ Key: testRelationKey, Format: model.RelationFormat_object, - }, nil).AnyTimes() + }, nil).Maybe() s := fx.Service.(*service) s.ds = newDependencyService(s) @@ -626,14 +625,14 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ Key: bundle.RelationKeyName.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ + }, nil).Maybe() + fx.systemObjectService.EXPECT().GetRelationByKey(bundle.RelationKeyId.String()).Return(&model.Relation{ Key: bundle.RelationKeyId.String(), Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + }, nil).Maybe() var resp, err = fx.Search(pb.RpcObjectSearchSubscribeRequest{ SubId: subscriptionID, @@ -702,12 +701,6 @@ func TestNestedSubscription(t *testing.T) { }) } -func (c *collectionServiceMock) Name() string { - return "collectionService" -} - -func (c *collectionServiceMock) Init(a *app.App) error { return nil } - func testCreateSubscriptionWithNestedFilter(t *testing.T) *fixtureRealStore { fx := newFixtureWithRealObjectStore(t) fx.systemObjectServiceMock.EXPECT().GetRelationByKey(mock.Anything).Return(&model.Relation{}, nil) @@ -797,4 +790,3 @@ func testCreateSubscriptionWithNestedFilter(t *testing.T) *fixtureRealStore { }) return fx } - diff --git a/core/system_object/mock_system_object/mock_Service.go b/core/system_object/mock_system_object/mock_Service.go index b4200ba87..18c5e24f7 100644 --- a/core/system_object/mock_system_object/mock_Service.go +++ b/core/system_object/mock_system_object/mock_Service.go @@ -261,6 +261,60 @@ func (_c *MockService_GetObjectByUniqueKey_Call) RunAndReturn(run func(string, d return _c } +// GetObjectIdByUniqueKey provides a mock function with given fields: ctx, spaceId, key +func (_m *MockService) GetObjectIdByUniqueKey(ctx context.Context, spaceId string, key domain.UniqueKey) (string, error) { + ret := _m.Called(ctx, spaceId, key) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, domain.UniqueKey) (string, error)); ok { + return rf(ctx, spaceId, key) + } + if rf, ok := ret.Get(0).(func(context.Context, string, domain.UniqueKey) string); ok { + r0 = rf(ctx, spaceId, key) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, domain.UniqueKey) error); ok { + r1 = rf(ctx, spaceId, key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockService_GetObjectIdByUniqueKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetObjectIdByUniqueKey' +type MockService_GetObjectIdByUniqueKey_Call struct { + *mock.Call +} + +// GetObjectIdByUniqueKey is a helper method to define mock.On call +// - ctx context.Context +// - spaceId string +// - key domain.UniqueKey +func (_e *MockService_Expecter) GetObjectIdByUniqueKey(ctx interface{}, spaceId interface{}, key interface{}) *MockService_GetObjectIdByUniqueKey_Call { + return &MockService_GetObjectIdByUniqueKey_Call{Call: _e.mock.On("GetObjectIdByUniqueKey", ctx, spaceId, key)} +} + +func (_c *MockService_GetObjectIdByUniqueKey_Call) Run(run func(ctx context.Context, spaceId string, key domain.UniqueKey)) *MockService_GetObjectIdByUniqueKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(domain.UniqueKey)) + }) + return _c +} + +func (_c *MockService_GetObjectIdByUniqueKey_Call) Return(id string, err error) *MockService_GetObjectIdByUniqueKey_Call { + _c.Call.Return(id, err) + return _c +} + +func (_c *MockService_GetObjectIdByUniqueKey_Call) RunAndReturn(run func(context.Context, string, domain.UniqueKey) (string, error)) *MockService_GetObjectIdByUniqueKey_Call { + _c.Call.Return(run) + return _c +} + // GetObjectType provides a mock function with given fields: url func (_m *MockService) GetObjectType(url string) (*model.ObjectType, error) { ret := _m.Called(url) diff --git a/pkg/lib/core/mock_core/service_mock.go b/pkg/lib/core/mock_core/service_mock.go deleted file mode 100644 index 258b44f04..000000000 --- a/pkg/lib/core/mock_core/service_mock.go +++ /dev/null @@ -1,214 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/pkg/lib/core (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package mock_core -destination ./mock_core/service_mock.go github.com/anyproto/anytype-heart/pkg/lib/core Service -// -// Package mock_core is a generated GoMock package. -package mock_core - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - gomock "go.uber.org/mock/gomock" - - core "github.com/anyproto/anytype-heart/pkg/lib/core" - threads "github.com/anyproto/anytype-heart/pkg/lib/threads" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockService) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) -} - -// EnsurePredefinedBlocks mocks base method. -func (m *MockService) EnsurePredefinedBlocks(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EnsurePredefinedBlocks", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// EnsurePredefinedBlocks indicates an expected call of EnsurePredefinedBlocks. -func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsurePredefinedBlocks", reflect.TypeOf((*MockService)(nil).EnsurePredefinedBlocks), arg0) -} - -// GetAllWorkspaces mocks base method. -func (m *MockService) GetAllWorkspaces() ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllWorkspaces") - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAllWorkspaces indicates an expected call of GetAllWorkspaces. -func (mr *MockServiceMockRecorder) GetAllWorkspaces() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllWorkspaces", reflect.TypeOf((*MockService)(nil).GetAllWorkspaces)) -} - -// GetWorkspaceIdForObject mocks base method. -func (m *MockService) GetWorkspaceIdForObject(arg0 string) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetWorkspaceIdForObject", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetWorkspaceIdForObject indicates an expected call of GetWorkspaceIdForObject. -func (mr *MockServiceMockRecorder) GetWorkspaceIdForObject(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceIdForObject", reflect.TypeOf((*MockService)(nil).GetWorkspaceIdForObject), arg0) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// IsStarted mocks base method. -func (m *MockService) IsStarted() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsStarted") - ret0, _ := ret[0].(bool) - return ret0 -} - -// IsStarted indicates an expected call of IsStarted. -func (mr *MockServiceMockRecorder) IsStarted() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsStarted", reflect.TypeOf((*MockService)(nil).IsStarted)) -} - -// LocalProfile mocks base method. -func (m *MockService) LocalProfile() (core.Profile, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LocalProfile") - ret0, _ := ret[0].(core.Profile) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// LocalProfile indicates an expected call of LocalProfile. -func (mr *MockServiceMockRecorder) LocalProfile() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalProfile", reflect.TypeOf((*MockService)(nil).LocalProfile)) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} - -// PredefinedBlocks mocks base method. -func (m *MockService) PredefinedBlocks() threads.DerivedSmartblockIds { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PredefinedBlocks") - ret0, _ := ret[0].(threads.DerivedSmartblockIds) - return ret0 -} - -// PredefinedBlocks indicates an expected call of PredefinedBlocks. -func (mr *MockServiceMockRecorder) PredefinedBlocks() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PredefinedBlocks", reflect.TypeOf((*MockService)(nil).PredefinedBlocks)) -} - -// ProfileID mocks base method. -func (m *MockService) ProfileID() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProfileID") - ret0, _ := ret[0].(string) - return ret0 -} - -// ProfileID indicates an expected call of ProfileID. -func (mr *MockServiceMockRecorder) ProfileID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProfileID", reflect.TypeOf((*MockService)(nil).ProfileID)) -} - -// Run mocks base method. -func (m *MockService) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) -} - -// Stop mocks base method. -func (m *MockService) Stop() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Stop") - ret0, _ := ret[0].(error) - return ret0 -} - -// Stop indicates an expected call of Stop. -func (mr *MockServiceMockRecorder) Stop() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockService)(nil).Stop)) -} diff --git a/util/testMock/anytype_mock.go b/util/testMock/anytype_mock.go index 551d23700..d15f9aecd 100644 --- a/util/testMock/anytype_mock.go +++ b/util/testMock/anytype_mock.go @@ -15,6 +15,7 @@ import ( app "github.com/anyproto/any-sync/app" gomock "go.uber.org/mock/gomock" + domain "github.com/anyproto/anytype-heart/core/domain" core "github.com/anyproto/anytype-heart/pkg/lib/core" threads "github.com/anyproto/anytype-heart/pkg/lib/threads" ) @@ -42,6 +43,20 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { return m.recorder } +// AccountObjects mocks base method. +func (m *MockService) AccountObjects() threads.DerivedSmartblockIds { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AccountObjects") + ret0, _ := ret[0].(threads.DerivedSmartblockIds) + return ret0 +} + +// AccountObjects indicates an expected call of AccountObjects. +func (mr *MockServiceMockRecorder) AccountObjects() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountObjects", reflect.TypeOf((*MockService)(nil).AccountObjects)) +} + // Close mocks base method. func (m *MockService) Close(arg0 context.Context) error { m.ctrl.T.Helper() @@ -56,48 +71,77 @@ func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) } -// EnsurePredefinedBlocks mocks base method. -func (m *MockService) EnsurePredefinedBlocks(arg0 context.Context) error { +// DeriveObjectId mocks base method. +func (m *MockService) DeriveObjectId(arg0 context.Context, arg1 string, arg2 domain.UniqueKey) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EnsurePredefinedBlocks", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// EnsurePredefinedBlocks indicates an expected call of EnsurePredefinedBlocks. -func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsurePredefinedBlocks", reflect.TypeOf((*MockService)(nil).EnsurePredefinedBlocks), arg0) -} - -// GetAllWorkspaces mocks base method. -func (m *MockService) GetAllWorkspaces() ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllWorkspaces") - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAllWorkspaces indicates an expected call of GetAllWorkspaces. -func (mr *MockServiceMockRecorder) GetAllWorkspaces() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllWorkspaces", reflect.TypeOf((*MockService)(nil).GetAllWorkspaces)) -} - -// GetWorkspaceIdForObject mocks base method. -func (m *MockService) GetWorkspaceIdForObject(arg0 string) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetWorkspaceIdForObject", arg0) + ret := m.ctrl.Call(m, "DeriveObjectId", arg0, arg1, arg2) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetWorkspaceIdForObject indicates an expected call of GetWorkspaceIdForObject. -func (mr *MockServiceMockRecorder) GetWorkspaceIdForObject(arg0 any) *gomock.Call { +// DeriveObjectId indicates an expected call of DeriveObjectId. +func (mr *MockServiceMockRecorder) DeriveObjectId(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceIdForObject", reflect.TypeOf((*MockService)(nil).GetWorkspaceIdForObject), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeriveObjectId", reflect.TypeOf((*MockService)(nil).DeriveObjectId), arg0, arg1, arg2) +} + +// DerivePredefinedObjects mocks base method. +func (m *MockService) DerivePredefinedObjects(arg0 context.Context, arg1 string, arg2 bool) (threads.DerivedSmartblockIds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DerivePredefinedObjects", arg0, arg1, arg2) + ret0, _ := ret[0].(threads.DerivedSmartblockIds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DerivePredefinedObjects indicates an expected call of DerivePredefinedObjects. +func (mr *MockServiceMockRecorder) DerivePredefinedObjects(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DerivePredefinedObjects", reflect.TypeOf((*MockService)(nil).DerivePredefinedObjects), arg0, arg1, arg2) +} + +// EnsurePredefinedBlocks mocks base method. +func (m *MockService) EnsurePredefinedBlocks(arg0 context.Context, arg1 string) (threads.DerivedSmartblockIds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsurePredefinedBlocks", arg0, arg1) + ret0, _ := ret[0].(threads.DerivedSmartblockIds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EnsurePredefinedBlocks indicates an expected call of EnsurePredefinedBlocks. +func (mr *MockServiceMockRecorder) EnsurePredefinedBlocks(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsurePredefinedBlocks", reflect.TypeOf((*MockService)(nil).EnsurePredefinedBlocks), arg0, arg1) +} + +// GetSystemRelationID mocks base method. +func (m *MockService) GetSystemRelationID(arg0 string, arg1 domain.RelationKey) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSystemRelationID", arg0, arg1) + ret0, _ := ret[0].(string) + return ret0 +} + +// GetSystemRelationID indicates an expected call of GetSystemRelationID. +func (mr *MockServiceMockRecorder) GetSystemRelationID(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSystemRelationID", reflect.TypeOf((*MockService)(nil).GetSystemRelationID), arg0, arg1) +} + +// GetSystemTypeID mocks base method. +func (m *MockService) GetSystemTypeID(arg0 string, arg1 domain.TypeKey) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSystemTypeID", arg0, arg1) + ret0, _ := ret[0].(string) + return ret0 +} + +// GetSystemTypeID indicates an expected call of GetSystemTypeID. +func (mr *MockServiceMockRecorder) GetSystemTypeID(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSystemTypeID", reflect.TypeOf((*MockService)(nil).GetSystemTypeID), arg0, arg1) } // Init mocks base method. @@ -129,18 +173,18 @@ func (mr *MockServiceMockRecorder) IsStarted() *gomock.Call { } // LocalProfile mocks base method. -func (m *MockService) LocalProfile() (core.Profile, error) { +func (m *MockService) LocalProfile(arg0 string) (core.Profile, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LocalProfile") + ret := m.ctrl.Call(m, "LocalProfile", arg0) ret0, _ := ret[0].(core.Profile) ret1, _ := ret[1].(error) return ret0, ret1 } // LocalProfile indicates an expected call of LocalProfile. -func (mr *MockServiceMockRecorder) LocalProfile() *gomock.Call { +func (mr *MockServiceMockRecorder) LocalProfile(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalProfile", reflect.TypeOf((*MockService)(nil).LocalProfile)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalProfile", reflect.TypeOf((*MockService)(nil).LocalProfile), arg0) } // Name mocks base method. @@ -157,32 +201,32 @@ func (mr *MockServiceMockRecorder) Name() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) } -// PredefinedBlocks mocks base method. -func (m *MockService) PredefinedBlocks() threads.DerivedSmartblockIds { +// PredefinedObjects mocks base method. +func (m *MockService) PredefinedObjects(arg0 string) threads.DerivedSmartblockIds { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PredefinedBlocks") + ret := m.ctrl.Call(m, "PredefinedObjects", arg0) ret0, _ := ret[0].(threads.DerivedSmartblockIds) return ret0 } -// PredefinedBlocks indicates an expected call of PredefinedBlocks. -func (mr *MockServiceMockRecorder) PredefinedBlocks() *gomock.Call { +// PredefinedObjects indicates an expected call of PredefinedObjects. +func (mr *MockServiceMockRecorder) PredefinedObjects(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PredefinedBlocks", reflect.TypeOf((*MockService)(nil).PredefinedBlocks)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PredefinedObjects", reflect.TypeOf((*MockService)(nil).PredefinedObjects), arg0) } // ProfileID mocks base method. -func (m *MockService) ProfileID() string { +func (m *MockService) ProfileID(arg0 string) string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProfileID") + ret := m.ctrl.Call(m, "ProfileID", arg0) ret0, _ := ret[0].(string) return ret0 } // ProfileID indicates an expected call of ProfileID. -func (mr *MockServiceMockRecorder) ProfileID() *gomock.Call { +func (mr *MockServiceMockRecorder) ProfileID(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProfileID", reflect.TypeOf((*MockService)(nil).ProfileID)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProfileID", reflect.TypeOf((*MockService)(nil).ProfileID), arg0) } // Run mocks base method. diff --git a/util/testMock/file_service_mock.go b/util/testMock/file_service_mock.go index 4827033d9..18fd6d708 100644 --- a/util/testMock/file_service_mock.go +++ b/util/testMock/file_service_mock.go @@ -17,6 +17,7 @@ import ( types "github.com/gogo/protobuf/types" gomock "go.uber.org/mock/gomock" + domain "github.com/anyproto/anytype-heart/core/domain" files "github.com/anyproto/anytype-heart/core/files" pb "github.com/anyproto/anytype-heart/pb" mill "github.com/anyproto/anytype-heart/pkg/lib/mill" @@ -47,10 +48,10 @@ func (m *MockFileService) EXPECT() *MockFileServiceMockRecorder { } // FileAdd mocks base method. -func (m *MockFileService) FileAdd(arg0 context.Context, arg1 ...files.AddOption) (files.File, error) { +func (m *MockFileService) FileAdd(arg0 context.Context, arg1 string, arg2 ...files.AddOption) (files.File, error) { m.ctrl.T.Helper() - varargs := []any{arg0} - for _, a := range arg1 { + varargs := []any{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "FileAdd", varargs...) @@ -60,14 +61,14 @@ func (m *MockFileService) FileAdd(arg0 context.Context, arg1 ...files.AddOption) } // FileAdd indicates an expected call of FileAdd. -func (mr *MockFileServiceMockRecorder) FileAdd(arg0 any, arg1 ...any) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileAdd(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0}, arg1...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileAdd", reflect.TypeOf((*MockFileService)(nil).FileAdd), varargs...) } // FileByHash mocks base method. -func (m *MockFileService) FileByHash(arg0 context.Context, arg1 string) (files.File, error) { +func (m *MockFileService) FileByHash(arg0 context.Context, arg1 domain.FullID) (files.File, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FileByHash", arg0, arg1) ret0, _ := ret[0].(files.File) @@ -82,7 +83,7 @@ func (mr *MockFileServiceMockRecorder) FileByHash(arg0, arg1 any) *gomock.Call { } // FileGetKeys mocks base method. -func (m *MockFileService) FileGetKeys(arg0 string) (*files.FileKeys, error) { +func (m *MockFileService) FileGetKeys(arg0 domain.FullID) (*files.FileKeys, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FileGetKeys", arg0) ret0, _ := ret[0].(*files.FileKeys) @@ -97,9 +98,9 @@ func (mr *MockFileServiceMockRecorder) FileGetKeys(arg0 any) *gomock.Call { } // FileListOffload mocks base method. -func (m *MockFileService) FileListOffload(arg0 []string, arg1 bool) (uint64, uint64, error) { +func (m *MockFileService) FileListOffload(arg0 context.Context, arg1 []string, arg2 bool) (uint64, uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileListOffload", arg0, arg1) + ret := m.ctrl.Call(m, "FileListOffload", arg0, arg1, arg2) ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(uint64) ret2, _ := ret[2].(error) @@ -107,46 +108,46 @@ func (m *MockFileService) FileListOffload(arg0 []string, arg1 bool) (uint64, uin } // FileListOffload indicates an expected call of FileListOffload. -func (mr *MockFileServiceMockRecorder) FileListOffload(arg0, arg1 any) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileListOffload(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileListOffload", reflect.TypeOf((*MockFileService)(nil).FileListOffload), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileListOffload", reflect.TypeOf((*MockFileService)(nil).FileListOffload), arg0, arg1, arg2) } // FileOffload mocks base method. -func (m *MockFileService) FileOffload(arg0 string, arg1 bool) (uint64, error) { +func (m *MockFileService) FileOffload(arg0 context.Context, arg1 string, arg2 bool) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileOffload", arg0, arg1) + ret := m.ctrl.Call(m, "FileOffload", arg0, arg1, arg2) ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } // FileOffload indicates an expected call of FileOffload. -func (mr *MockFileServiceMockRecorder) FileOffload(arg0, arg1 any) *gomock.Call { +func (mr *MockFileServiceMockRecorder) FileOffload(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileOffload", reflect.TypeOf((*MockFileService)(nil).FileOffload), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileOffload", reflect.TypeOf((*MockFileService)(nil).FileOffload), arg0, arg1, arg2) } // GetSpaceUsage mocks base method. -func (m *MockFileService) GetSpaceUsage(arg0 context.Context) (*pb.RpcFileSpaceUsageResponseUsage, error) { +func (m *MockFileService) GetSpaceUsage(arg0 context.Context, arg1 string) (*pb.RpcFileSpaceUsageResponseUsage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSpaceUsage", arg0) + ret := m.ctrl.Call(m, "GetSpaceUsage", arg0, arg1) ret0, _ := ret[0].(*pb.RpcFileSpaceUsageResponseUsage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSpaceUsage indicates an expected call of GetSpaceUsage. -func (mr *MockFileServiceMockRecorder) GetSpaceUsage(arg0 any) *gomock.Call { +func (mr *MockFileServiceMockRecorder) GetSpaceUsage(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpaceUsage", reflect.TypeOf((*MockFileService)(nil).GetSpaceUsage), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpaceUsage", reflect.TypeOf((*MockFileService)(nil).GetSpaceUsage), arg0, arg1) } // ImageAdd mocks base method. -func (m *MockFileService) ImageAdd(arg0 context.Context, arg1 ...files.AddOption) (files.Image, error) { +func (m *MockFileService) ImageAdd(arg0 context.Context, arg1 string, arg2 ...files.AddOption) (files.Image, error) { m.ctrl.T.Helper() - varargs := []any{arg0} - for _, a := range arg1 { + varargs := []any{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "ImageAdd", varargs...) @@ -156,14 +157,14 @@ func (m *MockFileService) ImageAdd(arg0 context.Context, arg1 ...files.AddOption } // ImageAdd indicates an expected call of ImageAdd. -func (mr *MockFileServiceMockRecorder) ImageAdd(arg0 any, arg1 ...any) *gomock.Call { +func (mr *MockFileServiceMockRecorder) ImageAdd(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0}, arg1...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageAdd", reflect.TypeOf((*MockFileService)(nil).ImageAdd), varargs...) } // ImageByHash mocks base method. -func (m *MockFileService) ImageByHash(arg0 context.Context, arg1 string) (files.Image, error) { +func (m *MockFileService) ImageByHash(arg0 context.Context, arg1 domain.FullID) (files.Image, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ImageByHash", arg0, arg1) ret0, _ := ret[0].(files.Image) @@ -359,12 +360,13 @@ func (m *MockFile) EXPECT() *MockFileMockRecorder { } // Details mocks base method. -func (m *MockFile) Details(arg0 context.Context) (*types.Struct, error) { +func (m *MockFile) Details(arg0 context.Context) (*types.Struct, domain.TypeKey, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Details", arg0) ret0, _ := ret[0].(*types.Struct) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret1, _ := ret[1].(domain.TypeKey) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } // Details indicates an expected call of Details. diff --git a/util/testMock/mockDetailsModifier/dm_mock.go b/util/testMock/mockDetailsModifier/dm_mock.go index 5fdd3758e..7886afce9 100644 --- a/util/testMock/mockDetailsModifier/dm_mock.go +++ b/util/testMock/mockDetailsModifier/dm_mock.go @@ -13,6 +13,8 @@ import ( types "github.com/gogo/protobuf/types" gomock "go.uber.org/mock/gomock" + + session "github.com/anyproto/anytype-heart/core/session" ) // MockDetailsModifier is a mock of DetailsModifier interface. @@ -39,17 +41,17 @@ func (m *MockDetailsModifier) EXPECT() *MockDetailsModifierMockRecorder { } // ModifyDetails mocks base method. -func (m *MockDetailsModifier) ModifyDetails(arg0 string, arg1 func(*types.Struct) (*types.Struct, error)) error { +func (m *MockDetailsModifier) ModifyDetails(arg0 session.Context, arg1 string, arg2 func(*types.Struct) (*types.Struct, error)) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ModifyDetails", arg0, arg1) + ret := m.ctrl.Call(m, "ModifyDetails", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // ModifyDetails indicates an expected call of ModifyDetails. -func (mr *MockDetailsModifierMockRecorder) ModifyDetails(arg0, arg1 any) *gomock.Call { +func (mr *MockDetailsModifierMockRecorder) ModifyDetails(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDetails", reflect.TypeOf((*MockDetailsModifier)(nil).ModifyDetails), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDetails", reflect.TypeOf((*MockDetailsModifier)(nil).ModifyDetails), arg0, arg1, arg2) } // ModifyLocalDetails mocks base method. diff --git a/util/testMock/mockKanban/kanban_mock.go b/util/testMock/mockKanban/kanban_mock.go index 79a5c0463..b19f1b9fa 100644 --- a/util/testMock/mockKanban/kanban_mock.go +++ b/util/testMock/mockKanban/kanban_mock.go @@ -41,18 +41,18 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // Grouper mocks base method. -func (m *MockService) Grouper(arg0 string) (kanban.Grouper, error) { +func (m *MockService) Grouper(arg0, arg1 string) (kanban.Grouper, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Grouper", arg0) + ret := m.ctrl.Call(m, "Grouper", arg0, arg1) ret0, _ := ret[0].(kanban.Grouper) ret1, _ := ret[1].(error) return ret0, ret1 } // Grouper indicates an expected call of Grouper. -func (mr *MockServiceMockRecorder) Grouper(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) Grouper(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Grouper", reflect.TypeOf((*MockService)(nil).Grouper), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Grouper", reflect.TypeOf((*MockService)(nil).Grouper), arg0, arg1) } // Init mocks base method. diff --git a/util/testMock/mockRelation/relation_mock.go b/util/testMock/mockRelation/relation_mock.go deleted file mode 100644 index 9a6ced1ae..000000000 --- a/util/testMock/mockRelation/relation_mock.go +++ /dev/null @@ -1,159 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/relation (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package mockRelation -destination relation_mock.go github.com/anyproto/anytype-heart/core/relation Service -// -// Package mockRelation is a generated GoMock package. -package mockRelation - -import ( - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" - - relation "github.com/anyproto/anytype-heart/core/relation" - relationutils "github.com/anyproto/anytype-heart/core/relation/relationutils" - pbtypes "github.com/anyproto/anytype-heart/util/pbtypes" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// FetchKey mocks base method. -func (m *MockService) FetchKey(arg0 string, arg1 ...relation.FetchOption) (*relationutils.Relation, error) { - m.ctrl.T.Helper() - varargs := []any{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "FetchKey", varargs...) - ret0, _ := ret[0].(*relationutils.Relation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchKey indicates an expected call of FetchKey. -func (mr *MockServiceMockRecorder) FetchKey(arg0 any, arg1 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchKey", reflect.TypeOf((*MockService)(nil).FetchKey), varargs...) -} - -// FetchKeys mocks base method. -func (m *MockService) FetchKeys(arg0 ...string) (relationutils.Relations, error) { - m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "FetchKeys", varargs...) - ret0, _ := ret[0].(relationutils.Relations) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchKeys indicates an expected call of FetchKeys. -func (mr *MockServiceMockRecorder) FetchKeys(arg0 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchKeys", reflect.TypeOf((*MockService)(nil).FetchKeys), arg0...) -} - -// FetchLinks mocks base method. -func (m *MockService) FetchLinks(arg0 pbtypes.RelationLinks) (relationutils.Relations, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchLinks", arg0) - ret0, _ := ret[0].(relationutils.Relations) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchLinks indicates an expected call of FetchLinks. -func (mr *MockServiceMockRecorder) FetchLinks(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchLinks", reflect.TypeOf((*MockService)(nil).FetchLinks), arg0) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// ListAll mocks base method. -func (m *MockService) ListAll(arg0 ...relation.FetchOption) (relationutils.Relations, error) { - m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "ListAll", varargs...) - ret0, _ := ret[0].(relationutils.Relations) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListAll indicates an expected call of ListAll. -func (mr *MockServiceMockRecorder) ListAll(arg0 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAll", reflect.TypeOf((*MockService)(nil).ListAll), arg0...) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} - -// ValidateFormat mocks base method. -func (m *MockService) ValidateFormat(arg0 string, arg1 *types.Value) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ValidateFormat", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// ValidateFormat indicates an expected call of ValidateFormat. -func (mr *MockServiceMockRecorder) ValidateFormat(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateFormat", reflect.TypeOf((*MockService)(nil).ValidateFormat), arg0, arg1) -} diff --git a/util/testMock/mockSource/source_mock.go b/util/testMock/mockSource/source_mock.go index 15b4f51cb..0f2ae028c 100644 --- a/util/testMock/mockSource/source_mock.go +++ b/util/testMock/mockSource/source_mock.go @@ -18,9 +18,9 @@ import ( state "github.com/anyproto/anytype-heart/core/block/editor/state" source "github.com/anyproto/anytype-heart/core/block/source" + domain "github.com/anyproto/anytype-heart/core/domain" pb "github.com/anyproto/anytype-heart/pb" smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) // MockService is a mock of Service interface. @@ -62,18 +62,18 @@ func (mr *MockServiceMockRecorder) DetailsFromIdBasedSource(arg0 any) *gomock.Ca } // IDsListerBySmartblockType mocks base method. -func (m *MockService) IDsListerBySmartblockType(arg0 smartblock.SmartBlockType) (source.IDsLister, error) { +func (m *MockService) IDsListerBySmartblockType(arg0 string, arg1 smartblock.SmartBlockType) (source.IDsLister, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IDsListerBySmartblockType", arg0) + ret := m.ctrl.Call(m, "IDsListerBySmartblockType", arg0, arg1) ret0, _ := ret[0].(source.IDsLister) ret1, _ := ret[1].(error) return ret0, ret1 } // IDsListerBySmartblockType indicates an expected call of IDsListerBySmartblockType. -func (mr *MockServiceMockRecorder) IDsListerBySmartblockType(arg0 any) *gomock.Call { +func (mr *MockServiceMockRecorder) IDsListerBySmartblockType(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDsListerBySmartblockType", reflect.TypeOf((*MockService)(nil).IDsListerBySmartblockType), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDsListerBySmartblockType", reflect.TypeOf((*MockService)(nil).IDsListerBySmartblockType), arg0, arg1) } // Init mocks base method. @@ -120,7 +120,7 @@ func (mr *MockServiceMockRecorder) NewSource(arg0, arg1, arg2, arg3 any) *gomock } // NewStaticSource mocks base method. -func (m *MockService) NewStaticSource(arg0 string, arg1 model.SmartBlockType, arg2 *state.State, arg3 func(source.PushChangeParams) (string, error)) source.SourceWithType { +func (m *MockService) NewStaticSource(arg0 domain.FullID, arg1 smartblock.SmartBlockType, arg2 *state.State, arg3 func(source.PushChangeParams) (string, error)) source.SourceWithType { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewStaticSource", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(source.SourceWithType) @@ -134,15 +134,17 @@ func (mr *MockServiceMockRecorder) NewStaticSource(arg0, arg1, arg2, arg3 any) * } // RegisterStaticSource mocks base method. -func (m *MockService) RegisterStaticSource(arg0 string, arg1 source.Source) { +func (m *MockService) RegisterStaticSource(arg0 source.Source) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "RegisterStaticSource", arg0, arg1) + ret := m.ctrl.Call(m, "RegisterStaticSource", arg0) + ret0, _ := ret[0].(error) + return ret0 } // RegisterStaticSource indicates an expected call of RegisterStaticSource. -func (mr *MockServiceMockRecorder) RegisterStaticSource(arg0, arg1 any) *gomock.Call { +func (mr *MockServiceMockRecorder) RegisterStaticSource(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterStaticSource", reflect.TypeOf((*MockService)(nil).RegisterStaticSource), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterStaticSource", reflect.TypeOf((*MockService)(nil).RegisterStaticSource), arg0) } // RemoveStaticSource mocks base method. @@ -280,11 +282,25 @@ func (mr *MockSourceMockRecorder) ReadOnly() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadOnly", reflect.TypeOf((*MockSource)(nil).ReadOnly)) } +// SpaceID mocks base method. +func (m *MockSource) SpaceID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SpaceID") + ret0, _ := ret[0].(string) + return ret0 +} + +// SpaceID indicates an expected call of SpaceID. +func (mr *MockSourceMockRecorder) SpaceID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceID", reflect.TypeOf((*MockSource)(nil).SpaceID)) +} + // Type mocks base method. -func (m *MockSource) Type() model.SmartBlockType { +func (m *MockSource) Type() smartblock.SmartBlockType { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Type") - ret0, _ := ret[0].(model.SmartBlockType) + ret0, _ := ret[0].(smartblock.SmartBlockType) return ret0 } diff --git a/util/testMock/objectstore_mock.go b/util/testMock/objectstore_mock.go index 50864cf3c..64d5aa1b5 100644 --- a/util/testMock/objectstore_mock.go +++ b/util/testMock/objectstore_mock.go @@ -21,7 +21,6 @@ import ( database "github.com/anyproto/anytype-heart/pkg/lib/database" ftsearch "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - schema "github.com/anyproto/anytype-heart/pkg/lib/schema" ) // MockObjectStore is a mock of ObjectStore interface. @@ -146,38 +145,19 @@ func (mr *MockObjectStoreMockRecorder) GetAccountStatus() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountStatus", reflect.TypeOf((*MockObjectStore)(nil).GetAccountStatus)) } -// GetAggregatedOptions mocks base method. -func (m *MockObjectStore) GetAggregatedOptions(arg0 string) ([]*model.RelationOption, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAggregatedOptions", arg0) - ret0, _ := ret[0].([]*model.RelationOption) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAggregatedOptions indicates an expected call of GetAggregatedOptions. -func (mr *MockObjectStoreMockRecorder) GetAggregatedOptions(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAggregatedOptions", reflect.TypeOf((*MockObjectStore)(nil).GetAggregatedOptions), arg0) -} - // GetByIDs mocks base method. -func (m *MockObjectStore) GetByIDs(arg0 ...string) ([]*model.ObjectInfo, error) { +func (m *MockObjectStore) GetByIDs(arg0 string, arg1 []string) ([]*model.ObjectInfo, error) { m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetByIDs", varargs...) + ret := m.ctrl.Call(m, "GetByIDs", arg0, arg1) ret0, _ := ret[0].([]*model.ObjectInfo) ret1, _ := ret[1].(error) return ret0, ret1 } // GetByIDs indicates an expected call of GetByIDs. -func (mr *MockObjectStoreMockRecorder) GetByIDs(arg0 ...any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetByIDs(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockObjectStore)(nil).GetByIDs), arg0...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockObjectStore)(nil).GetByIDs), arg0, arg1) } // GetChecksums mocks base method. @@ -195,21 +175,6 @@ func (mr *MockObjectStoreMockRecorder) GetChecksums() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChecksums", reflect.TypeOf((*MockObjectStore)(nil).GetChecksums)) } -// GetCurrentWorkspaceID mocks base method. -func (m *MockObjectStore) GetCurrentWorkspaceID() (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentWorkspaceID") - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentWorkspaceID indicates an expected call of GetCurrentWorkspaceID. -func (mr *MockObjectStoreMockRecorder) GetCurrentWorkspaceID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentWorkspaceID", reflect.TypeOf((*MockObjectStore)(nil).GetCurrentWorkspaceID)) -} - // GetDetails mocks base method. func (m *MockObjectStore) GetDetails(arg0 string) (*model.ObjectDetails, error) { m.ctrl.T.Helper() @@ -255,36 +220,6 @@ func (mr *MockObjectStoreMockRecorder) GetLastIndexedHeadsHash(arg0 any) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).GetLastIndexedHeadsHash), arg0) } -// GetObjectType mocks base method. -func (m *MockObjectStore) GetObjectType(arg0 string) (*model.ObjectType, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetObjectType", arg0) - ret0, _ := ret[0].(*model.ObjectType) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetObjectType indicates an expected call of GetObjectType. -func (mr *MockObjectStoreMockRecorder) GetObjectType(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectType", reflect.TypeOf((*MockObjectStore)(nil).GetObjectType), arg0) -} - -// GetObjectTypes mocks base method. -func (m *MockObjectStore) GetObjectTypes(arg0 []string) ([]*model.ObjectType, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetObjectTypes", arg0) - ret0, _ := ret[0].([]*model.ObjectType) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetObjectTypes indicates an expected call of GetObjectTypes. -func (mr *MockObjectStoreMockRecorder) GetObjectTypes(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTypes", reflect.TypeOf((*MockObjectStore)(nil).GetObjectTypes), arg0) -} - // GetOutboundLinksByID mocks base method. func (m *MockObjectStore) GetOutboundLinksByID(arg0 string) ([]string, error) { m.ctrl.T.Helper() @@ -300,49 +235,19 @@ func (mr *MockObjectStoreMockRecorder) GetOutboundLinksByID(arg0 any) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOutboundLinksByID", reflect.TypeOf((*MockObjectStore)(nil).GetOutboundLinksByID), arg0) } -// GetRelationByID mocks base method. -func (m *MockObjectStore) GetRelationByID(arg0 string) (*model.Relation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationByID", arg0) - ret0, _ := ret[0].(*model.Relation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRelationByID indicates an expected call of GetRelationByID. -func (mr *MockObjectStoreMockRecorder) GetRelationByID(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByID", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByID), arg0) -} - -// GetRelationByKey mocks base method. -func (m *MockObjectStore) GetRelationByKey(arg0 string) (*model.Relation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationByKey", arg0) - ret0, _ := ret[0].(*model.Relation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRelationByKey indicates an expected call of GetRelationByKey. -func (mr *MockObjectStoreMockRecorder) GetRelationByKey(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByKey), arg0) -} - // GetWithLinksInfoByID mocks base method. -func (m *MockObjectStore) GetWithLinksInfoByID(arg0 string) (*model.ObjectInfoWithLinks, error) { +func (m *MockObjectStore) GetWithLinksInfoByID(arg0, arg1 string) (*model.ObjectInfoWithLinks, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetWithLinksInfoByID", arg0) + ret := m.ctrl.Call(m, "GetWithLinksInfoByID", arg0, arg1) ret0, _ := ret[0].(*model.ObjectInfoWithLinks) ret1, _ := ret[1].(error) return ret0, ret1 } // GetWithLinksInfoByID indicates an expected call of GetWithLinksInfoByID. -func (mr *MockObjectStoreMockRecorder) GetWithLinksInfoByID(arg0 any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetWithLinksInfoByID(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWithLinksInfoByID", reflect.TypeOf((*MockObjectStore)(nil).GetWithLinksInfoByID), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWithLinksInfoByID", reflect.TypeOf((*MockObjectStore)(nil).GetWithLinksInfoByID), arg0, arg1) } // HasIDs mocks base method. @@ -364,21 +269,6 @@ func (mr *MockObjectStoreMockRecorder) HasIDs(arg0 ...any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasIDs", reflect.TypeOf((*MockObjectStore)(nil).HasIDs), arg0...) } -// HasObjectType mocks base method. -func (m *MockObjectStore) HasObjectType(arg0 string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HasObjectType", arg0) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// HasObjectType indicates an expected call of HasObjectType. -func (mr *MockObjectStoreMockRecorder) HasObjectType(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasObjectType", reflect.TypeOf((*MockObjectStore)(nil).HasObjectType), arg0) -} - // Init mocks base method. func (m *MockObjectStore) Init(arg0 *app.App) error { m.ctrl.T.Helper() @@ -394,18 +284,18 @@ func (mr *MockObjectStoreMockRecorder) Init(arg0 any) *gomock.Call { } // List mocks base method. -func (m *MockObjectStore) List() ([]*model.ObjectInfo, error) { +func (m *MockObjectStore) List(arg0 string) ([]*model.ObjectInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List") + ret := m.ctrl.Call(m, "List", arg0) ret0, _ := ret[0].([]*model.ObjectInfo) ret1, _ := ret[1].(error) return ret0, ret1 } // List indicates an expected call of List. -func (mr *MockObjectStoreMockRecorder) List() *gomock.Call { +func (mr *MockObjectStoreMockRecorder) List(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockObjectStore)(nil).List)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockObjectStore)(nil).List), arg0) } // ListIDsFromFullTextQueue mocks base method. @@ -453,9 +343,9 @@ func (mr *MockObjectStoreMockRecorder) Name() *gomock.Call { } // Query mocks base method. -func (m *MockObjectStore) Query(arg0 schema.Schema, arg1 database.Query) ([]database.Record, int, error) { +func (m *MockObjectStore) Query(arg0 database.Query) ([]database.Record, int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Query", arg0, arg1) + ret := m.ctrl.Call(m, "Query", arg0) ret0, _ := ret[0].([]database.Record) ret1, _ := ret[1].(int) ret2, _ := ret[2].(error) @@ -463,9 +353,9 @@ func (m *MockObjectStore) Query(arg0 schema.Schema, arg1 database.Query) ([]data } // Query indicates an expected call of Query. -func (mr *MockObjectStoreMockRecorder) Query(arg0, arg1 any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) Query(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockObjectStore)(nil).Query), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockObjectStore)(nil).Query), arg0) } // QueryByID mocks base method. @@ -530,20 +420,6 @@ func (mr *MockObjectStoreMockRecorder) QueryRaw(arg0, arg1, arg2 any) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryRaw", reflect.TypeOf((*MockObjectStore)(nil).QueryRaw), arg0, arg1, arg2) } -// RemoveCurrentWorkspaceID mocks base method. -func (m *MockObjectStore) RemoveCurrentWorkspaceID() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoveCurrentWorkspaceID") - ret0, _ := ret[0].(error) - return ret0 -} - -// RemoveCurrentWorkspaceID indicates an expected call of RemoveCurrentWorkspaceID. -func (mr *MockObjectStoreMockRecorder) RemoveCurrentWorkspaceID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveCurrentWorkspaceID", reflect.TypeOf((*MockObjectStore)(nil).RemoveCurrentWorkspaceID)) -} - // RemoveIDsFromFullTextQueue mocks base method. func (m *MockObjectStore) RemoveIDsFromFullTextQueue(arg0 []string) { m.ctrl.T.Helper() @@ -612,20 +488,6 @@ func (mr *MockObjectStoreMockRecorder) SaveLastIndexedHeadsHash(arg0, arg1 any) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).SaveLastIndexedHeadsHash), arg0, arg1) } -// SetCurrentWorkspaceID mocks base method. -func (m *MockObjectStore) SetCurrentWorkspaceID(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetCurrentWorkspaceID", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetCurrentWorkspaceID indicates an expected call of SetCurrentWorkspaceID. -func (mr *MockObjectStoreMockRecorder) SetCurrentWorkspaceID(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentWorkspaceID", reflect.TypeOf((*MockObjectStore)(nil).SetCurrentWorkspaceID), arg0) -} - // SubscribeForAll mocks base method. func (m *MockObjectStore) SubscribeForAll(arg0 func(database.Record)) { m.ctrl.T.Helper() diff --git a/util/testMock/sbt_provider_mock.go b/util/testMock/sbt_provider_mock.go index cc5856195..8e51e0778 100644 --- a/util/testMock/sbt_provider_mock.go +++ b/util/testMock/sbt_provider_mock.go @@ -68,6 +68,21 @@ func (mr *MockSmartBlockTypeProviderMockRecorder) Name() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Name)) } +// PartitionIDsByType mocks base method. +func (m *MockSmartBlockTypeProvider) PartitionIDsByType(arg0 string, arg1 []string) (map[smartblock.SmartBlockType][]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PartitionIDsByType", arg0, arg1) + ret0, _ := ret[0].(map[smartblock.SmartBlockType][]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PartitionIDsByType indicates an expected call of PartitionIDsByType. +func (mr *MockSmartBlockTypeProviderMockRecorder) PartitionIDsByType(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PartitionIDsByType", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).PartitionIDsByType), arg0, arg1) +} + // RegisterStaticType mocks base method. func (m *MockSmartBlockTypeProvider) RegisterStaticType(arg0 string, arg1 smartblock.SmartBlockType) { m.ctrl.T.Helper() @@ -81,16 +96,16 @@ func (mr *MockSmartBlockTypeProviderMockRecorder) RegisterStaticType(arg0, arg1 } // Type mocks base method. -func (m *MockSmartBlockTypeProvider) Type(arg0 string) (smartblock.SmartBlockType, error) { +func (m *MockSmartBlockTypeProvider) Type(arg0, arg1 string) (smartblock.SmartBlockType, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Type", arg0) + ret := m.ctrl.Call(m, "Type", arg0, arg1) ret0, _ := ret[0].(smartblock.SmartBlockType) ret1, _ := ret[1].(error) return ret0, ret1 } // Type indicates an expected call of Type. -func (mr *MockSmartBlockTypeProviderMockRecorder) Type(arg0 any) *gomock.Call { +func (mr *MockSmartBlockTypeProviderMockRecorder) Type(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Type), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Type), arg0, arg1) } From 7aa6140ab36be8dd8c30038066db9da0dc0482bf Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 21:24:36 +0500 Subject: [PATCH 16/22] Make links migration temporary --- core/block/editor/page.go | 8 +------- core/block/editor/widget.go | 8 +------- core/block/source/source.go | 9 +++++++++ .../{editor => source}/sub_object_links_migration.go | 2 +- .../sub_object_links_migration_test.go | 2 +- 5 files changed, 13 insertions(+), 16 deletions(-) rename core/block/{editor => source}/sub_object_links_migration.go (99%) rename core/block/{editor => source}/sub_object_links_migration_test.go (98%) diff --git a/core/block/editor/page.go b/core/block/editor/page.go index 1b127d980..73bc287c6 100644 --- a/core/block/editor/page.go +++ b/core/block/editor/page.go @@ -193,13 +193,7 @@ func (p *Page) CreationStateMigration(ctx *smartblock.InitContext) migration.Mig } func (p *Page) StateMigrations() migration.Migrations { - dataviewMigration := newSubObjectsLinksMigration(p.SpaceID(), p.systemObjectService) - return migration.MakeMigrations([]migration.Migration{ - { - Version: 2, - Proc: dataviewMigration.migrate, - }, - }) + return migration.MakeMigrations(nil) } func GetDefaultViewRelations(rels []*model.Relation) []*model.BlockContentDataviewRelation { diff --git a/core/block/editor/widget.go b/core/block/editor/widget.go index 0ef3e9b17..8caf59eab 100644 --- a/core/block/editor/widget.go +++ b/core/block/editor/widget.go @@ -99,13 +99,7 @@ func (w *WidgetObject) withDefaultWidgets(st *state.State) { } func (w *WidgetObject) StateMigrations() migration.Migrations { - dataviewMigration := newSubObjectsLinksMigration(w.SpaceID(), w.systemObjectService) - return migration.MakeMigrations([]migration.Migration{ - { - Version: 2, - Proc: dataviewMigration.migrate, - }, - }) + return migration.MakeMigrations(nil) } func (w *WidgetObject) Unlink(ctx session.Context, ids ...string) (err error) { diff --git a/core/block/source/source.go b/core/block/source/source.go index a9390724e..293f7420e 100644 --- a/core/block/source/source.go +++ b/core/block/source/source.go @@ -214,6 +214,15 @@ func (s *source) buildState() (doc state.Doc, err error) { } st.BlocksInit(st) + // This is temporary migration. We will move it to persistent migration later after several releases. + // The reason is to minimize the number of glitches for users of both old and new versions of Anytype. + // For example, if we persist this migration for Dataview block now, user will see "No query selected" + // error in the old version of Anytype. We want to avoid this as much as possible by making this migration + // temporary, though the applying change to this Dataview block will persist this migration, breaking backward + // compatibility. But in many cases we expect that users update object not so often as they just view them. + migration := newSubObjectsLinksMigration(s.spaceID, s.systemObjectService) + migration.migrate(st) + s.changesSinceSnapshot = changesAppliedSinceSnapshot // TODO: check if we can leave only removeDuplicates instead of Normalize if err = st.Normalize(false); err != nil { diff --git a/core/block/editor/sub_object_links_migration.go b/core/block/source/sub_object_links_migration.go similarity index 99% rename from core/block/editor/sub_object_links_migration.go rename to core/block/source/sub_object_links_migration.go index a48e4fbc8..8cf3ee323 100644 --- a/core/block/editor/sub_object_links_migration.go +++ b/core/block/source/sub_object_links_migration.go @@ -1,4 +1,4 @@ -package editor +package source import ( "context" diff --git a/core/block/editor/sub_object_links_migration_test.go b/core/block/source/sub_object_links_migration_test.go similarity index 98% rename from core/block/editor/sub_object_links_migration_test.go rename to core/block/source/sub_object_links_migration_test.go index 19bbd2952..baa4fbc12 100644 --- a/core/block/editor/sub_object_links_migration_test.go +++ b/core/block/source/sub_object_links_migration_test.go @@ -1,4 +1,4 @@ -package editor +package source import ( "testing" From c991bb2667045c5a51f7477dbbf22a4329b1c2e4 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 2 Oct 2023 21:39:09 +0500 Subject: [PATCH 17/22] Make sub-object migration temporary --- core/block/editor/sub_objects_migration.go | 6 +++--- core/block/editor/workspaces.go | 19 +++++++------------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/core/block/editor/sub_objects_migration.go b/core/block/editor/sub_objects_migration.go index 8122baf6a..9bc3ff0ba 100644 --- a/core/block/editor/sub_objects_migration.go +++ b/core/block/editor/sub_objects_migration.go @@ -24,8 +24,9 @@ type subObjectsMigration struct { objectDeriver objectDeriver } -func (m *subObjectsMigration) migrateSubObjects(_ *state.State) { +func (m *subObjectsMigration) migrateSubObjects(st *state.State) { m.iterateAllSubObjects( + st, func(info smartblock.DocInfo) { uniqueKeyRaw := pbtypes.GetString(info.Details, bundle.RelationKeyUniqueKey.String()) id, err := m.migrateSubObject(context.Background(), uniqueKeyRaw, info.Details, info.Type) @@ -87,8 +88,7 @@ func collectionKeyToTypeKey(collKey string) (domain.TypeKey, bool) { return "", false } -func (m *subObjectsMigration) iterateAllSubObjects(proc func(smartblock.DocInfo)) { - st := m.workspace.NewState() +func (m *subObjectsMigration) iterateAllSubObjects(st *state.State, proc func(smartblock.DocInfo)) { for typeKey, coll := range objectTypeToCollection { collection := st.GetSubObjectCollection(coll) if collection == nil { diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index 88c4dee4a..bd9ab3928 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -83,6 +83,12 @@ func (w *Workspaces) Init(ctx *smartblock.InitContext) (err error) { } w.initTemplate(ctx) + subObjectMigration := subObjectsMigration{ + workspace: w, + objectDeriver: w.objectDeriver, + } + subObjectMigration.migrateSubObjects(ctx.State) + return nil } @@ -119,16 +125,5 @@ func (w *Workspaces) CreationStateMigration(ctx *smartblock.InitContext) migrati } func (w *Workspaces) StateMigrations() migration.Migrations { - return migration.MakeMigrations([]migration.Migration{ - { - Version: 1, - Proc: func(st *state.State) { - subObjectMigration := subObjectsMigration{ - workspace: w, - objectDeriver: w.objectDeriver, - } - subObjectMigration.migrateSubObjects(st) - }, - }, - }) + return migration.MakeMigrations(nil) } From e88c099c0df0799815339887a6a12cfba4f56011 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 2 Oct 2023 21:44:44 +0200 Subject: [PATCH 18/22] GO-2030 Fix space view creation --- space/techspace.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/space/techspace.go b/space/techspace.go index 7b74d2f12..295221712 100644 --- a/space/techspace.go +++ b/space/techspace.go @@ -43,10 +43,10 @@ func (s *techSpace) CreateSpaceView(ctx context.Context, spaceID string) (spaceV if err != nil { return } - obj, err := s.service.objectCache.DeriveTreeObject(ctx, spaceID, objectcache.TreeDerivationParams{ + obj, err := s.service.objectCache.DeriveTreeObject(ctx, s.techCore.Id(), objectcache.TreeDerivationParams{ Key: uniqueKey, InitFunc: func(id string) *editorsb.InitContext { - return &editorsb.InitContext{Ctx: ctx, SpaceID: spaceID, State: state.NewDoc(id, nil).(*state.State)} + return &editorsb.InitContext{Ctx: ctx, SpaceID: s.techCore.Id(), State: state.NewDoc(id, nil).(*state.State)} }, TargetSpaceID: spaceID, }) From cd8a85acff18308a594ccb8cb46d413fc7886876 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 2 Oct 2023 21:50:39 +0200 Subject: [PATCH 19/22] GO-2030 Tech space start sync --- space/techspace.go | 1 + 1 file changed, 1 insertion(+) diff --git a/space/techspace.go b/space/techspace.go index 295221712..ccdcacef9 100644 --- a/space/techspace.go +++ b/space/techspace.go @@ -35,6 +35,7 @@ func (s *techSpace) wakeUpViews(ctx context.Context) (err error) { return nil }) } + s.techCore.TreeSyncer().StartSync() return } From d3de2fbafeb18ee811c2a98c949d7f48eb8365ed Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 2 Oct 2023 22:21:44 +0200 Subject: [PATCH 20/22] GO-2030 Get rep key from personal id --- space/service.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/space/service.go b/space/service.go index b62b3b0ee..2f2966919 100644 --- a/space/service.go +++ b/space/service.go @@ -2,6 +2,9 @@ package space import ( "context" + "errors" + "strconv" + "strings" "sync" "github.com/anyproto/any-sync/app" @@ -21,6 +24,8 @@ const CName = "client.space" var log = logger.NewNamed(CName) +var ErrIncorrectSpaceID = errors.New("incorrect space id") + func New() SpaceService { return &service{} } @@ -88,7 +93,11 @@ func (s *service) Run(ctx context.Context) (err error) { if err != nil { return } - + // TODO: move this logic to any-sync + s.repKey, err = getRepKey(s.personalSpaceID) + if err != nil { + return + } techSpaceCore, err := s.spaceCore.Derive(ctx, spacecore.TechSpaceType) if err != nil { return @@ -173,3 +182,11 @@ func (s *service) Close(ctx context.Context) (err error) { } return nil } + +func getRepKey(spaceID string) (uint64, error) { + sepIdx := strings.Index(spaceID, ".") + if sepIdx == -1 { + return 0, ErrIncorrectSpaceID + } + return strconv.ParseUint(spaceID[sepIdx+1:], 36, 64) +} From 45d02c7256736e0cf9eadbddd93572fa88276f6e Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 3 Oct 2023 11:05:44 +0500 Subject: [PATCH 21/22] Small refactoring --- core/block/editor/smartblock/smartblock.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/core/block/editor/smartblock/smartblock.go b/core/block/editor/smartblock/smartblock.go index b258b0b6f..31e9d1102 100644 --- a/core/block/editor/smartblock/smartblock.go +++ b/core/block/editor/smartblock/smartblock.go @@ -656,7 +656,7 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { lastModified = time.Unix(pbtypes.GetInt64(s.LocalDetails(), bundle.RelationKeyLastModifiedDate.String()), 0) } } - sb.onApply(s) + sb.beforeStateApply(s) // this one will be reverted in case we don't have any actual change being made s.SetLastModified(lastModified.Unix(), sb.coreService.PredefinedObjects(sb.SpaceID()).Profile) @@ -1303,7 +1303,7 @@ func (sb *smartBlock) runIndexer(s *state.State, opts ...IndexOption) { } } -func (sb *smartBlock) onApply(s *state.State) { +func (sb *smartBlock) beforeStateApply(s *state.State) { flags := internalflag.NewFromState(s) // Run empty check only if any of these flags are present @@ -1323,14 +1323,16 @@ func (sb *smartBlock) onApply(s *state.State) { } func (sb *smartBlock) setRestrictionsDetail(s *state.State) { - var ints = make([]int, len(sb.Restrictions().Object)) - for i, v := range sb.Restrictions().Object { - ints[i] = int(v) + rawRestrictions := make([]int, len(sb.Restrictions().Object)) + for i, r := range sb.Restrictions().Object { + rawRestrictions[i] = int(r) } - s.SetLocalDetail(bundle.RelationKeyRestrictions.String(), pbtypes.IntList(ints...)) + s.SetLocalDetail(bundle.RelationKeyRestrictions.String(), pbtypes.IntList(rawRestrictions...)) // todo: verify this logic with clients - if sb.Restrictions().Object.Check(model.Restrictions_Details) != nil && sb.Restrictions().Object.Check(model.Restrictions_Blocks) != nil { + if sb.Restrictions().Object.Check(model.Restrictions_Details) != nil && + sb.Restrictions().Object.Check(model.Restrictions_Blocks) != nil { + s.SetDetailAndBundledRelation(bundle.RelationKeyIsReadonly, pbtypes.Bool(true)) } } From 58c9c020932bad164646420ae204faec37c87ea7 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 3 Oct 2023 14:21:32 +0500 Subject: [PATCH 22/22] Fix after merge --- core/block/editor/sub_objects_migration.go | 24 ++++++++------- core/block/editor/workspaces.go | 2 +- core/block/object/treesyncer/treesyncer.go | 1 - go.sum | 34 ++++++++++------------ pkg/lib/pb/model/models.pb.go | 5 ++-- space/spacecore/streamhandler.go | 2 +- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/core/block/editor/sub_objects_migration.go b/core/block/editor/sub_objects_migration.go index 9bc3ff0ba..55f2e0316 100644 --- a/core/block/editor/sub_objects_migration.go +++ b/core/block/editor/sub_objects_migration.go @@ -8,6 +8,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/object/objectcache" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" smartblock2 "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" @@ -15,7 +16,7 @@ import ( ) type objectDeriver interface { - DeriveTreeObjectWithUniqueKey(ctx context.Context, spaceID string, key domain.UniqueKey, initFunc smartblock.InitFunc) (sb smartblock.SmartBlock, err error) + DeriveTreeObject(ctx context.Context, spaceID string, params objectcache.TreeDerivationParams) (sb smartblock.SmartBlock, err error) } // Migrate legacy sub-objects to ordinary objects @@ -50,15 +51,18 @@ func (m *subObjectsMigration) migrateSubObject( if err != nil { return "", fmt.Errorf("unmarshal unique key: %w", err) } - sb, err := m.objectDeriver.DeriveTreeObjectWithUniqueKey(ctx, m.workspace.SpaceID(), uniqueKey, func(id string) *smartblock.InitContext { - st := state.NewDocWithUniqueKey(id, nil, uniqueKey).NewState() - st.SetDetails(details) - st.SetObjectTypeKey(typeKey) - return &smartblock.InitContext{ - IsNewObject: true, - State: st, - SpaceID: m.workspace.SpaceID(), - } + sb, err := m.objectDeriver.DeriveTreeObject(ctx, m.workspace.SpaceID(), objectcache.TreeDerivationParams{ + Key: uniqueKey, + InitFunc: func(id string) *smartblock.InitContext { + st := state.NewDocWithUniqueKey(id, nil, uniqueKey).NewState() + st.SetDetails(details) + st.SetObjectTypeKey(typeKey) + return &smartblock.InitContext{ + IsNewObject: true, + State: st, + SpaceID: m.workspace.SpaceID(), + } + }, }) if err != nil { return "", err diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index bd9ab3928..5ba8b9829 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -19,7 +19,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/core" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - "github.com/anyproto/anytype-heart/space/typeprovider" + "github.com/anyproto/anytype-heart/space/spacecore/typeprovider" "github.com/anyproto/anytype-heart/util/pbtypes" ) diff --git a/core/block/object/treesyncer/treesyncer.go b/core/block/object/treesyncer/treesyncer.go index 5dad55369..22a9019c8 100644 --- a/core/block/object/treesyncer/treesyncer.go +++ b/core/block/object/treesyncer/treesyncer.go @@ -12,7 +12,6 @@ import ( "github.com/anyproto/any-sync/commonspace/object/treesyncer" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/streampool" - "go.uber.org/zap" ) diff --git a/go.sum b/go.sum index b66d10eb0..2876df6b9 100644 --- a/go.sum +++ b/go.sum @@ -81,8 +81,8 @@ github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY= github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= -github.com/anyproto/any-sync v0.3.0-alpha.2 h1:eOJuED567lmwiO5NwJQrNwDafpaauTZsVDwXKvT+boM= -github.com/anyproto/any-sync v0.3.0-alpha.2/go.mod h1:NTXTvHr1W8f5dJFbMQNPoyMWeTSjXM10cj4qCUacvJU= +github.com/anyproto/any-sync v0.3.2-0.20230927204133-ce7bce7e4809 h1:aSyqpncSvTgSBhT72qU7eCGEnyvZNFRJpNOnowJwTFA= +github.com/anyproto/any-sync v0.3.2-0.20230927204133-ce7bce7e4809/go.mod h1:v0w3l3FBWjzNgg5t8aWlI+aYkcA8kLaoJFfr/GHsWYk= github.com/anyproto/go-chash v0.1.0 h1:I9meTPjXFRfXZHRJzjOHC/XF7Q5vzysKkiT/grsogXY= github.com/anyproto/go-chash v0.1.0/go.mod h1:0UjNQi3PDazP0fINpFYu6VKhuna+W/V+1vpXHAfNgLY= github.com/anyproto/go-gelf v0.0.0-20210418191311-774bd5b016e7 h1:SyEu5uxZ5nKHEJ6TPKQqjM+T00SYi0MW1VaLzqZtZ9E= @@ -303,7 +303,7 @@ github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJn github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -563,8 +563,8 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= -github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= +github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= @@ -574,8 +574,8 @@ github.com/ipfs/go-bitswap v0.3.4/go.mod h1:4T7fvNv/LmOys+21tnLzGKncMeeXUYUd1nUi github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= -github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= +github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= +github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.1.4/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -638,8 +638,6 @@ github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= -github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= @@ -669,8 +667,8 @@ github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9 github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -766,8 +764,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= -github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= -github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= +github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= +github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= @@ -1170,10 +1168,10 @@ github.com/pseudomuto/protoc-gen-doc v1.5.1/go.mod h1:XpMKYg6zkcpgfpCfQ8GcWBDRtR github.com/pseudomuto/protokit v0.2.1 h1:kCYpE3thoR6Esm0CUvd5xbrDTOZPvQPTDeyXpZfrJdk= github.com/pseudomuto/protokit v0.2.1/go.mod h1:gt7N5Rz2flBzYafvaxyIxMZC0TTF5jDZfRnw25hAAyo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= -github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= -github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= +github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= +github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -1305,7 +1303,7 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vektra/mockery/v2 v2.34.1 h1:H+wO4wTRlBjdY3yFUjv53GazCaDSEfhRKJugyo2aoNc= github.com/vektra/mockery/v2 v2.34.1/go.mod h1:9lREs4VEeQiUS3rizYQx1saxHu2JiIhThP0q9+fDegM= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= diff --git a/pkg/lib/pb/model/models.pb.go b/pkg/lib/pb/model/models.pb.go index eb93fceec..ec50beebd 100644 --- a/pkg/lib/pb/model/models.pb.go +++ b/pkg/lib/pb/model/models.pb.go @@ -5,11 +5,12 @@ package model import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" - types "github.com/gogo/protobuf/types" io "io" math "math" math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" + types "github.com/gogo/protobuf/types" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/space/spacecore/streamhandler.go b/space/spacecore/streamhandler.go index 69677ecdf..a99d1e9c1 100644 --- a/space/spacecore/streamhandler.go +++ b/space/spacecore/streamhandler.go @@ -2,13 +2,13 @@ package spacecore import ( "errors" - "go.uber.org/zap" "sync/atomic" "time" "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/net/peer" + "go.uber.org/zap" "golang.org/x/net/context" "storj.io/drpc" )