From 68a2f6dc51d7420dc24d7a6eacaa1a7759894acd Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Wed, 5 Jan 2011 16:25:51 -0800 Subject: [PATCH 1/4] Invalidate cached configuration when path changes The nhibernate configuration stores the physical path to the SqlCe database so we need to include the physical location as part of the hash key, so that xcopy migrations work as expected. Work Item: 17159 --HG-- branch : 1.x --- src/Orchard/Data/SessionConfigurationCache.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Orchard/Data/SessionConfigurationCache.cs b/src/Orchard/Data/SessionConfigurationCache.cs index 11b744a65..2bc3a3a7c 100644 --- a/src/Orchard/Data/SessionConfigurationCache.cs +++ b/src/Orchard/Data/SessionConfigurationCache.cs @@ -104,12 +104,20 @@ namespace Orchard.Data { private Hash ComputeHash() { var hash = new Hash(); + // Shell settings physical location + // The nhibernate configuration stores the physical path to the SqlCe database + // so we need to include the physical location as part of the hash key, so that + // xcopy migrations work as expected. + var pathName = GetPathName(_shellSettings.Name); + hash.AddString(_appDataFolder.MapPath(pathName).ToLowerInvariant()); + + // Shell settings data hash.AddString(_shellSettings.DataProvider); hash.AddString(_shellSettings.DataTablePrefix); hash.AddString(_shellSettings.DataConnectionString); hash.AddString(_shellSettings.Name); - // We need to hash the assemnly names, record names and property names + // Assembly names, record names and property names foreach (var tableName in _shellBlueprint.Records.Select(x => x.TableName)) { hash.AddString(tableName); } From cd9445930cdc41b64f1cd75921abde02d5b62a09 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Wed, 5 Jan 2011 17:28:48 -0800 Subject: [PATCH 2/4] Fix threading issue Work Item: 17154 --HG-- branch : 1.x --- src/Orchard/Localization/LocalizationModule.cs | 13 +++---------- src/Orchard/Logging/LoggingModule.cs | 12 +++--------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/Orchard/Localization/LocalizationModule.cs b/src/Orchard/Localization/LocalizationModule.cs index 506e7b893..7939aab0b 100644 --- a/src/Orchard/Localization/LocalizationModule.cs +++ b/src/Orchard/Localization/LocalizationModule.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Reflection; using Autofac; using Autofac.Core; @@ -8,7 +7,7 @@ using Module = Autofac.Module; namespace Orchard.Localization { public class LocalizationModule : Module { - private readonly IDictionary _localizerCache; + private readonly ConcurrentDictionary _localizerCache; public LocalizationModule() { _localizerCache = new ConcurrentDictionary(); @@ -26,14 +25,8 @@ namespace Orchard.Localization { var scope = registration.Activator.LimitType.FullName; registration.Activated += (sender, e) => { - if (_localizerCache.ContainsKey(scope)) { - userProperty.SetValue(e.Instance, _localizerCache[scope], null); - } - else { - var localizer = LocalizationUtilities.Resolve(e.Context, scope); - _localizerCache.Add(scope, localizer); - userProperty.SetValue(e.Instance, localizer, null); - } + var localizer = _localizerCache.GetOrAdd(scope, key => LocalizationUtilities.Resolve(e.Context, scope)); + userProperty.SetValue(e.Instance, localizer, null); }; } } diff --git a/src/Orchard/Logging/LoggingModule.cs b/src/Orchard/Logging/LoggingModule.cs index bf3528460..559458f19 100644 --- a/src/Orchard/Logging/LoggingModule.cs +++ b/src/Orchard/Logging/LoggingModule.cs @@ -11,7 +11,7 @@ using Module = Autofac.Module; namespace Orchard.Logging { public class LoggingModule : Module { - private readonly IDictionary _loggerCache; + private readonly ConcurrentDictionary _loggerCache; public LoggingModule() { _loggerCache = new ConcurrentDictionary(); @@ -63,14 +63,8 @@ namespace Orchard.Logging { yield return (ctx, instance) => { string component = componentType.ToString(); - if (_loggerCache.ContainsKey(component)) { - propertyInfo.SetValue(instance, _loggerCache[component], null); - } - else { - var propertyValue = ctx.Resolve(new TypedParameter(typeof(Type), componentType)); - _loggerCache.Add(component, propertyValue); - propertyInfo.SetValue(instance, propertyValue, null); - } + var logger = _loggerCache.GetOrAdd(component, key => ctx.Resolve(new TypedParameter(typeof(Type), componentType))); + propertyInfo.SetValue(instance, logger, null); }; } } From d2f86be59f9cf3ba45e430a86c920eeb1db877f6 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 5 Jan 2011 17:32:35 -0800 Subject: [PATCH 3/4] Fixing search task discovery If a background task was creating a content item, the index task might not see it if the creation was done in the same second. --HG-- branch : 1.x --- .../Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs index ef3d8c138..2de7e3269 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs @@ -101,7 +101,7 @@ namespace Orchard.Indexing.Services { // retrieve not yet processed tasks var taskRecords = lastIndexUtc == null ? _repository.Fetch(x => true).ToArray() - : _repository.Fetch(x => x.CreatedUtc > lastIndexUtc).ToArray(); + : _repository.Fetch(x => x.CreatedUtc >= lastIndexUtc).ToArray(); // CreatedUtc and lastIndexUtc might be equal if a content item is created in a background task // nothing to do ? From 7608894d0aaa3845aa27c7ffd31f42ce23fd91e2 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 5 Jan 2011 18:13:56 -0800 Subject: [PATCH 4/4] Fixing search commands Work Item: 17153 --HG-- branch : 1.x --- .../Modules/Lucene/Models/LuceneSearchHit.cs | 20 ++++-- .../Commands/IndexingCommands.cs | 69 +++++++------------ .../Orchard.Indexing/Services/IndexService.cs | 3 +- 3 files changed, 40 insertions(+), 52 deletions(-) diff --git a/src/Orchard.Web/Modules/Lucene/Models/LuceneSearchHit.cs b/src/Orchard.Web/Modules/Lucene/Models/LuceneSearchHit.cs index ed44a73f6..2c07a817a 100644 --- a/src/Orchard.Web/Modules/Lucene/Models/LuceneSearchHit.cs +++ b/src/Orchard.Web/Modules/Lucene/Models/LuceneSearchHit.cs @@ -1,4 +1,5 @@ -using Lucene.Net.Documents; +using System; +using Lucene.Net.Documents; using System.Globalization; using Lucene.Net.Util; using Orchard.Indexing; @@ -18,23 +19,28 @@ namespace Lucene.Models { public int ContentItemId { get { return int.Parse(GetString("id")); } } public int GetInt(string name) { - return NumericUtils.PrefixCodedToInt(_doc.GetField(name).StringValue()); + var field = _doc.GetField(name); + return field == null ? 0 : NumericUtils.PrefixCodedToInt(field.StringValue()); } public float GetFloat(string name) { - return float.Parse(_doc.GetField(name).StringValue(), CultureInfo.InvariantCulture); + var field = _doc.GetField(name); + return field == null ? 0 : float.Parse(field.StringValue(), CultureInfo.InvariantCulture); } public bool GetBoolean(string name) { - return bool.Parse(_doc.GetField(name).StringValue()); + var field = _doc.GetField(name); + return field == null ? false : bool.Parse(field.StringValue()); } public string GetString(string name) { - return _doc.GetField(name).StringValue(); + var field = _doc.GetField(name); + return field == null ? null : field.StringValue(); } - public System.DateTime GetDateTime(string name) { - return DateTools.StringToDate(_doc.GetField(name).StringValue()); + public DateTime GetDateTime(string name) { + var field = _doc.GetField(name); + return field == null ? DateTime.MinValue : DateTools.StringToDate(field.StringValue()); } } } diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Commands/IndexingCommands.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Commands/IndexingCommands.cs index a6a886b45..b8b702044 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Commands/IndexingCommands.cs +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Commands/IndexingCommands.cs @@ -3,30 +3,29 @@ using System.Collections.Generic; using System.Linq; using Orchard.Commands; using Orchard.ContentManagement; +using Orchard.ContentManagement.Aspects; +using Orchard.Indexing.Services; using Orchard.Tasks.Indexing; namespace Orchard.Indexing.Commands { public class IndexingCommands : DefaultOrchardCommandHandler { - private readonly IEnumerable _indexNotifierHandlers; private readonly IIndexManager _indexManager; + private readonly IIndexingService _indexingService; private readonly IIndexingTaskManager _indexingTaskManager; private readonly IContentManager _contentManager; private const string SearchIndexName = "Search"; public IndexingCommands( - IEnumerable indexNotifierHandlers, IIndexManager indexManager, + IIndexingService indexingService, IIndexingTaskManager indexingTaskManager, IContentManager contentManager) { - _indexNotifierHandlers = indexNotifierHandlers; _indexingTaskManager = indexingTaskManager; _contentManager = contentManager; _indexManager = indexManager; + _indexingService = indexingService; } - [OrchardSwitch] - public string IndexName { get; set; } - [OrchardSwitch] public string Query { get; set; } @@ -34,48 +33,31 @@ namespace Orchard.Indexing.Commands { public string ContentItem { get; set; } [CommandName("index update")] - [CommandHelp("index update [/IndexName:]\r\n\t" + "Updates the index with the specified , or the search index if not specified")] - [OrchardSwitches("IndexName")] + [CommandHelp("index update\r\n\t" + "Updates the search index")] public string Update() { - if ( !_indexManager.HasIndexProvider() ) { - throw new OrchardException(T("No index available")); - } - - var indexName = String.IsNullOrWhiteSpace(IndexName) ? SearchIndexName : IndexName; - foreach ( var handler in _indexNotifierHandlers ) { - handler.UpdateIndex(indexName); - } + _indexingService.UpdateIndex(); - return "Index is now being updated..."; + return T("Index is now being updated...").Text; } [CommandName("index rebuild")] - [CommandHelp("index rebuild [/IndexName:]\r\n\t" + "Rebuilds the index with the specified , or the search index if not specified")] - [OrchardSwitches("IndexName")] + [CommandHelp("index rebuild \r\n\t" + "Rebuilds the search index")] public string Rebuild() { - if ( !_indexManager.HasIndexProvider() ) { - throw new OrchardException(T("No index available")); - } + _indexingService.RebuildIndex(); + _indexingService.UpdateIndex(); - var indexName = String.IsNullOrWhiteSpace(IndexName) ? SearchIndexName : IndexName; - var searchProvider = _indexManager.GetSearchIndexProvider(); - if ( searchProvider.Exists(indexName) ) - searchProvider.DeleteIndex(indexName); - - searchProvider.CreateIndex(indexName); - return "Index is now being rebuilt..."; + return T("Index is now being rebuilt...").Text; } [CommandName("index search")] - [CommandHelp("index search /Query: [/IndexName:]\r\n\t" + "Searches the specified terms in the index with the specified , or in the search index if not specified")] - [OrchardSwitches("Query,IndexName")] + [CommandHelp("index search /Query:\r\n\t" + "Searches the specified terms in the search index")] + [OrchardSwitches("Query")] public string Search() { if ( !_indexManager.HasIndexProvider() ) { throw new OrchardException(T("No index available")); } - var indexName = String.IsNullOrWhiteSpace(IndexName) ? SearchIndexName : IndexName; - var searchBuilder = _indexManager.GetSearchIndexProvider().CreateSearchBuilder(indexName); - var results = searchBuilder.WithField("body", Query).WithField("title", Query).Search(); + var searchBuilder = _indexManager.GetSearchIndexProvider().CreateSearchBuilder(SearchIndexName); + var results = searchBuilder.Parse( new [] {"body", "title"}, Query).Search(); Context.Output.WriteLine("{0} result{1}\r\n-----------------\r\n", results.Count(), results.Count() > 0 ? "s" : ""); @@ -83,27 +65,28 @@ namespace Orchard.Indexing.Commands { Context.Output.WriteLine("│ {0} │ {1,6} │", "Title" + new string(' ', 60 - "Title".Length), "Score"); Context.Output.WriteLine("├──────────────────────────────────────────────────────────────┼────────┤"); foreach ( var searchHit in results ) { - var title = searchHit.GetString("title") ?? "- no title -"; + var contentItem = _contentManager.Get(searchHit.ContentItemId); + var routable = contentItem.As(); + var title = routable == null ? "- no title -" : routable.Title; title = title.Substring(0, Math.Min(60, title.Length)); - var score = searchHit.Score; + var score = Math.Round(searchHit.Score, 2).ToString(); Context.Output.WriteLine("│ {0} │ {1,6} │", title + new string(' ', 60 - title.Length), score); } Context.Output.WriteLine("└──────────────────────────────────────────────────────────────┴────────┘"); Context.Output.WriteLine(); - return "End of search results"; + return T("End of search results").Text; } [CommandName("index stats")] - [CommandHelp("index stats [/IndexName:]\r\n\t" + "Displays some statistics about the index with the specified , or in the search index if not specified")] + [CommandHelp("index stats\r\n\t" + "Displays some statistics about the search index")] [OrchardSwitches("IndexName")] public string Stats() { if ( !_indexManager.HasIndexProvider() ) { throw new OrchardException(T("No index available")); } - var indexName = String.IsNullOrWhiteSpace(IndexName) ? SearchIndexName : IndexName; - Context.Output.WriteLine("Number of indexed documents: {0}", _indexManager.GetSearchIndexProvider().NumDocs(indexName)); - return ""; + + return T("Number of indexed documents: {0}", _indexManager.GetSearchIndexProvider().NumDocs(SearchIndexName)).Text; } [CommandName("index refresh")] @@ -118,7 +101,7 @@ namespace Orchard.Indexing.Commands { var contentItem = _contentManager.Get(contentItemId); _indexingTaskManager.CreateUpdateIndexTask(contentItem); - return "Content Item marked for reindexing"; + return T("Content Item marked for reindexing").Text; } [CommandName("index delete")] @@ -133,7 +116,7 @@ namespace Orchard.Indexing.Commands { var contentItem = _contentManager.Get(contentItemId); _indexingTaskManager.CreateDeleteIndexTask(contentItem); - return "Content Item marked for deletion"; + return T("Content Item marked for deletion").Text; } } diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexService.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexService.cs index 2cb567de1..90014a203 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexService.cs +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexService.cs @@ -5,8 +5,7 @@ using Orchard.UI.Notify; namespace Orchard.Indexing.Services { - public class IndexingService : IIndexingService - { + public class IndexingService : IIndexingService { private const string SearchIndexName = "Search"; private readonly IIndexManager _indexManager; private readonly IEnumerable _indexNotifierHandlers;