diff --git a/.hgignore b/.hgignore index 1c1635c97..4e3fd9c8b 100644 --- a/.hgignore +++ b/.hgignore @@ -26,3 +26,4 @@ glob:src/Orchard.Azure/Orchard.Azure.Web/Modules glob:src/Orchard.Azure/Orchard.Azure.Web/Themes syntax: glob src/Orchard.Web/Orchard.Web.Publish.xml +glob:src/TestResults/* diff --git a/.hgsubstate b/.hgsubstate index ba1cea6bb..6e64ba657 100644 --- a/.hgsubstate +++ b/.hgsubstate @@ -1,5 +1,5 @@ 1f8f582859916d411b5333dd0f32f57da0e72ee8 src/Orchard.Web/Modules/Orchard.AntiSpam -bb8c612e72535cbb28b03efb5f7c52e79ced61cd src/Orchard.Web/Modules/Orchard.Autoroute +e270989b0b0bcee22c03021af5a028215bcdefe9 src/Orchard.Web/Modules/Orchard.Autoroute 2ca2dbbf97b7219f9150d46d52f62bc405c17673 src/Orchard.Web/Modules/Orchard.ContentPermissions e6e70d69f37e48ea6c8784e83a9af4103f5d0dde src/Orchard.Web/Modules/Orchard.ContentPicker b5ccdaed10ff8bcd5bc94d46541209873ae0f722 src/Orchard.Web/Modules/Orchard.CustomForms @@ -8,5 +8,5 @@ e57f4a5dffac99ac64e195ae6ee5f2d720876b52 src/Orchard.Web/Modules/Orchard.Rules c85cd1e9651e3e0bb1ca97442ce390bf34cf3c76 src/Orchard.Web/Modules/Orchard.TaskLease 6ce83f60624b333aa6e23e756c07181d9df40094 src/Orchard.Web/Modules/Orchard.Tokens 1b4c795960358a84c743eeb6bd778fabbdf8455e src/orchard.web/Modules/Orchard.Alias -a5b0e6345d1a316e7184d1e77905e1300390756e src/orchard.web/Modules/Orchard.Projections +8ca57ca0486ad535c6c5d6940ad6c4ddd71130d2 src/orchard.web/Modules/Orchard.Projections 01976daba529461b30b7959fd45488829cd45d3e src/orchard.web/modules/Orchard.Fields diff --git a/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs b/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs index ef6141fb2..0e23583bd 100644 --- a/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs +++ b/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs @@ -16,6 +16,7 @@ using Orchard.Tests.ContentManagement.Records; using Orchard.Tests.ContentManagement.Models; using Orchard.DisplayManagement.Implementation; using Orchard.Tests.Stubs; +using NHibernate.Impl; namespace Orchard.Tests.ContentManagement { [TestFixture] @@ -451,6 +452,58 @@ namespace Orchard.Tests.ContentManagement { Assert.That(listTwo.Count(), Is.EqualTo(2)); Assert.That(listThree.Count(), Is.EqualTo(1)); } + + [Test] + public void StartsWithExtensionShouldBeUsed() { + _manager.Create("gamma", init => { init.Record.Frap = "one"; }); + _manager.Create("gamma", init => { init.Record.Frap = "two"; }); + _manager.Create("gamma", init => { init.Record.Frap = "three"; }); + _manager.Create("gamma", init => { init.Record.Frap = "four"; }); + _session.Flush(); + + var result = _manager.Query() + .Where(x => x.Frap.StartsWith("t")) + .List(); + + Assert.That(result.Count(), Is.EqualTo(2)); + Assert.That(result.Count(x => x.Get().Record.Frap == "two"), Is.EqualTo(1)); + Assert.That(result.Count(x => x.Get().Record.Frap == "three"), Is.EqualTo(1)); + } + + [Test] + public void EndsWithExtensionShouldBeUsed() { + _manager.Create("gamma", init => { init.Record.Frap = "one"; }); + _manager.Create("gamma", init => { init.Record.Frap = "two"; }); + _manager.Create("gamma", init => { init.Record.Frap = "three"; }); + _manager.Create("gamma", init => { init.Record.Frap = "four"; }); + _session.Flush(); + + var result = _manager.Query() + .Where(x => x.Frap.EndsWith("e")) + .List(); + + Assert.That(result.Count(), Is.EqualTo(2)); + Assert.That(result.Count(x => x.Get().Record.Frap == "one"), Is.EqualTo(1)); + Assert.That(result.Count(x => x.Get().Record.Frap == "three"), Is.EqualTo(1)); + } + + [Test] + public void ContainsExtensionShouldBeUsed() { + _manager.Create("gamma", init => { init.Record.Frap = "one"; }); + _manager.Create("gamma", init => { init.Record.Frap = "two"; }); + _manager.Create("gamma", init => { init.Record.Frap = "three"; }); + _manager.Create("gamma", init => { init.Record.Frap = "four"; }); + _session.Flush(); + + var result = _manager.Query() + .Where(x => x.Frap.Contains("o")) + .List(); + + Assert.That(result.Count(), Is.EqualTo(3)); + Assert.That(result.Count(x => x.Get().Record.Frap == "one"), Is.EqualTo(1)); + Assert.That(result.Count(x => x.Get().Record.Frap == "two"), Is.EqualTo(1)); + Assert.That(result.Count(x => x.Get().Record.Frap == "four"), Is.EqualTo(1)); + } } } diff --git a/src/Orchard.Web/Modules/Markdown/Styles/admin-markdown.css b/src/Orchard.Web/Modules/Markdown/Styles/admin-markdown.css index 5cc806cca..73a77fc1c 100644 --- a/src/Orchard.Web/Modules/Markdown/Styles/admin-markdown.css +++ b/src/Orchard.Web/Modules/Markdown/Styles/admin-markdown.css @@ -55,19 +55,32 @@ .wmd-preview blockquote { margin: 1em 3em; - color: #999; + color: #333; border-left: 2px solid #999; padding-left: 1em; } .wmd-preview pre, .wmd-preview code { margin: 1em 3em; - color: #999; + color: #333; border-left: 2px solid #999; padding-left: 1em; font-family: Courier New; } +.wmd-preview pre code { + border: none; + margin-left: 0px; + padding-left: 0px; +} + + +.wmd-preview p code { + border: none; + margin: 0px; + padding: 0px; +} + /* Grippie */ div.grippie { diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs index b5045086a..bc090f338 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs @@ -132,7 +132,7 @@ namespace Orchard.Tags.Services { public IEnumerable GetTaggedContentItems(int tagId, int skip, int take, VersionOptions options) { return _orchardServices.ContentManager .Query() - .Where(tpr => tpr.Tags.Any(tr => tr.TagRecord.Id == tagId)) + .WhereAny(part => part.Tags, tag => tag.TagRecord.Id == tagId) .Join().OrderByDescending(x => x.CreatedUtc) .Slice(skip, take); } @@ -144,7 +144,7 @@ namespace Orchard.Tags.Services { public int GetTaggedContentItemCount(int tagId, VersionOptions options) { return _orchardServices.ContentManager .Query() - .Where(tpr => tpr.Tags.Any(tr => tr.TagRecord.Id == tagId)) + .WhereAny(part => part.Tags, tag => tag.TagRecord.Id == tagId) .Count(); } diff --git a/src/Orchard/ContentManagement/DefaultContentManager.cs b/src/Orchard/ContentManagement/DefaultContentManager.cs index cfd91b0b3..419dadcb2 100644 --- a/src/Orchard/ContentManagement/DefaultContentManager.cs +++ b/src/Orchard/ContentManagement/DefaultContentManager.cs @@ -34,6 +34,9 @@ namespace Orchard.ContentManagement { private const string Published = "Published"; private const string Draft = "Draft"; + static DefaultContentManager() { + RestrictionExtensions.RegisterExtensions(); + } public DefaultContentManager( IComponentContext context, IRepository contentTypeRepository, diff --git a/src/Orchard/ContentManagement/DefaultContentQuery.cs b/src/Orchard/ContentManagement/DefaultContentQuery.cs index 17c54c6f7..069e3cc9a 100644 --- a/src/Orchard/ContentManagement/DefaultContentQuery.cs +++ b/src/Orchard/ContentManagement/DefaultContentQuery.cs @@ -36,7 +36,7 @@ namespace Orchard.ContentManagement { return _session; } - IQueryOver BindQueryOverByPath(IQueryOver queryOver, string name) { + IQueryOver BindQueryOverByPath(IQueryOver queryOver, string name, JoinType joinType = JoinType.InnerJoin) { if (_joins.ContainsKey(typeof(TRecord).Name)) { return (IQueryOver)_joins[typeof(TRecord).Name]; } @@ -53,7 +53,7 @@ namespace Orchard.ContentManagement { Expression.Property(parameter, syntheticProperty), parameter); - var join = queryOver.JoinQueryOver(syntheticExpression); + var join = queryOver.JoinQueryOver(syntheticExpression, joinType); _joins[typeof(TRecord).Name] = join; return join; @@ -62,13 +62,13 @@ namespace Orchard.ContentManagement { IQueryOver BindTypeQueryOver() { // ([ContentItemVersionRecord] >join> [ContentItemRecord]) >join> [ContentType] - return BindQueryOverByPath(BindItemQueryOver(), "ContentType"); + return BindQueryOverByPath(BindItemQueryOver(), "ContentType", JoinType.LeftOuterJoin); } IQueryOver BindItemQueryOver() { // [ContentItemVersionRecord] >join> [ContentItemRecord] - return BindQueryOverByPath(BindItemVersionQueryOver(), "ContentItemRecord"); + return BindQueryOverByPath(BindItemVersionQueryOver(), "ContentItemRecord", JoinType.LeftOuterJoin); } IQueryOver BindItemVersionQueryOver() { @@ -103,7 +103,14 @@ namespace Orchard.ContentManagement { } private void Where(Expression> predicate) where TRecord : ContentPartRecord { - BindPartQueryOver().Where(predicate); + var processedCriteria = NHibernate.Impl.ExpressionProcessor.ProcessExpression(predicate); + BindPartQueryOver().Where(processedCriteria); + //BindPartQueryOver().WithSubquery.WhereSome(.Where(predicate); + } + + private void WhereAny(Expression>> selector, Expression> predicate) where TRecord : ContentPartRecord { + //var address = BindPartQueryOver() QueryOver.Of().Where(selector); + BindPartQueryOver().JoinQueryOver(selector).Where(predicate); } private void OrderBy(Expression> keySelector) where TRecord : ContentPartRecord { @@ -146,10 +153,12 @@ namespace Orchard.ContentManagement { queryOver.Take(count); } - return new ReadOnlyCollection(queryOver + var result = queryOver .List() .Select(x => ContentManager.Get(x.Id, VersionOptions.VersionRecord(x.Id))) - .ToList()); + .ToList(); + + return new ReadOnlyCollection(result); } int Count() { @@ -254,6 +263,11 @@ namespace Orchard.ContentManagement { return this; } + IContentQuery IContentQuery.WhereAny(Expression>> selector, Expression> predicate) { + _query.WhereAny(selector, predicate); + return this; + } + IContentQuery IContentQuery.OrderBy(Expression> keySelector) { _query.OrderBy(keySelector); return this; diff --git a/src/Orchard/ContentManagement/Diagram.cd b/src/Orchard/ContentManagement/Diagram.cd deleted file mode 100644 index 6fc3fb202..000000000 --- a/src/Orchard/ContentManagement/Diagram.cd +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - AAACAAAAAAACAAhAABAAAAAAAAAAQABAAAAQAAAEBAA= - Models\ContentItem.cs - - - - - - - - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAA= - Models\ContentPart.cs - - - - - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAA= - Models\ContentPart.cs - - - - - - AAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAA= - Models\Records\ContentItemRecord.cs - - - - - - - - - AAACAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA= - Models\Records\ContentTypeRecord.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAA= - Models\IContent.cs - - - - - - AAAAEAAAAAAAACBBAIAAAAAAAAEAAEgAAACAAAAAAAA= - Models\IContentManager.cs - - - - - - AAAAEAAAAAEAAABBAIAAAIAAACEAAAQAAACAAAAAAAg= - Models\Driver\IContentHandler.cs - - - - \ No newline at end of file diff --git a/src/Orchard/ContentManagement/IContentQuery.cs b/src/Orchard/ContentManagement/IContentQuery.cs index 946f47de7..6421f3c24 100644 --- a/src/Orchard/ContentManagement/IContentQuery.cs +++ b/src/Orchard/ContentManagement/IContentQuery.cs @@ -32,6 +32,7 @@ namespace Orchard.ContentManagement { new IContentQuery ForVersion(VersionOptions options); IContentQuery Where(Expression> predicate); + IContentQuery WhereAny(Expression>> selector, Expression> predicate); IContentQuery OrderBy(Expression> keySelector); IContentQuery OrderByDescending(Expression> keySelector); diff --git a/src/Orchard/ContentManagement/RestrictionExtensions.cs b/src/Orchard/ContentManagement/RestrictionExtensions.cs new file mode 100644 index 000000000..b47d2ef38 --- /dev/null +++ b/src/Orchard/ContentManagement/RestrictionExtensions.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using NHibernate.Criterion; +using NHibernate.Impl; +using Orchard.ContentManagement.Records; + +namespace Orchard.ContentManagement { + public static class RestrictionExtensions { + public static void RegisterExtensions() { + ExpressionProcessor.RegisterCustomMethodCall(() => "".StartsWith(""), RestrictionExtensions.ProcessStartsWith); + ExpressionProcessor.RegisterCustomMethodCall(() => "".EndsWith(""), RestrictionExtensions.ProcessEndsWith); + ExpressionProcessor.RegisterCustomMethodCall(() => "".Contains(""), RestrictionExtensions.ProcessContains); + } + + public static ICriterion ProcessStartsWith(MethodCallExpression methodCallExpression) { + ExpressionProcessor.ProjectionInfo projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Object); + string value = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[0]); + MatchMode matchMode = MatchMode.Start; + return projection.Create(s => Restrictions.InsensitiveLike(s, value, matchMode), p => Restrictions.InsensitiveLike(p, value, matchMode)); + } + + + public static ICriterion ProcessEndsWith(MethodCallExpression methodCallExpression) { + ExpressionProcessor.ProjectionInfo projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Object); + string value = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[0]); + MatchMode matchMode = MatchMode.End; + return projection.Create(s => Restrictions.InsensitiveLike(s, value, matchMode), p => Restrictions.InsensitiveLike(p, value, matchMode)); + } + + + public static ICriterion ProcessContains(MethodCallExpression methodCallExpression) { + ExpressionProcessor.ProjectionInfo projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Object); + string value = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[0]); + MatchMode matchMode = MatchMode.Anywhere; + return projection.Create(s => Restrictions.InsensitiveLike(s, value, matchMode), p => Restrictions.InsensitiveLike(p, value, matchMode)); + } + } +} diff --git a/src/Orchard/Data/Conventions/AggregateAttribute.cs b/src/Orchard/Data/Conventions/AggregateAttribute.cs index d15354a11..b83d5fe70 100644 --- a/src/Orchard/Data/Conventions/AggregateAttribute.cs +++ b/src/Orchard/Data/Conventions/AggregateAttribute.cs @@ -23,7 +23,7 @@ namespace Orchard.Data.Conventions { } public void Apply(IOneToManyCollectionInstance instance) { - instance.Fetch.Join(); + instance.Fetch.Select(); instance.Cache.ReadWrite(); } diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 7b76f8631..963bb3b27 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -171,6 +171,7 @@ + @@ -906,7 +907,6 @@ -