diff --git a/src/Squidex.Domain.Apps.Entities/Contents/ContentQueryService.cs b/src/Squidex.Domain.Apps.Entities/Contents/ContentQueryService.cs index 2d90d55db..c4840e906 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/ContentQueryService.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/ContentQueryService.cs @@ -212,10 +212,14 @@ namespace Squidex.Domain.Apps.Entities.Contents result.Data = result.Data.ConvertName2Name(schema.SchemaDef, converters); } - if (result.DataDraft != null) + if (result.DataDraft != null && (context.Unpublished || context.IsFrontendClient)) { result.DataDraft = result.DataDraft.ConvertName2Name(schema.SchemaDef, converters); } + else + { + result.DataDraft = null; + } yield return result; } diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/GrainTextIndexer.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/GrainTextIndexer.cs index 697668f76..81477f7aa 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/GrainTextIndexer.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/GrainTextIndexer.cs @@ -46,11 +46,35 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text this.log = log; } + public bool Handles(StoredEvent @event) + { + return true; + } + public Task ClearAsync() { return Task.CompletedTask; } + public async Task IndexAsync(Guid schemaId, Guid id, NamedContentData data, NamedContentData dataDraft) + { + var index = grainFactory.GetGrain(schemaId); + + using (Profiler.TraceMethod()) + { + try + { + await index.IndexAsync(id, new IndexData { Data = data, DataDraft = dataDraft }, false); + } + catch (Exception ex) + { + log.LogError(ex, w => w + .WriteProperty("action", "UpdateTextEntry") + .WriteProperty("status", "Failed")); + } + } + } + public async Task On(Envelope @event) { try @@ -75,10 +99,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text case ContentUpdated contentUpdated: await index.IndexAsync(id, Data(contentUpdated.Data), false); break; - case ContentChangesPublished contentChangesPublished: + case ContentChangesDiscarded contentChangesDiscarded: await index.CopyAsync(id, false); break; - case ContentChangesDiscarded contentChangesDiscarded: + case ContentChangesPublished contentChangesPublished: case ContentStatusChanged contentStatusChanged when contentStatusChanged.Status == Status.Published: await index.CopyAsync(id, true); break; diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/ITextIndexer.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/ITextIndexer.cs index 77270fefc..1e2d62618 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/ITextIndexer.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/ITextIndexer.cs @@ -8,12 +8,15 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities.Apps; namespace Squidex.Domain.Apps.Entities.Contents.Text { public interface ITextIndexer { + Task IndexAsync(Guid schemaId, Guid contentId, NamedContentData draftData, NamedContentData data); + Task> SearchAsync(string queryText, IAppEntity app, Guid schemaId, bool useDraft = false); } } diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexData.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexData.cs index 240cc0fda..e6c469ddc 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexData.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexData.cs @@ -12,5 +12,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text public sealed class IndexData { public NamedContentData Data { get; set; } + + public NamedContentData DataDraft { get; set; } } } diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs index d6becb142..ff97da642 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs @@ -77,7 +77,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text return true; } - public void Index(NamedContentData data, bool onlyDraft) + public void Index(NamedContentData data, NamedContentData dataDraft, bool onlyDraft) { var converted = CreateDocument(data); @@ -85,7 +85,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text var existing = GetDocument(1); - if (IsForPublished(existing)) + if (dataDraft != null) + { + converted = CreateDocument(dataDraft); + + Upsert(converted, 0, 0, 1); + } + else if (IsForPublished(existing)) { Upsert(converted, 0, 0, 1); } @@ -109,8 +115,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text { if (fromDraft) { - Update(1, 1, 0); - Update(0, 0, 1); + Update(1, 0, 0); + Update(0, 1, 1); } else { diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexerGrain.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexerGrain.cs index cb07d9463..cb0f0a202 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexerGrain.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexerGrain.cs @@ -29,7 +29,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text private const LuceneVersion Version = LuceneVersion.LUCENE_48; private const int MaxResults = 2000; private const int MaxUpdates = 100; - private static readonly TimeSpan CommitDelay = TimeSpan.FromSeconds(30); + private static readonly TimeSpan CommitDelay = TimeSpan.FromSeconds(10); private static readonly Analyzer Analyzer = new MultiLanguageAnalyzer(Version); private static readonly string[] Invariant = { InvariantPartitioning.Instance.Master.Key }; private readonly SnapshotDeletionPolicy snapshotter = new SnapshotDeletionPolicy(new KeepOnlyLastCommitDeletionPolicy()); @@ -90,7 +90,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text { var content = new TextIndexContent(indexWriter, indexSearcher, id); - content.Index(data.Value.Data, onlyDraft); + content.Index(data.Value.Data, data.Value.DataDraft, onlyDraft); return TryFlushAsync(); } diff --git a/src/Squidex/Config/Domain/StoreServices.cs b/src/Squidex/Config/Domain/StoreServices.cs index 218f124a0..584cdb7b6 100644 --- a/src/Squidex/Config/Domain/StoreServices.cs +++ b/src/Squidex/Config/Domain/StoreServices.cs @@ -107,7 +107,8 @@ namespace Squidex.Config.Domain c.GetRequiredService().GetDatabase(mongoContentDatabaseName), c.GetRequiredService(), c.GetRequiredService(), - c.GetRequiredService())) + c.GetRequiredService(), + c.GetRequiredService())) .AsOptional() .AsOptional>() .AsOptional(); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/GrainTextIndexerTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/GrainTextIndexerTests.cs index 665ea2a4e..281f4413f 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/GrainTextIndexerTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/GrainTextIndexerTests.cs @@ -38,6 +38,18 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text sut = new GrainTextIndexer(grainFactory, A.Fake()); } + [Fact] + public async Task Should_call_grain_when_indexing_data() + { + var data = new NamedContentData(); + var dataDraft = new NamedContentData(); + + await sut.IndexAsync(schemaId, contentId, data, dataDraft); + + A.CallTo(() => grain.IndexAsync(contentId, A>.That.Matches(x => x.Value.Data == data && x.Value.DataDraft == dataDraft), false)) + .MustHaveHappened(); + } + [Fact] public async Task Should_call_grain_when_content_deleted() { @@ -87,7 +99,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text await sut.On(E(new ContentChangesPublished())); - A.CallTo(() => grain.CopyAsync(contentId, false)) + A.CallTo(() => grain.CopyAsync(contentId, true)) .MustHaveHappened(); } @@ -98,7 +110,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text await sut.On(E(new ContentChangesDiscarded())); - A.CallTo(() => grain.CopyAsync(contentId, true)) + A.CallTo(() => grain.CopyAsync(contentId, false)) .MustHaveHappened(); }