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; 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 ? 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); } 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); }; } }