Exemplo n.º 1
0
        public void DocumentsShouldBeDeleted()
        {
            _provider.CreateIndex("default");
            _provider.Store("default", _provider.New(1).Add("field", "value1"));
            _provider.Store("default", _provider.New(11).Add("field", "value11"));
            _provider.Store("default", _provider.New(111).Add("field", "value111"));

            var searchBuilder = _provider.CreateSearchBuilder("default");

            Assert.That(searchBuilder.Get(1).ContentItemId, Is.EqualTo(1));
            Assert.That(searchBuilder.Get(11).ContentItemId, Is.EqualTo(11));
            Assert.That(searchBuilder.Get(111).ContentItemId, Is.EqualTo(111));

            _provider.Delete("default", 1);

            Assert.That(searchBuilder.Get(1), Is.Null);
            Assert.That(searchBuilder.Get(11).ContentItemId, Is.EqualTo(11));
            Assert.That(searchBuilder.Get(111).ContentItemId, Is.EqualTo(111));

            _provider.Delete("default", new [] { 1, 11, 111 });

            Assert.That(searchBuilder.Get(1), Is.Null);
            Assert.That(searchBuilder.Get(11), Is.Null);
            Assert.That(searchBuilder.Get(111), Is.Null);
        }
        public Task HandleAsync(RemoveDocumentDirectoryCommand command, CancellationToken cancellationToken = default(CancellationToken), IProgress <ProgressInfo> progress = null)
        {
            return(Task.Run(() => {
                var actualStep = 0;
                var totalSteps = 2;

                try {
                    progress.Start(totalSteps, Strings.RemoveDocumentDirectory_Progress_Start_Title);

                    var documentDirectory = _database.ExecuteReaderSingle(SQLs.GetDocumentDirectory, DocumentDirectory.Map, parameters: new[] {
                        Parameter.CreateInputParameter(Common.DatabaseSchema.DocumentDirectories.DocumentDirectoryID, command.DocumentDirectoryID, DbType.Int32)
                    });

                    using (var transaction = _database.Connection.BeginTransaction()) {
                        progress.PerformStep(++actualStep, totalSteps, Strings.RemoveDocumentDirectory_Progress_Step_Database_Message, documentDirectory.Label);

                        _database.ExecuteScalar(SQLs.RemoveDocumentDirectory, parameters: new[] {
                            Parameter.CreateInputParameter(Common.DatabaseSchema.DocumentDirectories.DocumentDirectoryID, documentDirectory.DocumentDirectoryID, DbType.Int32)
                        });

                        if (cancellationToken.IsCancellationRequested)
                        {
                            progress.Cancel(actualStep, totalSteps);

                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        transaction.Commit();
                    }

                    progress.PerformStep(++actualStep, totalSteps, Strings.RemoveDocumentDirectory_Progress_Step_Index_Message, documentDirectory.Label);
                    _indexProvider
                    .Delete(documentDirectory.Code);

                    progress.Complete(actualStep, totalSteps);
                } catch (Exception ex) { progress.Error(actualStep, totalSteps, ex.Message); throw; }
            }, cancellationToken));
        }
        /// <summary>
        /// Indexes a batch of content items
        /// </summary>
        /// <returns>
        /// <c>true</c> if there are more items to process; otherwise, <c>false</c>.
        /// </returns>
        private bool BatchIndex(string indexName, string settingsFilename, IndexSettings indexSettings)
        {
            var  addToIndex      = new List <IDocumentIndex>();
            var  deleteFromIndex = new List <int>();
            bool loop            = false;

            // Rebuilding the index ?
            if (indexSettings.Mode == IndexingMode.Rebuild)
            {
                Logger.Information("Rebuilding index");
                _indexingStatus = IndexingStatus.Rebuilding;

                do
                {
                    loop = true;

                    // load all content items
                    var contentItems = _contentRepository
                                       .Table.Where(versionRecord => versionRecord.Latest && versionRecord.Id > indexSettings.LastContentId)
                                       .OrderBy(versionRecord => versionRecord.Id)
                                       .Take(ContentItemsPerLoop)
                                       .ToList()
                                       .Select(versionRecord => _contentManager.Get(versionRecord.ContentItemRecord.Id, VersionOptions.VersionRecord(versionRecord.Id)))
                                       .Distinct()
                                       .ToList();

                    // if no more elements to index, switch to update mode
                    if (contentItems.Count == 0)
                    {
                        indexSettings.Mode = IndexingMode.Update;
                    }

                    foreach (var item in contentItems)
                    {
                        try {
                            var settings = GetTypeIndexingSettings(item);

                            // skip items from types which are not indexed
                            if (settings.List.Contains(indexName))
                            {
                                if (item.HasPublished())
                                {
                                    var            published     = _contentManager.Get(item.Id, VersionOptions.Published);
                                    IDocumentIndex documentIndex = ExtractDocumentIndex(published);

                                    if (documentIndex != null && documentIndex.IsDirty)
                                    {
                                        addToIndex.Add(documentIndex);
                                    }
                                }
                            }
                            else if (settings.List.Contains(indexName + ":latest"))
                            {
                                IDocumentIndex documentIndex = ExtractDocumentIndex(item);

                                if (documentIndex != null && documentIndex.IsDirty)
                                {
                                    addToIndex.Add(documentIndex);
                                }
                            }

                            indexSettings.LastContentId = item.VersionRecord.Id;
                        }
                        catch (Exception ex) {
                            Logger.Warning(ex, "Unable to index content item #{0} during rebuild", item.Id);
                        }
                    }

                    if (contentItems.Count < ContentItemsPerLoop)
                    {
                        loop = false;
                    }
                    else
                    {
                        _transactionManager.RequireNew();
                    }
                } while (loop);
            }

            if (indexSettings.Mode == IndexingMode.Update)
            {
                Logger.Information("Updating index");
                _indexingStatus = IndexingStatus.Updating;

                do
                {
                    var indexingTasks = _taskRepository
                                        .Table.Where(x => x.Id > indexSettings.LastIndexedId)
                                        .OrderBy(x => x.Id)
                                        .Take(ContentItemsPerLoop)
                                        .ToList()
                                        .GroupBy(x => x.ContentItemRecord.Id)
                                        .Select(group => new { TaskId = group.Max(task => task.Id), Delete = group.Last().Action == IndexingTaskRecord.Delete, Id = group.Key, ContentItem = _contentManager.Get(group.Key, VersionOptions.Latest) })
                                        .OrderBy(x => x.TaskId)
                                        .ToArray();

                    foreach (var item in indexingTasks)
                    {
                        try {
                            IDocumentIndex documentIndex = null;

                            // item.ContentItem can be null if the content item has been deleted
                            if (item.ContentItem != null)
                            {
                                // skip items from types which are not indexed
                                var settings = GetTypeIndexingSettings(item.ContentItem);
                                if (settings.List.Contains(indexName))
                                {
                                    if (item.ContentItem.HasPublished())
                                    {
                                        var published = _contentManager.Get(item.Id, VersionOptions.Published);
                                        documentIndex = ExtractDocumentIndex(published);
                                    }
                                }
                                else if (settings.List.Contains(indexName + ":latest"))
                                {
                                    var latest = _contentManager.Get(item.Id, VersionOptions.Latest);
                                    documentIndex = ExtractDocumentIndex(latest);
                                }
                            }

                            if (documentIndex == null || item.Delete)
                            {
                                deleteFromIndex.Add(item.Id);
                            }
                            else if (documentIndex.IsDirty)
                            {
                                addToIndex.Add(documentIndex);
                            }

                            indexSettings.LastIndexedId = item.TaskId;
                        }
                        catch (Exception ex) {
                            Logger.Warning(ex, "Unable to index content item #{0} during update", item.Id);
                        }
                    }

                    if (indexingTasks.Length < ContentItemsPerLoop)
                    {
                        loop = false;
                    }
                    else
                    {
                        _transactionManager.RequireNew();
                    }
                } while (loop);
            }

            // save current state of the index
            indexSettings.LastIndexedUtc = _clock.UtcNow;
            _appDataFolder.CreateFile(settingsFilename, indexSettings.ToXml());

            if (deleteFromIndex.Count == 0 && addToIndex.Count == 0)
            {
                // nothing more to do
                _indexingStatus = IndexingStatus.Idle;
                return(false);
            }

            // save new and updated documents to the index
            try {
                if (addToIndex.Count > 0)
                {
                    _indexProvider.Store(indexName, addToIndex);
                    Logger.Information("Added content items to index: {0}", addToIndex.Count);
                }
            }
            catch (Exception ex) {
                Logger.Warning(ex, "An error occured while adding a document to the index");
            }

            // removing documents from the index
            try {
                if (deleteFromIndex.Count > 0)
                {
                    _indexProvider.Delete(indexName, deleteFromIndex);
                    Logger.Information("Added content items to index: {0}", addToIndex.Count);
                }
            }
            catch (Exception ex) {
                Logger.Warning(ex, "An error occured while removing a document from the index");
            }

            return(true);
        }