diff --git a/core/block/export/export_test.go b/core/block/export/export_test.go index c5b697e940..6b2616e8fb 100644 --- a/core/block/export/export_test.go +++ b/core/block/export/export_test.go @@ -61,7 +61,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyName: pbtypes.String("name2"), }, }) - err := storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err := storeFixture.UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) provider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) @@ -95,7 +95,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyIsDeleted: pbtypes.Bool(true), }, }) - err := storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err := storeFixture.UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) provider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) @@ -127,7 +127,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyType: pbtypes.String("objectType"), }, }) - err := storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err := storeFixture.UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) objectGetter := mock_cache.NewMockObjectGetter(t) @@ -184,7 +184,7 @@ func Test_docsForExport(t *testing.T) { }, }) - err = storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err = storeFixture.UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) objectGetter := mock_cache.NewMockObjectGetter(t) @@ -404,7 +404,7 @@ func Test_docsForExport(t *testing.T) { }, }) - err = storeFixture.UpdateObjectLinks(templateId, []string{linkedObjectId}) + err = storeFixture.UpdateObjectLinks(context.Background(), templateId, []string{linkedObjectId}) assert.Nil(t, err) objectGetter := mock_cache.NewMockObjectGetter(t) diff --git a/core/indexer/fulltext.go b/core/indexer/fulltext.go index 451782108f..c32d816aaf 100644 --- a/core/indexer/fulltext.go +++ b/core/indexer/fulltext.go @@ -40,15 +40,7 @@ func (i *indexer) ForceFTIndex() { // MUST NOT be called more than once func (i *indexer) ftLoopRoutine() { ticker := time.NewTicker(ftIndexInterval) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go func() { - select { - case <-i.quit: - cancel() - case <-ctx.Done(): - } - }() + ctx := i.runCtx i.runFullTextIndexer(ctx) defer close(i.ftQueueFinished) @@ -229,7 +221,7 @@ func (i *indexer) ftInit() error { return err } for _, id := range ids { - if err := i.store.AddToIndexQueue(id); err != nil { + if err := i.store.AddToIndexQueue(i.runCtx, id); err != nil { return err } } diff --git a/core/indexer/fulltext_test.go b/core/indexer/fulltext_test.go index 6e1d9035b4..f7a3841d8e 100644 --- a/core/indexer/fulltext_test.go +++ b/core/indexer/fulltext_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/anyproto/any-sync/app" + "github.com/cheggaaa/mb/v3" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -85,10 +86,11 @@ func NewIndexerFixture(t *testing.T) *IndexerFixture { indexerFx.ftsearch = indxr.ftsearch indexerFx.pickerFx = mock_cache.NewMockObjectGetter(t) indxr.picker = indexerFx.pickerFx - indxr.quit = make(chan struct{}) + indxr.batcher = mb.New[indexTask](100) indxr.forceFt = make(chan struct{}) indxr.config = &config.Config{NetworkMode: pb.RpcAccount_LocalOnly} - + indxr.runCtx, indxr.runCtxCancel = context.WithCancel(ctx) + go indxr.indexBatchLoop() return indexerFx } @@ -326,7 +328,7 @@ func TestRunFullTextIndexer(t *testing.T) { blockbuilder.ID("blockId1"), ), ))) - indexerFx.store.AddToIndexQueue("objectId" + strconv.Itoa(i)) + indexerFx.store.AddToIndexQueue(context.Background(), "objectId"+strconv.Itoa(i)) indexerFx.pickerFx.EXPECT().GetObject(mock.Anything, "objectId"+strconv.Itoa(i)).Return(smartTest, nil).Once() } @@ -352,7 +354,7 @@ func TestRunFullTextIndexer(t *testing.T) { ), ))) indexerFx.pickerFx.EXPECT().GetObject(mock.Anything, "objectId"+strconv.Itoa(i)).Return(smartTest, nil).Once() - indexerFx.store.AddToIndexQueue("objectId" + strconv.Itoa(i)) + indexerFx.store.AddToIndexQueue(context.Background(), "objectId"+strconv.Itoa(i)) } @@ -381,7 +383,7 @@ func TestPrepareSearchDocument_Reindex_Removed(t *testing.T) { blockbuilder.ID("blockId1"), ), ))) - indexerFx.store.AddToIndexQueue("objectId1") + indexerFx.store.AddToIndexQueue(context.Background(), "objectId1") indexerFx.pickerFx.EXPECT().GetObject(mock.Anything, mock.Anything).Return(smartTest, nil) indexerFx.runFullTextIndexer(context.Background()) diff --git a/core/indexer/indexer.go b/core/indexer/indexer.go index cc94e819b5..a8c14f78f9 100644 --- a/core/indexer/indexer.go +++ b/core/indexer/indexer.go @@ -10,6 +10,7 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/spacestorage" + "github.com/cheggaaa/mb/v3" "go.uber.org/zap" "golang.org/x/exp/slices" @@ -54,6 +55,12 @@ type Hasher interface { Hash() string } +type indexTask struct { + info smartblock.DocInfo + options []smartblock.IndexOption + done chan error +} + type indexer struct { store objectstore.ObjectStore fileStore filestore.FileStore @@ -61,8 +68,10 @@ type indexer struct { picker cache.ObjectGetter ftsearch ftsearch.FTSearch storageService storage.ClientStorage + batcher *mb.MB[indexTask] - quit chan struct{} + runCtx context.Context + runCtxCancel context.CancelFunc ftQueueFinished chan struct{} config *config.Config @@ -81,10 +90,11 @@ func (i *indexer) Init(a *app.App) (err error) { i.fileStore = app.MustComponent[filestore.FileStore](a) i.ftsearch = app.MustComponent[ftsearch.FTSearch](a) i.picker = app.MustComponent[cache.ObjectGetter](a) - i.quit = make(chan struct{}) - i.ftQueueFinished = make(chan struct{}) + i.runCtx, i.runCtxCancel = context.WithCancel(context.Background()) i.forceFt = make(chan struct{}) i.config = app.MustComponent[*config.Config](a) + i.batcher = mb.New[indexTask](100) + go i.indexBatchLoop() return } @@ -100,14 +110,71 @@ func (i *indexer) StartFullTextIndex() (err error) { if ftErr := i.ftInit(); ftErr != nil { log.Errorf("can't init ft: %v", ftErr) } + i.ftQueueFinished = make(chan struct{}) go i.ftLoopRoutine() return } +func (i *indexer) indexBatchLoop() { + for { + tasks, err := i.batcher.Wait(i.runCtx) + if err != nil { + return + } + if iErr := i.indexBatch(tasks); iErr != nil { + log.Warnf("indexBatch error: %v", iErr) + } + } +} + +func (i *indexer) indexBatch(tasks []indexTask) (err error) { + tx, err := i.store.WriteTx(i.runCtx) + if err != nil { + return err + } + st := time.Now() + + closeTasks := func(closeErr error) { + for _, t := range tasks { + if closeErr != nil { + select { + case t.done <- closeErr: + default: + } + } else { + close(t.done) + } + } + } + + defer func() { + if err != nil { + _ = tx.Rollback() + } else { + if err = tx.Commit(); err != nil { + closeTasks(err) + } else { + closeTasks(nil) + } + log.Infof("indexBatch: indexed %d docs for a %v: err: %v", len(tasks), time.Since(st), err) + } + }() + + for _, task := range tasks { + if iErr := i.index(tx.Context(), task.info, task.options...); iErr != nil { + task.done <- iErr + } + } + return +} + func (i *indexer) Close(ctx context.Context) (err error) { - close(i.quit) - // we need to wait for the ftQueue processing to be finished gracefully. Because we may be in the middle of badger transaction - <-i.ftQueueFinished + _ = i.batcher.Close() + if i.runCtxCancel != nil { + i.runCtxCancel() + // we need to wait for the ftQueue processing to be finished gracefully. Because we may be in the middle of badger transaction + <-i.ftQueueFinished + } return nil } @@ -129,10 +196,23 @@ func (i *indexer) RemoveAclIndexes(spaceId string) (err error) { if err != nil { return } - return i.store.DeleteDetails(ids...) + return i.store.DeleteDetails(i.runCtx, ids...) } func (i *indexer) Index(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption) error { + done := make(chan error) + if err := i.batcher.Add(ctx, indexTask{ + info: info, + options: options, + done: done, + }); err != nil { + return err + } + err, _ := <-done + return err +} + +func (i *indexer) index(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption) error { // options are stored in smartblock pkg because of cyclic dependency :( startTime := time.Now() opts := &smartblock.IndexOptions{} @@ -150,7 +230,7 @@ func (i *indexer) Index(ctx context.Context, info smartblock.DocInfo, options .. return } - err = i.store.SaveLastIndexedHeadsHash(info.Id, headHashToIndex) + err = i.store.SaveLastIndexedHeadsHash(ctx, info.Id, headHashToIndex) if err != nil { log.With("objectID", info.Id).Errorf("failed to save indexed heads hash: %v", err) } @@ -161,7 +241,7 @@ func (i *indexer) Index(ctx context.Context, info smartblock.DocInfo, options .. return nil } - lastIndexedHash, err := i.store.GetLastIndexedHeadsHash(info.Id) + lastIndexedHash, err := i.store.GetLastIndexedHeadsHash(ctx, info.Id) if err != nil { log.With("object", info.Id).Errorf("failed to get last indexed heads hash: %v", err) } @@ -180,7 +260,7 @@ func (i *indexer) Index(ctx context.Context, info smartblock.DocInfo, options .. indexSetTime := time.Now() var hasError bool if indexLinks { - if err = i.store.UpdateObjectLinks(info.Id, info.Links); err != nil { + if err = i.store.UpdateObjectLinks(ctx, info.Id, info.Links); err != nil { hasError = true log.With("objectID", info.Id).Errorf("failed to save object links: %v", err) } @@ -208,12 +288,12 @@ func (i *indexer) Index(ctx context.Context, info smartblock.DocInfo, options .. } if !(opts.SkipFullTextIfHeadsNotChanged && lastIndexedHash == headHashToIndex) { - if err := i.store.AddToIndexQueue(info.Id); err != nil { + if err := i.store.AddToIndexQueue(ctx, info.Id); err != nil { log.With("objectID", info.Id).Errorf("can't add id to index queue: %v", err) } } } else { - _ = i.store.DeleteDetails(info.Id) + _ = i.store.DeleteDetails(ctx, info.Id) } indexDetailsTime := time.Now() detailsCount := 0 diff --git a/core/indexer/indexer_test.go b/core/indexer/indexer_test.go index a085842310..377da61478 100644 --- a/core/indexer/indexer_test.go +++ b/core/indexer/indexer_test.go @@ -14,6 +14,8 @@ import ( "github.com/anyproto/anytype-heart/tests/testutil" ) +var ctx = context.Background() + func TestIndexer(t *testing.T) { for _, testCase := range []struct { name string @@ -44,7 +46,7 @@ func TestIndexer(t *testing.T) { smartTest.SetType(coresb.SmartBlockTypePage) indexerFx.storageServiceFx.EXPECT().BindSpaceID(mock.Anything, mock.Anything).Return(nil) - indexerFx.store.SaveLastIndexedHeadsHash("objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") + indexerFx.store.SaveLastIndexedHeadsHash(ctx, "objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") // when err := indexerFx.Index(context.Background(), smartTest.GetDocInfo(), testCase.options) @@ -71,7 +73,7 @@ func TestIndexer(t *testing.T) { smartTest.SetType(coresb.SmartBlockTypePage) indexerFx.storageServiceFx.EXPECT().BindSpaceID(mock.Anything, mock.Anything).Return(nil) - indexerFx.store.SaveLastIndexedHeadsHash("objectId1", "randomHash") + indexerFx.store.SaveLastIndexedHeadsHash(ctx, "objectId1", "randomHash") // when err := indexerFx.Index(context.Background(), smartTest.GetDocInfo(), testCase.options) @@ -99,7 +101,7 @@ func TestIndexer(t *testing.T) { smartTest.SetType(coresb.SmartBlockTypePage) indexerFx.storageServiceFx.EXPECT().BindSpaceID(mock.Anything, mock.Anything).Return(nil) - indexerFx.store.SaveLastIndexedHeadsHash("objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") + indexerFx.store.SaveLastIndexedHeadsHash(ctx, "objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") // when err := indexerFx.Index(context.Background(), smartTest.GetDocInfo()) diff --git a/core/indexer/reindex.go b/core/indexer/reindex.go index 216f425c52..6cb6628bdb 100644 --- a/core/indexer/reindex.go +++ b/core/indexer/reindex.go @@ -302,7 +302,7 @@ func (i *indexer) removeOldFiles(spaceId string, flags reindexFlags) error { } for _, id := range ids { if domain.IsFileId(id) { - err = i.store.DeleteDetails(id) + err = i.store.DeleteDetails(i.runCtx, id) if err != nil { log.Errorf("delete old file %s: %s", id, err) } @@ -382,7 +382,7 @@ func (i *indexer) removeDetails(spaceId string) error { log.Errorf("reindex failed to get all ids(removeAllIndexedObjects): %v", err) } for _, id := range ids { - if err = i.store.DeleteDetails(id); err != nil { + if err = i.store.DeleteDetails(i.runCtx, id); err != nil { log.Errorf("reindex failed to delete details(removeAllIndexedObjects): %v", err) } } @@ -412,7 +412,7 @@ func (i *indexer) removeOldObjects() (err error) { return } - err = i.store.DeleteDetails(ids...) + err = i.store.DeleteDetails(i.runCtx, ids...) log.With(zap.Int("count", len(ids)), zap.Error(err)).Warnf("removeOldObjects") return err } @@ -484,7 +484,7 @@ func (i *indexer) reindexOutdatedObjects(ctx context.Context, space clientspace. log.With("tree", tid).Errorf("reindexOutdatedObjects failed to get tree to reindex: %s", err) } - lastHash, err := i.store.GetLastIndexedHeadsHash(tid) + lastHash, err := i.store.GetLastIndexedHeadsHash(ctx, tid) if err != nil { logErr(err) continue diff --git a/core/indexer/reindex_test.go b/core/indexer/reindex_test.go index 64e6b33857..87c6aec498 100644 --- a/core/indexer/reindex_test.go +++ b/core/indexer/reindex_test.go @@ -77,9 +77,9 @@ func TestReindexMarketplaceSpace(t *testing.T) { favs := []string{"fav1", "fav2"} trash := []string{"trash1", "trash2"} - err := fx.store.UpdateObjectLinks("home", favs) + err := fx.store.UpdateObjectLinks(ctx, "home", favs) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("bin", trash) + err = fx.store.UpdateObjectLinks(ctx, "bin", trash) require.NoError(t, err) homeLinks, err := fx.store.GetOutboundLinksByID("home") @@ -293,9 +293,9 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { // given favs := []string{"fav1", "fav2"} trash := []string{"trash1", "trash2"} - err = fx.store.UpdateObjectLinks("home", favs) + err = fx.store.UpdateObjectLinks(ctx, "home", favs) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("bin", trash) + err = fx.store.UpdateObjectLinks(ctx, "bin", trash) require.NoError(t, err) homeLinks, err := fx.store.GetOutboundLinksByID("home") @@ -330,11 +330,11 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { obj1links := []string{"obj2", "obj3"} obj2links := []string{"obj1"} obj3links := []string{"obj2"} - err = fx.store.UpdateObjectLinks("obj1", obj1links) + err = fx.store.UpdateObjectLinks(ctx, "obj1", obj1links) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("obj2", obj2links) + err = fx.store.UpdateObjectLinks(ctx, "obj2", obj2links) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("obj3", obj3links) + err = fx.store.UpdateObjectLinks(ctx, "obj3", obj3links) require.NoError(t, err) storedObj1links, err := fx.store.GetOutboundLinksByID("obj1") diff --git a/go.mod b/go.mod index 7934258775..c2a2601ac1 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/PuerkitoBio/goquery v1.9.2 github.com/VividCortex/ewma v1.2.0 github.com/adrium/goheif v0.0.0-20230113233934-ca402e77a786 - github.com/anyproto/any-store v0.0.3 + github.com/anyproto/any-store v0.0.4 github.com/anyproto/any-sync v0.5.1-0.20240902135827-fa1ea8d417f7 github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438 github.com/anyproto/lexid v0.0.2 @@ -94,7 +94,7 @@ require ( go.uber.org/mock v0.4.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 golang.org/x/image v0.20.0 golang.org/x/mobile v0.0.0-20240806205939-81131f6468ab golang.org/x/net v0.29.0 @@ -176,7 +176,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f // indirect + github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect github.com/gorilla/css v1.0.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect @@ -275,10 +275,10 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect - modernc.org/libc v1.41.0 // indirect + modernc.org/libc v1.60.1 // indirect modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.7.2 // indirect - modernc.org/sqlite v1.29.1 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/sqlite v1.32.0 // indirect nhooyr.io/websocket v1.8.7 // indirect zombiezen.com/go/sqlite v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 092fa177d5..e9c3ed8266 100644 --- a/go.sum +++ b/go.sum @@ -83,10 +83,8 @@ github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxB github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= -github.com/anyproto/any-store v0.0.3 h1:802U8KNiylXUJ1DA12LgnnG/OfTgAXOVRnOIue5qtn0= -github.com/anyproto/any-store v0.0.3/go.mod h1:MA3sSqRXIp0h9bC2LnMuDGVEFGB3BkI/UuWNCleGHMs= -github.com/anyproto/any-sync v0.5.1-0.20240901205415-2ba5555b6e90 h1:tO2BeAsVHediuj0LHU3OtNk0FSwi+2i++icDJQraMRU= -github.com/anyproto/any-sync v0.5.1-0.20240901205415-2ba5555b6e90/go.mod h1:oLo4tkNYdum85NCE1QaRzy4KPK+RlBMkhTH6U27ZvX0= +github.com/anyproto/any-store v0.0.4 h1:Iv5XXOi0WM0g0yPNYixFA/MQpAxwHpJ5VtNuRszvE3g= +github.com/anyproto/any-store v0.0.4/go.mod h1:MA3sSqRXIp0h9bC2LnMuDGVEFGB3BkI/UuWNCleGHMs= github.com/anyproto/any-sync v0.5.1-0.20240902135827-fa1ea8d417f7 h1:PKbNC5YPffnnclPpg1SnV0HAKsbFll48acDN88jVjRo= github.com/anyproto/any-sync v0.5.1-0.20240902135827-fa1ea8d417f7/go.mod h1:oLo4tkNYdum85NCE1QaRzy4KPK+RlBMkhTH6U27ZvX0= github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580 h1:Ba80IlCCxkZ9H1GF+7vFu/TSpPvbpDCxXJ5ogc4euYc= @@ -496,8 +494,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f h1:f00RU+zOX+B3rLAmMMkzHUF2h1z4DeYR9tTCvEq2REY= -github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -1540,8 +1538,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -2017,14 +2015,30 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= -modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= +modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= +modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/libc v1.60.1 h1:at373l8IFRTkJIkAU85BIuUoBM4T1b51ds0E1ovPG2s= +modernc.org/libc v1.60.1/go.mod h1:xJuobKuNxKH3RUatS7GjR+suWj+5c2K7bi4m/S5arOY= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= -modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= diff --git a/pkg/lib/localstore/objectstore/delete.go b/pkg/lib/localstore/objectstore/delete.go index 321d25c52c..8dcc80d816 100644 --- a/pkg/lib/localstore/objectstore/delete.go +++ b/pkg/lib/localstore/objectstore/delete.go @@ -14,8 +14,8 @@ import ( "github.com/anyproto/anytype-heart/util/pbtypes" ) -func (s *dsObjectStore) DeleteDetails(ids ...string) error { - txn, err := s.anyStore.WriteTx(s.componentCtx) +func (s *dsObjectStore) DeleteDetails(ctx context.Context, ids ...string) error { + txn, err := s.anyStore.WriteTx(ctx) if err != nil { return fmt.Errorf("write txn: %w", err) } diff --git a/pkg/lib/localstore/objectstore/fixture.go b/pkg/lib/localstore/objectstore/fixture.go index 404b02bab4..0699b7c9fc 100644 --- a/pkg/lib/localstore/objectstore/fixture.go +++ b/pkg/lib/localstore/objectstore/fixture.go @@ -28,6 +28,8 @@ type StoreFixture struct { // nolint: unused const spaceName = "space1" +var ctx = context.Background() + func NewStoreFixture(t testing.TB) *StoreFixture { ctx, cancel := context.WithCancel(context.Background()) diff --git a/pkg/lib/localstore/objectstore/indexer_store.go b/pkg/lib/localstore/objectstore/indexer_store.go index 110959a741..c2881b4bf6 100644 --- a/pkg/lib/localstore/objectstore/indexer_store.go +++ b/pkg/lib/localstore/objectstore/indexer_store.go @@ -13,7 +13,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) -func (s *dsObjectStore) AddToIndexQueue(id string) error { +func (s *dsObjectStore) AddToIndexQueue(ctx context.Context, id string) error { arena := s.arenaPool.Get() defer func() { arena.Reset() @@ -22,7 +22,7 @@ func (s *dsObjectStore) AddToIndexQueue(id string) error { obj := arena.NewObject() obj.Set("id", arena.NewString(id)) - _, err := s.fulltextQueue.UpsertOne(s.componentCtx, obj) + _, err := s.fulltextQueue.UpsertOne(ctx, obj) return err } @@ -114,16 +114,16 @@ func (s *dsObjectStore) GetGlobalChecksums() (checksums *model.ObjectStoreChecks const headsStateField = "h" // GetLastIndexedHeadsHash return empty hash without error if record was not found -func (s *dsObjectStore) GetLastIndexedHeadsHash(id string) (headsHash string, err error) { - doc, err := s.headsState.FindId(s.componentCtx, id) +func (s *dsObjectStore) GetLastIndexedHeadsHash(ctx context.Context, id string) (headsHash string, err error) { + doc, err := s.headsState.FindId(ctx, id) if errors.Is(err, anystore.ErrDocNotFound) { return "", nil } return string(doc.Value().GetStringBytes(headsStateField)), nil } -func (s *dsObjectStore) SaveLastIndexedHeadsHash(id string, headsHash string) error { - _, err := s.headsState.UpsertId(s.componentCtx, id, query.ModifyFunc(func(arena *fastjson.Arena, val *fastjson.Value) (*fastjson.Value, bool, error) { +func (s *dsObjectStore) SaveLastIndexedHeadsHash(ctx context.Context, id string, headsHash string) error { + _, err := s.headsState.UpsertId(ctx, id, query.ModifyFunc(func(arena *fastjson.Arena, val *fastjson.Value) (*fastjson.Value, bool, error) { val.Set(headsStateField, arena.NewString(headsHash)) return val, true, nil })) diff --git a/pkg/lib/localstore/objectstore/indexer_store_test.go b/pkg/lib/localstore/objectstore/indexer_store_test.go index de03907433..91ab5129ab 100644 --- a/pkg/lib/localstore/objectstore/indexer_store_test.go +++ b/pkg/lib/localstore/objectstore/indexer_store_test.go @@ -14,9 +14,9 @@ func TestDsObjectStore_IndexQueue(t *testing.T) { s := NewStoreFixture(t) t.Run("add to queue", func(t *testing.T) { - require.NoError(t, s.AddToIndexQueue("one")) - require.NoError(t, s.AddToIndexQueue("one")) - require.NoError(t, s.AddToIndexQueue("two")) + require.NoError(t, s.AddToIndexQueue(ctx, "one")) + require.NoError(t, s.AddToIndexQueue(ctx, "one")) + require.NoError(t, s.AddToIndexQueue(ctx, "two")) ids, err := s.ListIDsFromFullTextQueue(0) require.NoError(t, err) @@ -37,9 +37,9 @@ func TestIndexerBatch(t *testing.T) { s := NewStoreFixture(t) t.Run("batch - no more than limit", func(t *testing.T) { - require.NoError(t, s.AddToIndexQueue("one")) - require.NoError(t, s.AddToIndexQueue("two")) - require.NoError(t, s.AddToIndexQueue("three")) + require.NoError(t, s.AddToIndexQueue(ctx, "one")) + require.NoError(t, s.AddToIndexQueue(ctx, "two")) + require.NoError(t, s.AddToIndexQueue(ctx, "three")) var batches [][]string err := s.BatchProcessFullTextQueue(context.Background(), 2, func(ids []string) error { @@ -89,7 +89,7 @@ func TestHeadsHash(t *testing.T) { t.Run("previous hash is not found", func(t *testing.T) { s := NewStoreFixture(t) - got, err := s.GetLastIndexedHeadsHash("id1") + got, err := s.GetLastIndexedHeadsHash(ctx, "id1") require.NoError(t, err) assert.Empty(t, got) }) @@ -99,9 +99,9 @@ func TestHeadsHash(t *testing.T) { want := "hash1" - require.NoError(t, s.SaveLastIndexedHeadsHash("id1", want)) + require.NoError(t, s.SaveLastIndexedHeadsHash(ctx, "id1", want)) - got, err := s.GetLastIndexedHeadsHash("id1") + got, err := s.GetLastIndexedHeadsHash(ctx, "id1") require.NoError(t, err) assert.Equal(t, want, got) }) diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go index 3f02477376..64d6a2f981 100644 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go +++ b/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go @@ -3,10 +3,11 @@ package mock_objectstore import ( - context "context" - + anystore "github.com/anyproto/any-store" app "github.com/anyproto/any-sync/app" + context "context" + coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" database "github.com/anyproto/anytype-heart/pkg/lib/database" @@ -39,17 +40,17 @@ func (_m *MockObjectStore) EXPECT() *MockObjectStore_Expecter { return &MockObjectStore_Expecter{mock: &_m.Mock} } -// AddToIndexQueue provides a mock function with given fields: id -func (_m *MockObjectStore) AddToIndexQueue(id string) error { - ret := _m.Called(id) +// AddToIndexQueue provides a mock function with given fields: ctx, id +func (_m *MockObjectStore) AddToIndexQueue(ctx context.Context, id string) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for AddToIndexQueue") } var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -63,14 +64,15 @@ type MockObjectStore_AddToIndexQueue_Call struct { } // AddToIndexQueue is a helper method to define mock.On call +// - ctx context.Context // - id string -func (_e *MockObjectStore_Expecter) AddToIndexQueue(id interface{}) *MockObjectStore_AddToIndexQueue_Call { - return &MockObjectStore_AddToIndexQueue_Call{Call: _e.mock.On("AddToIndexQueue", id)} +func (_e *MockObjectStore_Expecter) AddToIndexQueue(ctx interface{}, id interface{}) *MockObjectStore_AddToIndexQueue_Call { + return &MockObjectStore_AddToIndexQueue_Call{Call: _e.mock.On("AddToIndexQueue", ctx, id)} } -func (_c *MockObjectStore_AddToIndexQueue_Call) Run(run func(id string)) *MockObjectStore_AddToIndexQueue_Call { +func (_c *MockObjectStore_AddToIndexQueue_Call) Run(run func(ctx context.Context, id string)) *MockObjectStore_AddToIndexQueue_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(context.Context), args[1].(string)) }) return _c } @@ -80,7 +82,7 @@ func (_c *MockObjectStore_AddToIndexQueue_Call) Return(_a0 error) *MockObjectSto return _c } -func (_c *MockObjectStore_AddToIndexQueue_Call) RunAndReturn(run func(string) error) *MockObjectStore_AddToIndexQueue_Call { +func (_c *MockObjectStore_AddToIndexQueue_Call) RunAndReturn(run func(context.Context, string) error) *MockObjectStore_AddToIndexQueue_Call { _c.Call.Return(run) return _c } @@ -179,13 +181,14 @@ func (_c *MockObjectStore_Close_Call) RunAndReturn(run func(context.Context) err return _c } -// DeleteDetails provides a mock function with given fields: id -func (_m *MockObjectStore) DeleteDetails(id ...string) error { +// DeleteDetails provides a mock function with given fields: ctx, id +func (_m *MockObjectStore) DeleteDetails(ctx context.Context, id ...string) error { _va := make([]interface{}, len(id)) for _i := range id { _va[_i] = id[_i] } var _ca []interface{} + _ca = append(_ca, ctx) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -194,8 +197,8 @@ func (_m *MockObjectStore) DeleteDetails(id ...string) error { } var r0 error - if rf, ok := ret.Get(0).(func(...string) error); ok { - r0 = rf(id...) + if rf, ok := ret.Get(0).(func(context.Context, ...string) error); ok { + r0 = rf(ctx, id...) } else { r0 = ret.Error(0) } @@ -209,21 +212,22 @@ type MockObjectStore_DeleteDetails_Call struct { } // DeleteDetails is a helper method to define mock.On call +// - ctx context.Context // - id ...string -func (_e *MockObjectStore_Expecter) DeleteDetails(id ...interface{}) *MockObjectStore_DeleteDetails_Call { +func (_e *MockObjectStore_Expecter) DeleteDetails(ctx interface{}, id ...interface{}) *MockObjectStore_DeleteDetails_Call { return &MockObjectStore_DeleteDetails_Call{Call: _e.mock.On("DeleteDetails", - append([]interface{}{}, id...)...)} + append([]interface{}{ctx}, id...)...)} } -func (_c *MockObjectStore_DeleteDetails_Call) Run(run func(id ...string)) *MockObjectStore_DeleteDetails_Call { +func (_c *MockObjectStore_DeleteDetails_Call) Run(run func(ctx context.Context, id ...string)) *MockObjectStore_DeleteDetails_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]string, len(args)-0) - for i, a := range args[0:] { + variadicArgs := make([]string, len(args)-1) + for i, a := range args[1:] { if a != nil { variadicArgs[i] = a.(string) } } - run(variadicArgs...) + run(args[0].(context.Context), variadicArgs...) }) return _c } @@ -233,7 +237,7 @@ func (_c *MockObjectStore_DeleteDetails_Call) Return(_a0 error) *MockObjectStore return _c } -func (_c *MockObjectStore_DeleteDetails_Call) RunAndReturn(run func(...string) error) *MockObjectStore_DeleteDetails_Call { +func (_c *MockObjectStore_DeleteDetails_Call) RunAndReturn(run func(context.Context, ...string) error) *MockObjectStore_DeleteDetails_Call { _c.Call.Return(run) return _c } @@ -1032,9 +1036,9 @@ func (_c *MockObjectStore_GetInboundLinksByID_Call) RunAndReturn(run func(string return _c } -// GetLastIndexedHeadsHash provides a mock function with given fields: id -func (_m *MockObjectStore) GetLastIndexedHeadsHash(id string) (string, error) { - ret := _m.Called(id) +// GetLastIndexedHeadsHash provides a mock function with given fields: ctx, id +func (_m *MockObjectStore) GetLastIndexedHeadsHash(ctx context.Context, id string) (string, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetLastIndexedHeadsHash") @@ -1042,17 +1046,17 @@ func (_m *MockObjectStore) GetLastIndexedHeadsHash(id string) (string, error) { var r0 string var r1 error - if rf, ok := ret.Get(0).(func(string) (string, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, string) (string, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(string) string); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, string) string); ok { + r0 = rf(ctx, id) } else { r0 = ret.Get(0).(string) } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -1066,14 +1070,15 @@ type MockObjectStore_GetLastIndexedHeadsHash_Call struct { } // GetLastIndexedHeadsHash is a helper method to define mock.On call +// - ctx context.Context // - id string -func (_e *MockObjectStore_Expecter) GetLastIndexedHeadsHash(id interface{}) *MockObjectStore_GetLastIndexedHeadsHash_Call { - return &MockObjectStore_GetLastIndexedHeadsHash_Call{Call: _e.mock.On("GetLastIndexedHeadsHash", id)} +func (_e *MockObjectStore_Expecter) GetLastIndexedHeadsHash(ctx interface{}, id interface{}) *MockObjectStore_GetLastIndexedHeadsHash_Call { + return &MockObjectStore_GetLastIndexedHeadsHash_Call{Call: _e.mock.On("GetLastIndexedHeadsHash", ctx, id)} } -func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) Run(run func(id string)) *MockObjectStore_GetLastIndexedHeadsHash_Call { +func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) Run(run func(ctx context.Context, id string)) *MockObjectStore_GetLastIndexedHeadsHash_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(context.Context), args[1].(string)) }) return _c } @@ -1083,7 +1088,7 @@ func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) Return(headsHash string, return _c } -func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) RunAndReturn(run func(string) (string, error)) *MockObjectStore_GetLastIndexedHeadsHash_Call { +func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) RunAndReturn(run func(context.Context, string) (string, error)) *MockObjectStore_GetLastIndexedHeadsHash_Call { _c.Call.Return(run) return _c } @@ -2708,17 +2713,17 @@ func (_c *MockObjectStore_SaveChecksums_Call) RunAndReturn(run func(string, *mod return _c } -// SaveLastIndexedHeadsHash provides a mock function with given fields: id, headsHash -func (_m *MockObjectStore) SaveLastIndexedHeadsHash(id string, headsHash string) error { - ret := _m.Called(id, headsHash) +// SaveLastIndexedHeadsHash provides a mock function with given fields: ctx, id, headsHash +func (_m *MockObjectStore) SaveLastIndexedHeadsHash(ctx context.Context, id string, headsHash string) error { + ret := _m.Called(ctx, id, headsHash) if len(ret) == 0 { panic("no return value specified for SaveLastIndexedHeadsHash") } var r0 error - if rf, ok := ret.Get(0).(func(string, string) error); ok { - r0 = rf(id, headsHash) + if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { + r0 = rf(ctx, id, headsHash) } else { r0 = ret.Error(0) } @@ -2732,15 +2737,16 @@ type MockObjectStore_SaveLastIndexedHeadsHash_Call struct { } // SaveLastIndexedHeadsHash is a helper method to define mock.On call +// - ctx context.Context // - id string // - headsHash string -func (_e *MockObjectStore_Expecter) SaveLastIndexedHeadsHash(id interface{}, headsHash interface{}) *MockObjectStore_SaveLastIndexedHeadsHash_Call { - return &MockObjectStore_SaveLastIndexedHeadsHash_Call{Call: _e.mock.On("SaveLastIndexedHeadsHash", id, headsHash)} +func (_e *MockObjectStore_Expecter) SaveLastIndexedHeadsHash(ctx interface{}, id interface{}, headsHash interface{}) *MockObjectStore_SaveLastIndexedHeadsHash_Call { + return &MockObjectStore_SaveLastIndexedHeadsHash_Call{Call: _e.mock.On("SaveLastIndexedHeadsHash", ctx, id, headsHash)} } -func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) Run(run func(id string, headsHash string)) *MockObjectStore_SaveLastIndexedHeadsHash_Call { +func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) Run(run func(ctx context.Context, id string, headsHash string)) *MockObjectStore_SaveLastIndexedHeadsHash_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + run(args[0].(context.Context), args[1].(string), args[2].(string)) }) return _c } @@ -2750,7 +2756,7 @@ func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) Return(err error) *Mock return _c } -func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) RunAndReturn(run func(string, string) error) *MockObjectStore_SaveLastIndexedHeadsHash_Call { +func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) RunAndReturn(run func(context.Context, string, string) error) *MockObjectStore_SaveLastIndexedHeadsHash_Call { _c.Call.Return(run) return _c } @@ -2977,17 +2983,17 @@ func (_c *MockObjectStore_UpdateObjectDetails_Call) RunAndReturn(run func(contex return _c } -// UpdateObjectLinks provides a mock function with given fields: id, links -func (_m *MockObjectStore) UpdateObjectLinks(id string, links []string) error { - ret := _m.Called(id, links) +// UpdateObjectLinks provides a mock function with given fields: ctx, id, links +func (_m *MockObjectStore) UpdateObjectLinks(ctx context.Context, id string, links []string) error { + ret := _m.Called(ctx, id, links) if len(ret) == 0 { panic("no return value specified for UpdateObjectLinks") } var r0 error - if rf, ok := ret.Get(0).(func(string, []string) error); ok { - r0 = rf(id, links) + if rf, ok := ret.Get(0).(func(context.Context, string, []string) error); ok { + r0 = rf(ctx, id, links) } else { r0 = ret.Error(0) } @@ -3001,15 +3007,16 @@ type MockObjectStore_UpdateObjectLinks_Call struct { } // UpdateObjectLinks is a helper method to define mock.On call +// - ctx context.Context // - id string // - links []string -func (_e *MockObjectStore_Expecter) UpdateObjectLinks(id interface{}, links interface{}) *MockObjectStore_UpdateObjectLinks_Call { - return &MockObjectStore_UpdateObjectLinks_Call{Call: _e.mock.On("UpdateObjectLinks", id, links)} +func (_e *MockObjectStore_Expecter) UpdateObjectLinks(ctx interface{}, id interface{}, links interface{}) *MockObjectStore_UpdateObjectLinks_Call { + return &MockObjectStore_UpdateObjectLinks_Call{Call: _e.mock.On("UpdateObjectLinks", ctx, id, links)} } -func (_c *MockObjectStore_UpdateObjectLinks_Call) Run(run func(id string, links []string)) *MockObjectStore_UpdateObjectLinks_Call { +func (_c *MockObjectStore_UpdateObjectLinks_Call) Run(run func(ctx context.Context, id string, links []string)) *MockObjectStore_UpdateObjectLinks_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]string)) + run(args[0].(context.Context), args[1].(string), args[2].([]string)) }) return _c } @@ -3019,7 +3026,7 @@ func (_c *MockObjectStore_UpdateObjectLinks_Call) Return(_a0 error) *MockObjectS return _c } -func (_c *MockObjectStore_UpdateObjectLinks_Call) RunAndReturn(run func(string, []string) error) *MockObjectStore_UpdateObjectLinks_Call { +func (_c *MockObjectStore_UpdateObjectLinks_Call) RunAndReturn(run func(context.Context, string, []string) error) *MockObjectStore_UpdateObjectLinks_Call { _c.Call.Return(run) return _c } @@ -3071,6 +3078,64 @@ func (_c *MockObjectStore_UpdatePendingLocalDetails_Call) RunAndReturn(run func( return _c } +// WriteTx provides a mock function with given fields: ctx +func (_m *MockObjectStore) WriteTx(ctx context.Context) (anystore.WriteTx, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for WriteTx") + } + + var r0 anystore.WriteTx + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (anystore.WriteTx, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) anystore.WriteTx); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(anystore.WriteTx) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockObjectStore_WriteTx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteTx' +type MockObjectStore_WriteTx_Call struct { + *mock.Call +} + +// WriteTx is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockObjectStore_Expecter) WriteTx(ctx interface{}) *MockObjectStore_WriteTx_Call { + return &MockObjectStore_WriteTx_Call{Call: _e.mock.On("WriteTx", ctx)} +} + +func (_c *MockObjectStore_WriteTx_Call) Run(run func(ctx context.Context)) *MockObjectStore_WriteTx_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockObjectStore_WriteTx_Call) Return(_a0 anystore.WriteTx, _a1 error) *MockObjectStore_WriteTx_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockObjectStore_WriteTx_Call) RunAndReturn(run func(context.Context) (anystore.WriteTx, error)) *MockObjectStore_WriteTx_Call { + _c.Call.Return(run) + return _c +} + // NewMockObjectStore creates a new instance of MockObjectStore. 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 NewMockObjectStore(t interface { diff --git a/pkg/lib/localstore/objectstore/objects.go b/pkg/lib/localstore/objectstore/objects.go index c1699beaf3..bb800c3065 100644 --- a/pkg/lib/localstore/objectstore/objects.go +++ b/pkg/lib/localstore/objectstore/objects.go @@ -66,12 +66,12 @@ type ObjectStore interface { // UpdateObjectDetails updates existing object or create if not missing. Should be used in order to amend existing indexes based on prev/new value // set discardLocalDetailsChanges to true in case the caller doesn't have local details in the State UpdateObjectDetails(ctx context.Context, id string, details *types.Struct) error - UpdateObjectLinks(id string, links []string) error + UpdateObjectLinks(ctx context.Context, id string, links []string) error UpdatePendingLocalDetails(id string, proc func(details *types.Struct) (*types.Struct, error)) error ModifyObjectDetails(id string, proc func(details *types.Struct) (*types.Struct, bool, error)) error DeleteObject(id domain.FullID) error - DeleteDetails(id ...string) error + DeleteDetails(ctx context.Context, id ...string) error DeleteLinks(id ...string) error GetDetails(id string) (*model.ObjectDetails, error) @@ -97,10 +97,12 @@ type ObjectStore interface { GetObjectType(url string) (*model.ObjectType, error) BatchProcessFullTextQueue(ctx context.Context, limit int, processIds func(processIds []string) error) error + + WriteTx(ctx context.Context) (anystore.WriteTx, error) } type IndexerStore interface { - AddToIndexQueue(id string) error + AddToIndexQueue(ctx context.Context, id string) error ListIDsFromFullTextQueue(limit int) ([]string, error) RemoveIDsFromFullTextQueue(ids []string) error FTSearch() ftsearch.FTSearch @@ -111,8 +113,8 @@ type IndexerStore interface { // SaveChecksums Used to save checksums and force reindex counter SaveChecksums(spaceID string, checksums *model.ObjectStoreChecksums) (err error) - GetLastIndexedHeadsHash(id string) (headsHash string, err error) - SaveLastIndexedHeadsHash(id string, headsHash string) (err error) + GetLastIndexedHeadsHash(ctx context.Context, id string) (headsHash string, err error) + SaveLastIndexedHeadsHash(ctx context.Context, id string, headsHash string) (err error) } type AccountStore interface { @@ -247,6 +249,14 @@ func (s *dsObjectStore) runDatabase(ctx context.Context, path string) error { s.anyStore = store objectIndexes := []anystore.IndexInfo{ + { + Name: "uniqueKey", + Fields: []string{bundle.RelationKeyUniqueKey.String()}, + }, + { + Name: "source", + Fields: []string{bundle.RelationKeySource.String()}, + }, { Name: "layout", Fields: []string{bundle.RelationKeyLayout.String()}, @@ -255,22 +265,24 @@ func (s *dsObjectStore) runDatabase(ctx context.Context, path string) error { Name: "type", Fields: []string{bundle.RelationKeyType.String()}, }, - { - Name: "spaceId", - Fields: []string{bundle.RelationKeySpaceId.String()}, - }, { Name: "relationKey", Fields: []string{bundle.RelationKeyRelationKey.String()}, }, - { - Name: "uniqueKey", - Fields: []string{bundle.RelationKeyUniqueKey.String()}, - }, { Name: "lastModifiedDate", Fields: []string{bundle.RelationKeyLastModifiedDate.String()}, }, + { + Name: "fileId", + Fields: []string{bundle.RelationKeyFileId.String()}, + Sparse: true, + }, + { + Name: "oldAnytypeID", + Fields: []string{bundle.RelationKeyOldAnytypeID.String()}, + Sparse: true, + }, } err = s.addIndexes(ctx, objects, objectIndexes) if err != nil { @@ -304,6 +316,7 @@ func (s *dsObjectStore) runDatabase(ctx context.Context, path string) error { func (s *dsObjectStore) addIndexes(ctx context.Context, coll anystore.Collection, indexes []anystore.IndexInfo) error { gotIndexes := coll.GetIndexes() toCreate := indexes[:0] + var toDrop []string for _, idx := range indexes { if !slices.ContainsFunc(gotIndexes, func(i anystore.Index) bool { return i.Info().Name == idx.Name @@ -311,9 +324,27 @@ func (s *dsObjectStore) addIndexes(ctx context.Context, coll anystore.Collection toCreate = append(toCreate, idx) } } + for _, idx := range gotIndexes { + if !slices.ContainsFunc(indexes, func(i anystore.IndexInfo) bool { + return i.Name == idx.Info().Name + }) { + toDrop = append(toDrop, idx.Info().Name) + } + } + if len(toDrop) > 0 { + for _, indexName := range toDrop { + if err := coll.DropIndex(ctx, indexName); err != nil { + return err + } + } + } return coll.EnsureIndex(ctx, toCreate...) } +func (s *dsObjectStore) WriteTx(ctx context.Context) (anystore.WriteTx, error) { + return s.anyStore.WriteTx(ctx) +} + func (s *dsObjectStore) Close(_ context.Context) (err error) { s.componentCtxCancel() if s.objects != nil { diff --git a/pkg/lib/localstore/objectstore/objects_test.go b/pkg/lib/localstore/objectstore/objects_test.go index 201f03bce4..21470191ec 100644 --- a/pkg/lib/localstore/objectstore/objects_test.go +++ b/pkg/lib/localstore/objectstore/objects_test.go @@ -67,7 +67,7 @@ func Test_removeByPrefix(t *testing.T) { bundle.RelationKeySpaceId: pbtypes.String(spaceId), }) require.NoError(t, s.UpdateObjectDetails(context2.Background(), objId, details)) - require.NoError(t, s.UpdateObjectLinks(objId, links)) + require.NoError(t, s.UpdateObjectLinks(ctx, objId, links)) } // Test huge transaction @@ -175,7 +175,7 @@ func TestGetWithLinksInfoByID(t *testing.T) { obj3 := makeObjectWithName("id3", "name3") s.AddObjects(t, []TestObject{obj1, obj2, obj3}) - err := s.UpdateObjectLinks("id1", []string{"id2", "id3"}) + err := s.UpdateObjectLinks(ctx, "id1", []string{"id2", "id3"}) require.NoError(t, err) t.Run("links of first object", func(t *testing.T) { @@ -250,13 +250,13 @@ func TestDeleteObject(t *testing.T) { obj := makeObjectWithName("id1", "name1") s.AddObjects(t, []TestObject{obj}) - err := s.UpdateObjectLinks("id2", []string{"id1"}) + err := s.UpdateObjectLinks(ctx, "id2", []string{"id1"}) require.NoError(t, err) - err = s.SaveLastIndexedHeadsHash("id1", "hash1") + err = s.SaveLastIndexedHeadsHash(ctx, "id1", "hash1") require.NoError(t, err) - err = s.AddToIndexQueue("id1") + err = s.AddToIndexQueue(ctx, "id1") require.NoError(t, err) // Act @@ -286,7 +286,7 @@ func TestDeleteObject(t *testing.T) { require.NoError(t, err) assert.Empty(t, inbound) - hash, err := s.GetLastIndexedHeadsHash("id1") + hash, err := s.GetLastIndexedHeadsHash(ctx, "id1") require.NoError(t, err) assert.Empty(t, hash) @@ -300,7 +300,7 @@ func TestDeleteDetails(t *testing.T) { s := NewStoreFixture(t) s.AddObjects(t, []TestObject{makeObjectWithName("id1", "name1")}) - err := s.DeleteDetails("id1") + err := s.DeleteDetails(ctx, "id1") require.NoError(t, err) got, err := s.GetDetails("id1") diff --git a/pkg/lib/localstore/objectstore/update.go b/pkg/lib/localstore/objectstore/update.go index 62569bf81b..bf00d55934 100644 --- a/pkg/lib/localstore/objectstore/update.go +++ b/pkg/lib/localstore/objectstore/update.go @@ -72,8 +72,8 @@ func (s *dsObjectStore) migrateLocalDetails(objectId string, details *types.Stru return true } -func (s *dsObjectStore) UpdateObjectLinks(id string, links []string) error { - added, removed, err := s.updateObjectLinks(s.componentCtx, id, links) +func (s *dsObjectStore) UpdateObjectLinks(ctx context.Context, id string, links []string) error { + added, removed, err := s.updateObjectLinks(ctx, id, links) if err != nil { return err } diff --git a/pkg/lib/localstore/objectstore/update_test.go b/pkg/lib/localstore/objectstore/update_test.go index f5a1927260..6285421fea 100644 --- a/pkg/lib/localstore/objectstore/update_test.go +++ b/pkg/lib/localstore/objectstore/update_test.go @@ -277,7 +277,7 @@ func TestUpdateObjectLinks(t *testing.T) { t.Run("with no links added", func(t *testing.T) { s := NewStoreFixture(t) - err := s.UpdateObjectLinks("id1", []string{}) + err := s.UpdateObjectLinks(ctx, "id1", []string{}) require.NoError(t, err) out, err := s.GetOutboundLinksByID("id1") @@ -288,7 +288,7 @@ func TestUpdateObjectLinks(t *testing.T) { t.Run("with some links added", func(t *testing.T) { s := NewStoreFixture(t) - err := s.UpdateObjectLinks("id1", []string{"id2", "id3"}) + err := s.UpdateObjectLinks(ctx, "id1", []string{"id2", "id3"}) require.NoError(t, err) s.assertOutboundLinks(t, "id1", []string{"id2", "id3"}) @@ -301,7 +301,7 @@ func TestUpdateObjectLinks(t *testing.T) { s.givenExistingLinks(t) - err := s.UpdateObjectLinks("id1", []string{"id2", "id3"}) + err := s.UpdateObjectLinks(ctx, "id1", []string{"id2", "id3"}) require.NoError(t, err) s.assertOutboundLinks(t, "id1", []string{"id2", "id3"}) @@ -314,7 +314,7 @@ func TestUpdateObjectLinks(t *testing.T) { s.givenExistingLinks(t) - err := s.UpdateObjectLinks("id1", []string{}) + err := s.UpdateObjectLinks(ctx, "id1", []string{}) require.NoError(t, err) s.assertOutboundLinks(t, "id1", nil) @@ -344,7 +344,7 @@ func (fx *StoreFixture) assertOutboundLinks(t *testing.T, id string, links []str } func (fx *StoreFixture) givenExistingLinks(t *testing.T) { - err := fx.UpdateObjectLinks("id1", []string{"id2"}) + err := fx.UpdateObjectLinks(ctx, "id1", []string{"id2"}) require.NoError(t, err) fx.assertOutboundLinks(t, "id1", []string{"id2"}) diff --git a/pkg/lib/localstore/objectstore/virtual_space_store.go b/pkg/lib/localstore/objectstore/virtual_space_store.go index cee623f8db..7ff03113b5 100644 --- a/pkg/lib/localstore/objectstore/virtual_space_store.go +++ b/pkg/lib/localstore/objectstore/virtual_space_store.go @@ -77,7 +77,7 @@ func (s *dsObjectStore) DeleteVirtualSpace(spaceID string) error { if err != nil { return err } - err = s.DeleteDetails(ids...) + err = s.DeleteDetails(s.componentCtx, ids...) if err != nil { return err } diff --git a/util/testMock/objectstore_mock.go b/util/testMock/objectstore_mock.go index ad72600fe9..211b776cd5 100644 --- a/util/testMock/objectstore_mock.go +++ b/util/testMock/objectstore_mock.go @@ -13,6 +13,7 @@ import ( context "context" reflect "reflect" + anystore "github.com/anyproto/any-store" app "github.com/anyproto/any-sync/app" coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" domain "github.com/anyproto/anytype-heart/core/domain" @@ -49,17 +50,17 @@ func (m *MockObjectStore) EXPECT() *MockObjectStoreMockRecorder { } // AddToIndexQueue mocks base method. -func (m *MockObjectStore) AddToIndexQueue(arg0 string) error { +func (m *MockObjectStore) AddToIndexQueue(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddToIndexQueue", arg0) + ret := m.ctrl.Call(m, "AddToIndexQueue", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // AddToIndexQueue indicates an expected call of AddToIndexQueue. -func (mr *MockObjectStoreMockRecorder) AddToIndexQueue(arg0 any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) AddToIndexQueue(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToIndexQueue", reflect.TypeOf((*MockObjectStore)(nil).AddToIndexQueue), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToIndexQueue", reflect.TypeOf((*MockObjectStore)(nil).AddToIndexQueue), arg0, arg1) } // BatchProcessFullTextQueue mocks base method. @@ -91,10 +92,10 @@ func (mr *MockObjectStoreMockRecorder) Close(arg0 any) *gomock.Call { } // DeleteDetails mocks base method. -func (m *MockObjectStore) DeleteDetails(arg0 ...string) error { +func (m *MockObjectStore) DeleteDetails(arg0 context.Context, arg1 ...string) error { m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { + varargs := []any{arg0} + for _, a := range arg1 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "DeleteDetails", varargs...) @@ -103,9 +104,10 @@ func (m *MockObjectStore) DeleteDetails(arg0 ...string) error { } // DeleteDetails indicates an expected call of DeleteDetails. -func (mr *MockObjectStoreMockRecorder) DeleteDetails(arg0 ...any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) DeleteDetails(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDetails", reflect.TypeOf((*MockObjectStore)(nil).DeleteDetails), arg0...) + varargs := append([]any{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDetails", reflect.TypeOf((*MockObjectStore)(nil).DeleteDetails), varargs...) } // DeleteLinks mocks base method. @@ -324,18 +326,18 @@ func (mr *MockObjectStoreMockRecorder) GetInboundLinksByID(arg0 any) *gomock.Cal } // GetLastIndexedHeadsHash mocks base method. -func (m *MockObjectStore) GetLastIndexedHeadsHash(arg0 string) (string, error) { +func (m *MockObjectStore) GetLastIndexedHeadsHash(arg0 context.Context, arg1 string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastIndexedHeadsHash", arg0) + ret := m.ctrl.Call(m, "GetLastIndexedHeadsHash", arg0, arg1) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // GetLastIndexedHeadsHash indicates an expected call of GetLastIndexedHeadsHash. -func (mr *MockObjectStoreMockRecorder) GetLastIndexedHeadsHash(arg0 any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) GetLastIndexedHeadsHash(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).GetLastIndexedHeadsHash), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).GetLastIndexedHeadsHash), arg0, arg1) } // GetObjectByUniqueKey mocks base method. @@ -772,17 +774,17 @@ func (mr *MockObjectStoreMockRecorder) SaveChecksums(arg0, arg1 any) *gomock.Cal } // SaveLastIndexedHeadsHash mocks base method. -func (m *MockObjectStore) SaveLastIndexedHeadsHash(arg0, arg1 string) error { +func (m *MockObjectStore) SaveLastIndexedHeadsHash(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveLastIndexedHeadsHash", arg0, arg1) + ret := m.ctrl.Call(m, "SaveLastIndexedHeadsHash", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // SaveLastIndexedHeadsHash indicates an expected call of SaveLastIndexedHeadsHash. -func (mr *MockObjectStoreMockRecorder) SaveLastIndexedHeadsHash(arg0, arg1 any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) SaveLastIndexedHeadsHash(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).SaveLastIndexedHeadsHash), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).SaveLastIndexedHeadsHash), arg0, arg1, arg2) } // SaveVirtualSpace mocks base method. @@ -854,17 +856,17 @@ func (mr *MockObjectStoreMockRecorder) UpdateObjectDetails(arg0, arg1, arg2 any) } // UpdateObjectLinks mocks base method. -func (m *MockObjectStore) UpdateObjectLinks(arg0 string, arg1 []string) error { +func (m *MockObjectStore) UpdateObjectLinks(arg0 context.Context, arg1 string, arg2 []string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateObjectLinks", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateObjectLinks", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // UpdateObjectLinks indicates an expected call of UpdateObjectLinks. -func (mr *MockObjectStoreMockRecorder) UpdateObjectLinks(arg0, arg1 any) *gomock.Call { +func (mr *MockObjectStoreMockRecorder) UpdateObjectLinks(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectLinks", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectLinks), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectLinks", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectLinks), arg0, arg1, arg2) } // UpdatePendingLocalDetails mocks base method. @@ -880,3 +882,18 @@ func (mr *MockObjectStoreMockRecorder) UpdatePendingLocalDetails(arg0, arg1 any) mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePendingLocalDetails", reflect.TypeOf((*MockObjectStore)(nil).UpdatePendingLocalDetails), arg0, arg1) } + +// WriteTx mocks base method. +func (m *MockObjectStore) WriteTx(arg0 context.Context) (anystore.WriteTx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteTx", arg0) + ret0, _ := ret[0].(anystore.WriteTx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WriteTx indicates an expected call of WriteTx. +func (mr *MockObjectStoreMockRecorder) WriteTx(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteTx", reflect.TypeOf((*MockObjectStore)(nil).WriteTx), arg0) +}