diff --git a/core/block/source/service.go b/core/block/source/service.go index 4db5f6056b..e0c4bfe860 100644 --- a/core/block/source/service.go +++ b/core/block/source/service.go @@ -40,6 +40,7 @@ type accountService interface { type Space interface { Id() string + IsPersonal() bool TreeBuilder() objecttreebuilder.TreeBuilder GetRelationIdByKey(ctx context.Context, key domain.RelationKey) (id string, err error) GetTypeIdByKey(ctx context.Context, key domain.TypeKey) (id string, err error) diff --git a/core/block/source/source.go b/core/block/source/source.go index 6267c86e60..7c0934894e 100644 --- a/core/block/source/source.go +++ b/core/block/source/source.go @@ -171,7 +171,7 @@ type fileObjectMigrator interface { } type RelationGetter interface { - GetRelationByKey(key string) (*model.Relation, error) + GetRelationByKey(spaceId string, key string) (*model.Relation, error) } type source struct { diff --git a/core/block/source/sub_object_links_migration.go b/core/block/source/sub_object_links_migration.go index 3e3dd63fb7..d4564d31e0 100644 --- a/core/block/source/sub_object_links_migration.go +++ b/core/block/source/sub_object_links_migration.go @@ -91,7 +91,12 @@ func (m *subObjectsAndProfileLinksMigration) replaceLinksInDetails(s *state.Stat } } +// Migrate works only in personal space func (m *subObjectsAndProfileLinksMigration) Migrate(s *state.State) { + if !m.space.IsPersonal() { + return + } + uk, err := domain.NewUniqueKey(smartblock.SmartBlockTypeProfilePage, "") if err != nil { log.Errorf("migration: failed to create unique key for profile: %s", err) @@ -187,7 +192,7 @@ func (m *subObjectsAndProfileLinksMigration) migrateFilter(filter *model.BlockCo log.With("relationKey", filter.RelationKey).Warnf("empty filter value") return nil } - relation, err := m.objectStore.GetRelationByKey(filter.RelationKey) + relation, err := m.objectStore.GetRelationByKey(m.space.Id(), filter.RelationKey) if err != nil { log.Warnf("migration: failed to get relation by key %s: %s", filter.RelationKey, err) } diff --git a/core/subscription/dep.go b/core/subscription/dep.go index 79b91ed879..651a7e2f36 100644 --- a/core/subscription/dep.go +++ b/core/subscription/dep.go @@ -122,12 +122,12 @@ func (ds *dependencyService) isRelationObject(key string) bool { if isObj, ok := ds.isRelationObjMap[key]; ok { return isObj } - rel, err := ds.s.objectStore.GetRelationByKey(key) + relFormat, err := ds.s.objectStore.GetRelationFormatByKey(key) if err != nil { log.Errorf("can't get relation %s: %v", key, err) return false } - isObj := rel.Format == model.RelationFormat_object || rel.Format == model.RelationFormat_file || rel.Format == model.RelationFormat_tag || rel.Format == model.RelationFormat_status + isObj := relFormat == model.RelationFormat_object || relFormat == model.RelationFormat_file || relFormat == model.RelationFormat_tag || relFormat == model.RelationFormat_status ds.isRelationObjMap[key] = isObj return isObj } diff --git a/core/subscription/service_test.go b/core/subscription/service_test.go index aa7db8bd23..0641f8d200 100644 --- a/core/subscription/service_test.go +++ b/core/subscription/service_test.go @@ -32,14 +32,8 @@ func TestService_Search(t *testing.T) { }, 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.RelationKeyAuthor.String()).Return(&model.Relation{ - Key: bundle.RelationKeyAuthor.String(), - Format: model.RelationFormat_object, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyAuthor.String()).Return(model.RelationFormat_object, nil).AnyTimes() fx.store.EXPECT().QueryByID([]string{"author1"}).Return([]database.Record{ {Details: &types.Struct{Fields: map[string]*types.Value{ @@ -135,14 +129,8 @@ func TestService_Search(t *testing.T) { }, 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.RelationKeyAuthor.String()).Return(&model.Relation{ - Key: bundle.RelationKeyAuthor.String(), - Format: model.RelationFormat_object, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyAuthor.String()).Return(model.RelationFormat_object, nil).AnyTimes() fx.store.EXPECT().QueryByID([]string{"force1", "force2"}).Return([]database.Record{ {Details: &types.Struct{Fields: map[string]*types.Value{ @@ -194,10 +182,7 @@ func TestService_Search(t *testing.T) { }, nil, ) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ - Key: bundle.RelationKeyName.String(), - Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() resp, err := fx.Search(SubscribeRequest{ SubId: "test", @@ -261,10 +246,7 @@ func TestService_Search(t *testing.T) { }, nil, ) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ - Key: bundle.RelationKeyName.String(), - Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() resp, err := fx.Search(SubscribeRequest{ SubId: "test", @@ -359,14 +341,8 @@ func TestService_Search(t *testing.T) { }}}, }, 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() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() var resp, err = fx.Search(SubscribeRequest{ SubId: subscriptionID, @@ -409,14 +385,8 @@ func TestService_Search(t *testing.T) { }}}, }, 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() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() var resp, err = fx.Search(SubscribeRequest{ SubId: subscriptionID, @@ -466,14 +436,8 @@ func TestService_Search(t *testing.T) { }}}, }, 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() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() var resp, err = fx.Search(SubscribeRequest{ SubId: subscriptionID, @@ -508,15 +472,9 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ - Key: bundle.RelationKeyName.String(), - Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ - Key: testRelationKey, - Format: model.RelationFormat_object, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(testRelationKey).Return(model.RelationFormat_object, nil).AnyTimes() s := fx.Service.(*service) s.ds = newDependencyService(s) @@ -563,15 +521,9 @@ func TestService_Search(t *testing.T) { }}}, }, nil) - fx.store.EXPECT().GetRelationByKey(bundle.RelationKeyName.String()).Return(&model.Relation{ - Key: bundle.RelationKeyName.String(), - Format: model.RelationFormat_shorttext, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationByKey(testRelationKey).Return(&model.Relation{ - Key: testRelationKey, - Format: model.RelationFormat_object, - }, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(testRelationKey).Return(model.RelationFormat_object, nil).AnyTimes() s := fx.Service.(*service) s.ds = newDependencyService(s) @@ -618,14 +570,8 @@ func TestService_Search(t *testing.T) { }}}, }, 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() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() var resp, err = fx.Search(SubscribeRequest{ SubId: subscriptionID, @@ -1066,7 +1012,7 @@ func xTestNestedSubscription(t *testing.T) { func testCreateSubscriptionWithNestedFilter(t *testing.T) *fixtureRealStore { fx := newFixtureWithRealObjectStore(t) - // fx.store.EXPECT().GetRelationByKey(mock.Anything).Return(&model.Relation{}, nil) + // fx.store.EXPECT().GetRelationFormatByKey(mock.Anything).Return(&model.Relation{}, nil) resp, err := fx.Search(SubscribeRequest{ SubId: "test", Filters: []*model.BlockContentDataviewFilter{ diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go index 84235147cc..573ca980a5 100644 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go +++ b/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go @@ -1321,9 +1321,9 @@ func (_c *MockObjectStore_GetRelationByID_Call) RunAndReturn(run func(string) (* return _c } -// GetRelationByKey provides a mock function with given fields: key -func (_m *MockObjectStore) GetRelationByKey(key string) (*model.Relation, error) { - ret := _m.Called(key) +// GetRelationByKey provides a mock function with given fields: spaceId, key +func (_m *MockObjectStore) GetRelationByKey(spaceId string, key string) (*model.Relation, error) { + ret := _m.Called(spaceId, key) if len(ret) == 0 { panic("no return value specified for GetRelationByKey") @@ -1331,19 +1331,19 @@ func (_m *MockObjectStore) GetRelationByKey(key string) (*model.Relation, error) var r0 *model.Relation var r1 error - if rf, ok := ret.Get(0).(func(string) (*model.Relation, error)); ok { - return rf(key) + if rf, ok := ret.Get(0).(func(string, string) (*model.Relation, error)); ok { + return rf(spaceId, key) } - if rf, ok := ret.Get(0).(func(string) *model.Relation); ok { - r0 = rf(key) + if rf, ok := ret.Get(0).(func(string, string) *model.Relation); ok { + r0 = rf(spaceId, key) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*model.Relation) } } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(key) + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(spaceId, key) } else { r1 = ret.Error(1) } @@ -1357,14 +1357,15 @@ type MockObjectStore_GetRelationByKey_Call struct { } // GetRelationByKey is a helper method to define mock.On call +// - spaceId string // - key string -func (_e *MockObjectStore_Expecter) GetRelationByKey(key interface{}) *MockObjectStore_GetRelationByKey_Call { - return &MockObjectStore_GetRelationByKey_Call{Call: _e.mock.On("GetRelationByKey", key)} +func (_e *MockObjectStore_Expecter) GetRelationByKey(spaceId interface{}, key interface{}) *MockObjectStore_GetRelationByKey_Call { + return &MockObjectStore_GetRelationByKey_Call{Call: _e.mock.On("GetRelationByKey", spaceId, key)} } -func (_c *MockObjectStore_GetRelationByKey_Call) Run(run func(key string)) *MockObjectStore_GetRelationByKey_Call { +func (_c *MockObjectStore_GetRelationByKey_Call) Run(run func(spaceId string, key string)) *MockObjectStore_GetRelationByKey_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(string), args[1].(string)) }) return _c } @@ -1374,7 +1375,63 @@ func (_c *MockObjectStore_GetRelationByKey_Call) Return(_a0 *model.Relation, _a1 return _c } -func (_c *MockObjectStore_GetRelationByKey_Call) RunAndReturn(run func(string) (*model.Relation, error)) *MockObjectStore_GetRelationByKey_Call { +func (_c *MockObjectStore_GetRelationByKey_Call) RunAndReturn(run func(string, string) (*model.Relation, error)) *MockObjectStore_GetRelationByKey_Call { + _c.Call.Return(run) + return _c +} + +// GetRelationFormatByKey provides a mock function with given fields: key +func (_m *MockObjectStore) GetRelationFormatByKey(key string) (model.RelationFormat, error) { + ret := _m.Called(key) + + if len(ret) == 0 { + panic("no return value specified for GetRelationFormatByKey") + } + + var r0 model.RelationFormat + var r1 error + if rf, ok := ret.Get(0).(func(string) (model.RelationFormat, error)); ok { + return rf(key) + } + if rf, ok := ret.Get(0).(func(string) model.RelationFormat); ok { + r0 = rf(key) + } else { + r0 = ret.Get(0).(model.RelationFormat) + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockObjectStore_GetRelationFormatByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationFormatByKey' +type MockObjectStore_GetRelationFormatByKey_Call struct { + *mock.Call +} + +// GetRelationFormatByKey is a helper method to define mock.On call +// - key string +func (_e *MockObjectStore_Expecter) GetRelationFormatByKey(key interface{}) *MockObjectStore_GetRelationFormatByKey_Call { + return &MockObjectStore_GetRelationFormatByKey_Call{Call: _e.mock.On("GetRelationFormatByKey", key)} +} + +func (_c *MockObjectStore_GetRelationFormatByKey_Call) Run(run func(key string)) *MockObjectStore_GetRelationFormatByKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *MockObjectStore_GetRelationFormatByKey_Call) Return(_a0 model.RelationFormat, _a1 error) *MockObjectStore_GetRelationFormatByKey_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockObjectStore_GetRelationFormatByKey_Call) RunAndReturn(run func(string) (model.RelationFormat, error)) *MockObjectStore_GetRelationFormatByKey_Call { _c.Call.Return(run) return _c } diff --git a/pkg/lib/localstore/objectstore/objects.go b/pkg/lib/localstore/objectstore/objects.go index ff0d582e82..79377b86ce 100644 --- a/pkg/lib/localstore/objectstore/objects.go +++ b/pkg/lib/localstore/objectstore/objects.go @@ -154,7 +154,8 @@ type ObjectStore interface { FetchRelationByLinks(spaceId string, links pbtypes.RelationLinks) (relations relationutils.Relations, err error) ListAllRelations(spaceId string) (relations relationutils.Relations, err error) GetRelationByID(id string) (relation *model.Relation, err error) - GetRelationByKey(key string) (*model.Relation, error) + GetRelationByKey(spaceId string, key string) (*model.Relation, error) + GetRelationFormatByKey(key string) (model.RelationFormat, error) GetObjectType(url string) (*model.ObjectType, error) BatchProcessFullTextQueue(ctx context.Context, limit int, processIds func(processIds []string) error) error diff --git a/pkg/lib/localstore/objectstore/relations.go b/pkg/lib/localstore/objectstore/relations.go index 3aa259b6c9..dbd11e576e 100644 --- a/pkg/lib/localstore/objectstore/relations.go +++ b/pkg/lib/localstore/objectstore/relations.go @@ -148,20 +148,24 @@ func (s *dsObjectStore) ListAllRelations(spaceId string) (relations relationutil return } -func (s *dsObjectStore) GetRelationByKey(key string) (*model.Relation, error) { - // todo: should pass workspace +func (s *dsObjectStore) GetRelationByKey(spaceId string, key string) (*model.Relation, error) { q := database.Query{ Filters: []*model.BlockContentDataviewFilter{ { - Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeyRelationKey.String(), + Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.String(key), }, { - Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeyLayout.String(), + Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.Int64(int64(model.ObjectType_relation)), }, + { + RelationKey: bundle.RelationKeySpaceId.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(spaceId), + }, }, } @@ -178,3 +182,33 @@ func (s *dsObjectStore) GetRelationByKey(key string) (*model.Relation, error) { return rel.Relation, nil } + +func (s *dsObjectStore) GetRelationFormatByKey(key string) (model.RelationFormat, error) { + q := database.Query{ + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyRelationKey.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(key), + }, + { + RelationKey: bundle.RelationKeyLayout.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }, + } + + records, err := s.Query(q) + if err != nil { + return 0, err + } + + if len(records) == 0 { + return 0, ds.ErrNotFound + } + + rel := relationutils.RelationFromStruct(records[0].Details) + + return rel.Format, nil +} diff --git a/util/testMock/objectstore_mock.go b/util/testMock/objectstore_mock.go index 2a4b68e6b6..bbae32adc7 100644 --- a/util/testMock/objectstore_mock.go +++ b/util/testMock/objectstore_mock.go @@ -399,18 +399,33 @@ func (mr *MockObjectStoreMockRecorder) GetRelationByID(arg0 any) *gomock.Call { } // GetRelationByKey mocks base method. -func (m *MockObjectStore) GetRelationByKey(arg0 string) (*model.Relation, error) { +func (m *MockObjectStore) GetRelationByKey(arg0, arg1 string) (*model.Relation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationByKey", arg0) + ret := m.ctrl.Call(m, "GetRelationByKey", arg0, arg1) 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 { +func (mr *MockObjectStoreMockRecorder) GetRelationByKey(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByKey), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByKey), arg0, arg1) +} + +// GetRelationFormatByKey mocks base method. +func (m *MockObjectStore) GetRelationFormatByKey(arg0 string) (model.RelationFormat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRelationFormatByKey", arg0) + ret0, _ := ret[0].(model.RelationFormat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRelationFormatByKey indicates an expected call of GetRelationFormatByKey. +func (mr *MockObjectStoreMockRecorder) GetRelationFormatByKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationFormatByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationFormatByKey), arg0) } // GetRelationLink mocks base method.