diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index ba60925b11..eb9cc6903e 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using System.Threading; using AutoMapper; using LightInject; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; @@ -40,19 +41,19 @@ namespace Umbraco.Core { /// - /// A bootstrapper for the Umbraco application which initializes all objects for the Core of the application + /// A bootstrapper for the Umbraco application which initializes all objects for the Core of the application /// /// /// This does not provide any startup functionality relating to web objects /// public class CoreBootManager : IBootManager { - + private ServiceContainer _appStartupEvtContainer; protected ProfilingLogger ProfilingLogger { get; private set; } private DisposableTimer _timer; protected PluginManager PluginManager { get; private set; } - + private bool _isInitialized = false; private bool _isStarted = false; @@ -76,7 +77,7 @@ namespace Umbraco.Core public CoreBootManager(UmbracoApplicationBase umbracoApplication) { if (umbracoApplication == null) throw new ArgumentNullException("umbracoApplication"); - _umbracoApplication = umbracoApplication; + _umbracoApplication = umbracoApplication; } internal CoreBootManager(UmbracoApplicationBase umbracoApplication, ProfilingLogger logger) @@ -91,7 +92,7 @@ namespace Umbraco.Core { if (_isInitialized) throw new InvalidOperationException("The boot manager has already been initialized"); - + //Create logger/profiler, and their resolvers, these are special resolvers that can be resolved before frozen so we can start logging LoggerResolver.Current = new LoggerResolver(_umbracoApplication.Logger) { CanResolveBeforeFrozen = true }; var profiler = CreateProfiler(); @@ -99,7 +100,7 @@ namespace Umbraco.Core ProfilingLogger = new ProfilingLogger(_umbracoApplication.Logger, profiler); ProfilingLogger = ProfilingLogger?? new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler); - + ApplicationCache = CreateApplicationCache(); _timer = ProfilingLogger.TraceDuration( @@ -112,26 +113,24 @@ namespace Umbraco.Core //TODO: this is currently a singleton but it would be better if it weren't. Unfortunately the only way to get // rid of this singleton would be to put it into IoC and then use the ServiceLocator pattern. PluginManager.Current = PluginManager = new PluginManager(ServiceProvider, ApplicationCache.RuntimeCache, ProfilingLogger, true); - + //build up core IoC servoces ConfigureCoreServices(Container); //set the singleton resolved from the core container ApplicationContext.Current = ApplicationContext = Container.GetInstance(); - //TODO: Remove these for v8! + //TODO: Remove these for v8! LegacyPropertyEditorIdToAliasConverter.CreateMappingsForCoreEditors(); LegacyParameterEditorAliasConverter.CreateMappingsForCoreEditors(); - //TODO: Make this as part of the db ctor! - Database.Mapper = new PetaPocoMapper(); - + //Create a 'child'container which is a copy of all of the current registrations and begin a sub scope for it // this child container will be used to manage the application event handler instances and the scope will be // completed at the end of the boot process to allow garbage collection _appStartupEvtContainer = Container.CreateChildContainer(); _appStartupEvtContainer.BeginScope(); _appStartupEvtContainer.RegisterCollection(PluginManager.ResolveApplicationStartupHandlers()); - + //build up standard IoC services ConfigureApplicationServices(Container); @@ -143,11 +142,11 @@ namespace Umbraco.Core { try { - using (ProfilingLogger.DebugDuration(string.Format("Executing {0} in ApplicationInitialized", x.GetType()))) - { - x.OnApplicationInitialized(UmbracoApplication, ApplicationContext); + using (ProfilingLogger.DebugDuration(string.Format("Executing {0} in ApplicationInitialized", x.GetType()))) + { + x.OnApplicationInitialized(UmbracoApplication, ApplicationContext); + } } - } catch (Exception ex) { ProfilingLogger.Logger.Error("An error occurred running OnApplicationInitialized for handler " + x.GetType(), ex); @@ -166,12 +165,12 @@ namespace Umbraco.Core internal virtual void ConfigureCoreServices(ServiceContainer container) { container.Register(factory => container); - + //Logging container.RegisterSingleton(factory => _umbracoApplication.Logger); container.RegisterSingleton(factory => ProfilingLogger.Profiler); container.RegisterSingleton(factory => ProfilingLogger); - + //Config container.RegisterFrom(); @@ -193,7 +192,7 @@ namespace Umbraco.Core container.RegisterSingleton(); container.Register(factory => FileSystemProviderManager.Current.GetFileSystemProvider()); - + } /// @@ -202,9 +201,9 @@ namespace Umbraco.Core /// internal virtual void ConfigureApplicationServices(ServiceContainer container) { - + } - + /// /// Creates the ApplicationCache based on a new instance of System.Web.Caching.Cache /// @@ -260,7 +259,7 @@ namespace Umbraco.Core } /// - /// Fires after initialization and calls the callback to allow for customizations to occur & + /// Fires after initialization and calls the callback to allow for customizations to occur & /// Ensure that the OnApplicationStarting methods of the IApplicationEvents are called /// /// @@ -275,11 +274,11 @@ namespace Umbraco.Core { try { - using (ProfilingLogger.DebugDuration(string.Format("Executing {0} in ApplicationStarting", x.GetType()))) - { - x.OnApplicationStarting(UmbracoApplication, ApplicationContext); + using (ProfilingLogger.DebugDuration(string.Format("Executing {0} in ApplicationStarting", x.GetType()))) + { + x.OnApplicationStarting(UmbracoApplication, ApplicationContext); + } } - } catch (Exception ex) { ProfilingLogger.Logger.Error("An error occurred running OnApplicationStarting for handler " + x.GetType(), ex); @@ -306,7 +305,7 @@ namespace Umbraco.Core { if (_isComplete) throw new InvalidOperationException("The boot manager has already been completed"); - + FreezeResolution(); //Here we need to make sure the db can be connected to @@ -318,16 +317,16 @@ namespace Umbraco.Core ((UserService) ApplicationContext.Services.UserService).IsUpgrading = true; - + //call OnApplicationStarting of each application events handler Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x => { try { - using (ProfilingLogger.DebugDuration(string.Format("Executing {0} in ApplicationStarted", x.GetType()))) - { - x.OnApplicationStarted(UmbracoApplication, ApplicationContext); - } + using (ProfilingLogger.DebugDuration(string.Format("Executing {0} in ApplicationStarted", x.GetType()))) + { + x.OnApplicationStarted(UmbracoApplication, ApplicationContext); + } } catch (Exception ex) { @@ -445,7 +444,7 @@ namespace Umbraco.Core Container, ProfilingLogger.Logger, () => PluginManager.ResolveAssignedMapperTypes()); - + //RepositoryResolver.Current = new RepositoryResolver( // new RepositoryFactory(ApplicationCache)); @@ -469,7 +468,7 @@ namespace Umbraco.Core PluginManager.ResolveTypes()); // use the new DefaultShortStringHelper - ShortStringHelperResolver.Current = new ShortStringHelperResolver(Container, + ShortStringHelperResolver.Current = new ShortStringHelperResolver(Container, factory => new DefaultShortStringHelper(factory.GetInstance()).WithDefaultConfig()); UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver( diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 1f00fb0df9..8f94c993ba 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Web; using System.Web.Configuration; using System.Xml.Linq; +using NPoco; using Semver; using Umbraco.Core.Configuration; using Umbraco.Core.IO; @@ -789,5 +790,10 @@ namespace Umbraco.Core return true; } + + public Sql Sql() + { + return NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, Database)); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/DependencyInjection/RepositoryCompositionRoot.cs b/src/Umbraco.Core/DependencyInjection/RepositoryCompositionRoot.cs index 2d8e0109ec..f6ff4f1914 100644 --- a/src/Umbraco.Core/DependencyInjection/RepositoryCompositionRoot.cs +++ b/src/Umbraco.Core/DependencyInjection/RepositoryCompositionRoot.cs @@ -23,16 +23,20 @@ namespace Umbraco.Core.DependencyInjection { container.RegisterSingleton(factory => new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, factory.GetInstance())); container.RegisterSingleton(factory => GetDbContext(factory)); + container.RegisterSingleton(factory => SqlSyntaxProviders.CreateDefault(factory.GetInstance())); + container.Register(factory => factory.GetInstance().SqlSyntax); + container.RegisterSingleton(); - container.RegisterSingleton(factory => new PetaPocoUnitOfWorkProvider(factory.GetInstance())); + container.RegisterSingleton(factory => new NPocoUnitOfWorkProvider(factory.GetInstance())); + container.RegisterSingleton(factory => new MappingResolver( factory.GetInstance(), factory.GetInstance(), () => factory.GetInstance().ResolveAssignedMapperTypes())); container.Register(); - container.Register(factory => factory.GetInstance().SqlSyntax); container.RegisterSingleton(factory => CacheHelper.CreateDisabledCacheHelper(), "DisabledCache"); + container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.Scripts), "ScriptFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.MvcViews + "/Partials/"), "PartialViewFileSystem"); container.RegisterSingleton(factory => new PhysicalFileSystem(SystemDirectories.MvcViews + "/MacroPartials/"), "PartialViewMacroFileSystem"); diff --git a/src/Umbraco.Core/EnumerableExtensions.cs b/src/Umbraco.Core/EnumerableExtensions.cs index 58d4d453b7..156831670a 100644 --- a/src/Umbraco.Core/EnumerableExtensions.cs +++ b/src/Umbraco.Core/EnumerableExtensions.cs @@ -20,9 +20,33 @@ namespace Umbraco.Core if (groupSize <= 0) throw new ArgumentException("Must be greater than zero.", "groupSize"); - return source - .Select((x, i) => Tuple.Create(i / groupSize, x)) - .GroupBy(t => t.Item1, t => t.Item2); + + // following code derived from MoreLinq and does not allocate bazillions of tuples + + T[] temp = null; + var count = 0; + + foreach (var item in source) + { + if (temp == null) temp = new T[groupSize]; + temp[count++] = item; + if (count != groupSize) continue; + yield return temp/*.Select(x => x)*/; + temp = null; + count = 0; + } + + if (temp != null && count > 0) + yield return temp.Take(count); + } + + public static IEnumerable SelectByGroups(this IEnumerable source, Func, IEnumerable> selector, int groupSize) + { + // don't want to use a SelectMany(x => x) here - isn't this better? + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var resultGroup in source.InGroupsOf(groupSize).Select(selector)) + foreach (var result in resultGroup) + yield return result; } /// The distinct by. @@ -287,7 +311,7 @@ namespace Umbraco.Core /// /// The logic for this is taken from: /// http://stackoverflow.com/questions/4576723/test-whether-two-ienumerablet-have-the-same-values-with-the-same-frequencies - /// + /// /// There's a few answers, this one seems the best for it's simplicity and based on the comment of Eamon /// public static bool UnsortedSequenceEqual(this IEnumerable source, IEnumerable other) @@ -301,5 +325,27 @@ namespace Umbraco.Core && list1Groups.All(g => g.Count() == list2Groups[g.Key].Count()); } + /// + /// Transforms an enumerable. + /// + /// + /// + /// + /// + public static IEnumerable Transform(this IEnumerable source, Func, IEnumerable> transform) + { + return transform(source); + } + + /// + /// Gets a null IEnumerable as an empty IEnumerable. + /// + /// + /// + /// + public static IEnumerable EmptyNull(this IEnumerable items) + { + return items ?? Enumerable.Empty(); + } } } diff --git a/src/Umbraco.Core/ListExtensions.cs b/src/Umbraco.Core/ListExtensions.cs new file mode 100644 index 0000000000..e639cbd5c7 --- /dev/null +++ b/src/Umbraco.Core/ListExtensions.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; + +namespace Umbraco.Core +{ + /// + /// Provides extensions to the List type. + /// + internal static class ListExtensions + { + // based upon the original Zip method + public static IEnumerable Zip(this IEnumerable e1, IEnumerable e2, IEnumerable e3, + Func resultSelector) + { + if (e1 == null) throw new ArgumentNullException("e1"); + if (e2 == null) throw new ArgumentNullException("e2"); + if (e3 == null) throw new ArgumentNullException("e3"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + return ZipIterator(e1, e2, e3, resultSelector); + } + + private static IEnumerable ZipIterator(IEnumerable ie1, IEnumerable ie2, IEnumerable ie3, + Func resultSelector) + { + var e1 = ie1.GetEnumerator(); + try + { + var e2 = ie2.GetEnumerator(); + var e3 = ie3.GetEnumerator(); + try + { + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current); + } + finally + { + if (e2 != null) + e2.Dispose(); + if (e3 != null) + e3.Dispose(); + } + } + finally + { + if (e1 != null) + e1.Dispose(); + } + } + } +} diff --git a/src/Umbraco.Core/Models/Rdbms/AccessDto.cs b/src/Umbraco.Core/Models/Rdbms/AccessDto.cs index 37b1dbddd8..b9a512e027 100644 --- a/src/Umbraco.Core/Models/Rdbms/AccessDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/AccessDto.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Security.AccessControl; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -9,7 +10,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Models.Rdbms { [TableName("umbracoAccess")] - [PrimaryKey("id", autoIncrement = false)] + [PrimaryKey("id", AutoIncrement = false)] [ExplicitColumns] internal class AccessDto { @@ -39,6 +40,7 @@ namespace Umbraco.Core.Models.Rdbms public DateTime UpdateDate { get; set; } [ResultColumn] + [Reference(ReferenceType.Many, ReferenceMemberName = "AccessId")] public List Rules { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/AccessRuleDto.cs b/src/Umbraco.Core/Models/Rdbms/AccessRuleDto.cs index 78e3444e56..07f9d4f175 100644 --- a/src/Umbraco.Core/Models/Rdbms/AccessRuleDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/AccessRuleDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -6,7 +7,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Models.Rdbms { [TableName("umbracoAccessRule")] - [PrimaryKey("id", autoIncrement = false)] + [PrimaryKey("id", AutoIncrement = false)] [ExplicitColumns] internal class AccessRuleDto { diff --git a/src/Umbraco.Core/Models/Rdbms/CacheInstructionDto.cs b/src/Umbraco.Core/Models/Rdbms/CacheInstructionDto.cs index c24004b7dc..182b8c67b3 100644 --- a/src/Umbraco.Core/Models/Rdbms/CacheInstructionDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/CacheInstructionDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; diff --git a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs index eb9a66a7f2..8cef85b998 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms @@ -22,6 +23,7 @@ namespace Umbraco.Core.Models.Rdbms public int ContentTypeId { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "NodeId")] public NodeDto NodeDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/ContentType2ContentTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentType2ContentTypeDto.cs index 89773ef1ee..a4e5b6b71b 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentType2ContentTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentType2ContentTypeDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/ContentTypeAllowedContentTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentTypeAllowedContentTypeDto.cs index 91904437f0..9c101ffda4 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentTypeAllowedContentTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentTypeAllowedContentTypeDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsContentTypeAllowedContentType")] - [PrimaryKey("Id", autoIncrement = false)] + [PrimaryKey("Id", AutoIncrement = false)] [ExplicitColumns] internal class ContentTypeAllowedContentTypeDto { @@ -22,6 +23,7 @@ namespace Umbraco.Core.Models.Rdbms public int SortOrder { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne)] public ContentTypeDto ContentTypeDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs index 8d163abf44..483587cffc 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/ContentTypeTemplateDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentTypeTemplateDto.cs index 88ef02ea90..5ebd97319a 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentTypeTemplateDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentTypeTemplateDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsDocumentType")] - [PrimaryKey("contentTypeNodeId", autoIncrement = false)] + [PrimaryKey("contentTypeNodeId", AutoIncrement = false)] [ExplicitColumns] internal class ContentTypeTemplateDto { @@ -23,6 +24,7 @@ namespace Umbraco.Core.Models.Rdbms public bool IsDefault { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne)] public ContentTypeDto ContentTypeDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs index 3bd85cccf6..715f9908e4 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentVersionDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -28,6 +29,7 @@ namespace Umbraco.Core.Models.Rdbms public DateTime VersionDate { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "NodeId", ReferenceMemberName = "NodeId")] public ContentDto ContentDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/ContentXmlDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentXmlDto.cs index ca48a4074c..c72af43901 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentXmlDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentXmlDto.cs @@ -1,11 +1,12 @@ using System.Data; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsContentXml")] - [PrimaryKey("nodeId", autoIncrement = false)] + [PrimaryKey("nodeId", AutoIncrement = false)] [ExplicitColumns] internal class ContentXmlDto { diff --git a/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs index b0e63b0726..148116d70e 100644 --- a/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; @@ -26,6 +27,7 @@ namespace Umbraco.Core.Models.Rdbms public string DbType { get; set; }//NOTE Is set to [varchar] (50) in Sql Server script [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "DataTypeId")] public NodeDto NodeDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs b/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs index 652e63df0b..69c9e17dbd 100644 --- a/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs b/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs index 712d1937a9..262c9f3c5b 100644 --- a/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; @@ -28,6 +29,7 @@ namespace Umbraco.Core.Models.Rdbms public string Key { get; set; } [ResultColumn] + [Reference(ReferenceType.Many, ColumnName = "UniqueId", ReferenceMemberName = "UniqueId")] public List LanguageTextDtos { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs index 88e04087c9..2ad44fbe58 100644 --- a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -6,7 +7,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsDocument")] - [PrimaryKey("versionId", autoIncrement = false)] + [PrimaryKey("versionId", AutoIncrement = false)] [ExplicitColumns] internal class DocumentDto { @@ -46,16 +47,18 @@ namespace Umbraco.Core.Models.Rdbms [NullSetting(NullSetting = NullSettings.Null)] [ForeignKey(typeof(TemplateDto), Column = "nodeId")] public int? TemplateId { get; set; } - + [Column("newest")] [Constraint(Default = "0")] [Index(IndexTypes.NonClustered, Name = "IX_cmsDocument_newest")] public bool Newest { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ReferenceMemberName = "NodeId")] public ContentVersionDto ContentVersionDto { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ReferenceMemberName = "NodeId")] public DocumentPublishedReadOnlyDto DocumentPublishedReadOnlyDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/DocumentPublishedReadOnlyDto.cs b/src/Umbraco.Core/Models/Rdbms/DocumentPublishedReadOnlyDto.cs index 4a7e359d91..788e321877 100644 --- a/src/Umbraco.Core/Models/Rdbms/DocumentPublishedReadOnlyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DocumentPublishedReadOnlyDto.cs @@ -1,10 +1,11 @@ using System; +using NPoco; using Umbraco.Core.Persistence; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsDocument")] - [PrimaryKey("versionId", autoIncrement = false)] + [PrimaryKey("versionId", AutoIncrement = false)] [ExplicitColumns] internal class DocumentPublishedReadOnlyDto { diff --git a/src/Umbraco.Core/Models/Rdbms/DomainDto.cs b/src/Umbraco.Core/Models/Rdbms/DomainDto.cs index e43c1bdeae..e78c442184 100644 --- a/src/Umbraco.Core/Models/Rdbms/DomainDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DomainDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/ExternalLoginDto.cs b/src/Umbraco.Core/Models/Rdbms/ExternalLoginDto.cs index 803c25fdfc..1f335ec6ce 100644 --- a/src/Umbraco.Core/Models/Rdbms/ExternalLoginDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ExternalLoginDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs b/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs index a634dca0a4..2e6a4fdae2 100644 --- a/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs b/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs index 87329fbd4c..e14ffdb8a8 100644 --- a/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; diff --git a/src/Umbraco.Core/Models/Rdbms/LogDto.cs b/src/Umbraco.Core/Models/Rdbms/LogDto.cs index be67b5873a..277720d29b 100644 --- a/src/Umbraco.Core/Models/Rdbms/LogDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LogDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/MacroDto.cs b/src/Umbraco.Core/Models/Rdbms/MacroDto.cs index 15422f7a08..1affe3a04e 100644 --- a/src/Umbraco.Core/Models/Rdbms/MacroDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MacroDto.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; @@ -59,6 +60,7 @@ namespace Umbraco.Core.Models.Rdbms public string MacroFilePath { get; set; } [ResultColumn] + [Reference(ReferenceType.Many, ReferenceMemberName = "Macro")] public List MacroPropertyDtos { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs b/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs index e2efddc829..6d10315ec1 100644 --- a/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms @@ -11,8 +12,8 @@ namespace Umbraco.Core.Models.Rdbms [Column("id")] [PrimaryKeyColumn] public int Id { get; set; } - - [Column("editorAlias")] + + [Column("editorAlias")] public string EditorAlias { get; set; } [Column("macro")] diff --git a/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs b/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs index 888f331364..653f4d3c87 100644 --- a/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsMember2MemberGroup")] - [PrimaryKey("Member", autoIncrement = false)] + [PrimaryKey("Member", AutoIncrement = false)] [ExplicitColumns] internal class Member2MemberGroupDto { diff --git a/src/Umbraco.Core/Models/Rdbms/MemberDto.cs b/src/Umbraco.Core/Models/Rdbms/MemberDto.cs index e5f7b3f17c..35d5db1042 100644 --- a/src/Umbraco.Core/Models/Rdbms/MemberDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MemberDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsMember")] - [PrimaryKey("nodeId", autoIncrement = false)] + [PrimaryKey("nodeId", AutoIncrement = false)] [ExplicitColumns] internal class MemberDto { @@ -30,6 +31,7 @@ namespace Umbraco.Core.Models.Rdbms public string Password { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ReferenceMemberName = "NodeId")] public ContentVersionDto ContentVersionDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/MemberTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/MemberTypeDto.cs index c9432652af..7d637e74c6 100644 --- a/src/Umbraco.Core/Models/Rdbms/MemberTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MemberTypeDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/MemberTypeReadOnlyDto.cs b/src/Umbraco.Core/Models/Rdbms/MemberTypeReadOnlyDto.cs index 4833cb33f0..4997134ccf 100644 --- a/src/Umbraco.Core/Models/Rdbms/MemberTypeReadOnlyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MemberTypeReadOnlyDto.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence; namespace Umbraco.Core.Models.Rdbms @@ -68,11 +69,13 @@ namespace Umbraco.Core.Models.Rdbms /* PropertyTypes */ //TODO Add PropertyTypeDto (+MemberTypeDto and DataTypeDto as one) ReadOnly list [ResultColumn] + [Reference(ReferenceType.Many, ReferenceMemberName = "ContentTypeId")] public List PropertyTypes { get; set; } /* PropertyTypeGroups */ //TODO Add PropertyTypeGroupDto ReadOnly list [ResultColumn] + [Reference(ReferenceType.Many, ReferenceMemberName = "ContentTypeNodeId")] public List PropertyTypeGroups { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/MigrationDto.cs b/src/Umbraco.Core/Models/Rdbms/MigrationDto.cs index 1a76895e90..2cff4f1c5a 100644 --- a/src/Umbraco.Core/Models/Rdbms/MigrationDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MigrationDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs index c5fac092df..b0860ea34a 100644 --- a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs index d981855f24..e3adb3c915 100644 --- a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs @@ -1,11 +1,12 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsPreviewXml")] - [PrimaryKey("nodeId", autoIncrement = false)] + [PrimaryKey("nodeId", AutoIncrement = false)] [ExplicitColumns] internal class PreviewXmlDto { diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs index 63e3104d12..8840cb771d 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; @@ -52,6 +53,7 @@ namespace Umbraco.Core.Models.Rdbms public string Text { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "PropertyTypeId")] public PropertyTypeDto PropertyTypeDto { get; set; } [Ignore] @@ -68,12 +70,12 @@ namespace Umbraco.Core.Models.Rdbms { return Decimal.Value; } - + if (Date.HasValue) { return Date.Value; } - + if (string.IsNullOrEmpty(VarChar) == false) { return VarChar; diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs index 2be4b24157..cc74268c8a 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -52,6 +53,7 @@ namespace Umbraco.Core.Models.Rdbms public string Description { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "DataTypeId")] public DataTypeDto DataTypeDto { get; set; } [Column("UniqueID")] diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupDto.cs index 68de420a97..c560780dcf 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupDto.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -7,7 +8,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsPropertyTypeGroup")] - [PrimaryKey("id", autoIncrement = true)] + [PrimaryKey("id", AutoIncrement = true)] [ExplicitColumns] internal class PropertyTypeGroupDto { @@ -26,6 +27,7 @@ namespace Umbraco.Core.Models.Rdbms public int SortOrder { get; set; } [ResultColumn] + [Reference(ReferenceType.Many, ReferenceMemberName = "PropertyTypeGroupId")] public List PropertyTypeDtos { get; set; } [Column("uniqueID")] diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupReadOnlyDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupReadOnlyDto.cs index beebef9eeb..ac38b7b642 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupReadOnlyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeGroupReadOnlyDto.cs @@ -1,9 +1,10 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsPropertyTypeGroup")] - [PrimaryKey("id", autoIncrement = true)] + [PrimaryKey("id", AutoIncrement = true)] [ExplicitColumns] internal class PropertyTypeGroupReadOnlyDto { diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs index 2f448860b0..bba1546a93 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/RelationDto.cs b/src/Umbraco.Core/Models/Rdbms/RelationDto.cs index 368904a5cb..44f0199b17 100644 --- a/src/Umbraco.Core/Models/Rdbms/RelationDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/RelationDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs index 8a6eb5c02a..c927fcf455 100644 --- a/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; diff --git a/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs b/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs index 2a3751c083..55b6145a3a 100644 --- a/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs b/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs index 3580fcf918..91132d3a7e 100644 --- a/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsStylesheet")] - [PrimaryKey("nodeId", autoIncrement = false)] + [PrimaryKey("nodeId", AutoIncrement = false)] [ExplicitColumns] internal class StylesheetDto { diff --git a/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs b/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs index cfe3148764..8e249a8da2 100644 --- a/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsStylesheetProperty")] - [PrimaryKey("nodeId", autoIncrement = false)] + [PrimaryKey("nodeId", AutoIncrement = false)] [ExplicitColumns] internal class StylesheetPropertyDto { diff --git a/src/Umbraco.Core/Models/Rdbms/TagDto.cs b/src/Umbraco.Core/Models/Rdbms/TagDto.cs index d612f656bb..cb37f2c723 100644 --- a/src/Umbraco.Core/Models/Rdbms/TagDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TagDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs b/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs index 4fc936713a..d605530839 100644 --- a/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("cmsTagRelationship")] - [PrimaryKey("nodeId", autoIncrement = false)] + [PrimaryKey("nodeId", AutoIncrement = false)] [ExplicitColumns] internal class TagRelationshipDto { diff --git a/src/Umbraco.Core/Models/Rdbms/TaskDto.cs b/src/Umbraco.Core/Models/Rdbms/TaskDto.cs index e27f7c0a93..7ce24aa21e 100644 --- a/src/Umbraco.Core/Models/Rdbms/TaskDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TaskDto.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -44,6 +45,7 @@ namespace Umbraco.Core.Models.Rdbms public string Comment { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "TaskTypeId")] public TaskTypeDto TaskTypeDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/TaskTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/TaskTypeDto.cs index 2ff61953ce..113908a47c 100644 --- a/src/Umbraco.Core/Models/Rdbms/TaskTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TaskTypeDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs b/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs index 8e2fe0b9f5..b0bdb17bba 100644 --- a/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms @@ -27,6 +28,7 @@ namespace Umbraco.Core.Models.Rdbms public string Design { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "NodeId")] public NodeDto NodeDto { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/UmbracoDeployChecksumDto.cs b/src/Umbraco.Core/Models/Rdbms/UmbracoDeployChecksumDto.cs index 06d904ee88..a012d85563 100644 --- a/src/Umbraco.Core/Models/Rdbms/UmbracoDeployChecksumDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UmbracoDeployChecksumDto.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Models/Rdbms/UmbracoDeployDependencyDto.cs b/src/Umbraco.Core/Models/Rdbms/UmbracoDeployDependencyDto.cs index 765a32c929..6ec19a513d 100644 --- a/src/Umbraco.Core/Models/Rdbms/UmbracoDeployDependencyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UmbracoDeployDependencyDto.cs @@ -1,3 +1,4 @@ +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; diff --git a/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs b/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs index eafc6be230..5c80c6e117 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("umbracoUser2app")] - [PrimaryKey("user", autoIncrement = false)] + [PrimaryKey("user", AutoIncrement = false)] [ExplicitColumns] internal class User2AppDto { diff --git a/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs b/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs index 298ad920d9..e45c0a6ad8 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("umbracoUser2NodeNotify")] - [PrimaryKey("userId", autoIncrement = false)] + [PrimaryKey("userId", AutoIncrement = false)] [ExplicitColumns] internal class User2NodeNotifyDto { diff --git a/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs b/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs index 1e6662735f..117f88fe66 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs @@ -1,10 +1,11 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("umbracoUser2NodePermission")] - [PrimaryKey("userId", autoIncrement = false)] + [PrimaryKey("userId", AutoIncrement = false)] [ExplicitColumns] internal class User2NodePermissionDto { diff --git a/src/Umbraco.Core/Models/Rdbms/UserDto.cs b/src/Umbraco.Core/Models/Rdbms/UserDto.cs index 05a93c86bf..350f4b4a79 100644 --- a/src/Umbraco.Core/Models/Rdbms/UserDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UserDto.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { [TableName("umbracoUser")] - [PrimaryKey("id", autoIncrement = true)] + [PrimaryKey("id", AutoIncrement = true)] [ExplicitColumns] internal class UserDto { @@ -75,6 +76,7 @@ namespace Umbraco.Core.Models.Rdbms public DateTime? LastLoginDate { get; set; } [ResultColumn] + [Reference(ReferenceType.Many, ReferenceMemberName = "UserId")] public List User2AppDtos { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs index d3268a14fb..8b6d286073 100644 --- a/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence; +using NPoco; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs index eefacbcbc1..7936ac0fa8 100644 --- a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs @@ -2,6 +2,7 @@ using System.Data; using System.Linq; using System.Reflection; +using NPoco; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.SqlSyntax; @@ -11,7 +12,7 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions { public static TableDefinition GetTableDefinition(Type modelType, ISqlSyntaxProvider sqlSyntax) { - //Looks for PetaPoco's TableNameAtribute for the name of the table + //Looks for NPoco's TableNameAtribute for the name of the table //If no attribute is set we use the name of the Type as the default convention var tableNameAttribute = modelType.FirstAttribute(); string tableName = tableNameAttribute == null ? modelType.Name : tableNameAttribute.Value; @@ -108,7 +109,7 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions var constraintAttribute = propertyInfo.FirstAttribute(); if (constraintAttribute != null) { - //Special case for MySQL as it can't have multiple default DateTime values, which + //Special case for MySQL as it can't have multiple default DateTime values, which //is what the umbracoServer table definition is trying to create if (sqlSyntax is MySqlSyntaxProvider && definition.TableName == "umbracoServer" && definition.TableName.ToLowerInvariant() == "lastNotifiedDate".ToLowerInvariant()) diff --git a/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs b/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs index 418e5b953d..ad6af9dd0a 100644 --- a/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs +++ b/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; diff --git a/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs b/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs index 3e6d245416..d6ad4f1f3c 100644 --- a/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs +++ b/src/Umbraco.Core/Persistence/DatabasenodeLockExtensions.cs @@ -12,7 +12,7 @@ namespace Umbraco.Core.Persistence { if (database == null) throw new ArgumentNullException("database"); - if (database.CurrentTransactionIsolationLevel < IsolationLevel.RepeatableRead) + if (database.GetCurrentTransactionIsolationLevel() < IsolationLevel.RepeatableRead) throw new InvalidOperationException("A transaction with minimum RepeatableRead isolation level is required."); } diff --git a/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs b/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs index 72c4275541..f5c2ab9c4f 100644 --- a/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs +++ b/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs @@ -1,7 +1,12 @@ using System; +using System.Configuration; using System.Web; +using NPoco; +using NPoco.FluentMappings; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.FaultHandling; +using Umbraco.Core.Persistence.Mappers; namespace Umbraco.Core.Persistence { @@ -17,82 +22,100 @@ namespace Umbraco.Core.Persistence { private readonly string _connectionStringName; private readonly ILogger _logger; - public string ConnectionString { get; private set; } + private readonly DatabaseFactory _databaseFactory; + private readonly RetryPolicy _connectionRetryPolicy; + private readonly RetryPolicy _commandRetryPolicy; + + public string ConnectionString { get; private set; } public string ProviderName { get; private set; } - + //very important to have ThreadStatic: // see: http://issues.umbraco.org/issue/U4-2172 [ThreadStatic] - private static volatile UmbracoDatabase _nonHttpInstance; - - private static readonly object Locker = new object(); - + private static Lazy _nonHttpInstance; + /// /// Constructor accepting custom connection string /// /// Name of the connection string in web.config /// public DefaultDatabaseFactory(string connectionStringName, ILogger logger) + : this(logger) { - if (logger == null) throw new ArgumentNullException("logger"); Mandate.ParameterNotNullOrEmpty(connectionStringName, "connectionStringName"); _connectionStringName = connectionStringName; - _logger = logger; - } - /// - /// Constructor accepting custom connectino string and provider name - /// - /// Connection String to use with Database - /// Database Provider for the Connection String - /// - public DefaultDatabaseFactory(string connectionString, string providerName, ILogger logger) + if (ConfigurationManager.ConnectionStrings[connectionStringName] == null) + throw new InvalidOperationException("Can't find a connection string with the name '" + connectionStringName + "'"); + var connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; + + _connectionRetryPolicy = RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString); + _commandRetryPolicy = RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(connectionString); + } + + /// + /// Constructor accepting custom connectino string and provider name + /// + /// Connection String to use with Database + /// Database Provider for the Connection String + /// + public DefaultDatabaseFactory(string connectionString, string providerName, ILogger logger) + : this(logger) { - if (logger == null) throw new ArgumentNullException("logger"); Mandate.ParameterNotNullOrEmpty(connectionString, "connectionString"); Mandate.ParameterNotNullOrEmpty(providerName, "providerName"); ConnectionString = connectionString; ProviderName = providerName; + + _connectionRetryPolicy = RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString); + _commandRetryPolicy = RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(connectionString); + } + + private DefaultDatabaseFactory(ILogger logger) + { + if (logger == null) throw new ArgumentNullException("logger"); _logger = logger; - } + + // ensure we have only 1 set of mappers, and 1 PocoDataFactory, for all database + // so that everything NPoco is properly cached for the lifetime of the application + var mappers = new MapperCollection { new PocoMapper() }; + var pocoDataFactory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, mappers).Init()); + var config = new FluentConfig(xmappers => pocoDataFactory); + + // create the database factory + _databaseFactory = DatabaseFactory.Config(x => x + .UsingDatabase(CreateDatabaseInstance) // creating UmbracoDatabase instances + .WithFluentConfig(config)); // with proper configuration + + _nonHttpInstance = new Lazy(() => (UmbracoDatabase)_databaseFactory.GetDatabase()); + } + + private UmbracoDatabase CreateDatabaseInstance() + { + return string.IsNullOrEmpty(ConnectionString) == false && string.IsNullOrEmpty(ProviderName) == false + ? new UmbracoDatabase(ConnectionString, ProviderName, _logger, _connectionRetryPolicy, _commandRetryPolicy) + : new UmbracoDatabase(_connectionStringName, _logger, _connectionRetryPolicy, _commandRetryPolicy); + } public UmbracoDatabase CreateDatabase() { - //no http context, create the singleton global object + // no http context, create the singleton global object if (HttpContext.Current == null) { - if (_nonHttpInstance == null) - { - lock (Locker) - { - //double check - if (_nonHttpInstance == null) - { - _nonHttpInstance = string.IsNullOrEmpty(ConnectionString) == false && string.IsNullOrEmpty(ProviderName) == false - ? new UmbracoDatabase(ConnectionString, ProviderName, _logger) - : new UmbracoDatabase(_connectionStringName, _logger); - } - } - } - return _nonHttpInstance; + return _nonHttpInstance.Value; } - //we have an http context, so only create one per request - if (HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)) == false) - { - HttpContext.Current.Items.Add(typeof (DefaultDatabaseFactory), - string.IsNullOrEmpty(ConnectionString) == false && string.IsNullOrEmpty(ProviderName) == false - ? new UmbracoDatabase(ConnectionString, ProviderName, _logger) - : new UmbracoDatabase(_connectionStringName, _logger)); - } - return (UmbracoDatabase)HttpContext.Current.Items[typeof(DefaultDatabaseFactory)]; + // we have an http context, so only create one per request + var db = HttpContext.Current.Items[typeof (DefaultDatabaseFactory)] as UmbracoDatabase; + if (db == null) HttpContext.Current.Items[typeof (DefaultDatabaseFactory)] = db = (UmbracoDatabase) _databaseFactory.GetDatabase(); + return db; } protected override void DisposeResources() { - if (HttpContext.Current == null) + if (HttpContext.Current == null && _nonHttpInstance.IsValueCreated) { - _nonHttpInstance.Dispose(); + _nonHttpInstance.Value.Dispose(); } else { diff --git a/src/Umbraco.Core/Persistence/Factories/MacroFactory.cs b/src/Umbraco.Core/Persistence/Factories/MacroFactory.cs index d6b54e4797..6327a2ac62 100644 --- a/src/Umbraco.Core/Persistence/Factories/MacroFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MacroFactory.cs @@ -12,7 +12,7 @@ namespace Umbraco.Core.Persistence.Factories public IMacro BuildEntity(MacroDto dto) { var model = new Macro(dto.Id, dto.UseInEditor, dto.RefreshRate, dto.Alias, dto.Name, dto.ScriptType, dto.ScriptAssembly, dto.Xslt, dto.CacheByPage, dto.CachePersonalized, dto.DontRender, dto.MacroFilePath); - foreach (var p in dto.MacroPropertyDtos) + foreach (var p in dto.MacroPropertyDtos.EmptyNull()) { model.Properties.Add(new MacroProperty(p.Id, p.Alias, p.Name, p.SortOrder, p.EditorAlias)); } diff --git a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs index 658ddad2d4..0685432398 100644 --- a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs @@ -93,18 +93,15 @@ namespace Umbraco.Core.Persistence.Factories entity.IsDraft = dto.NewestVersion != default(Guid) && (dto.PublishedVersion == default(Guid) || dto.PublishedVersion != dto.NewestVersion); entity.HasPendingChanges = (dto.PublishedVersion != default(Guid) && dto.NewestVersion != default(Guid)) && dto.PublishedVersion != dto.NewestVersion; - if (dto.UmbracoPropertyDtos != null) + foreach (var propertyDto in dto.UmbracoPropertyDtos.EmptyNull()) { - foreach (var propertyDto in dto.UmbracoPropertyDtos) + entity.AdditionalData[propertyDto.PropertyAlias] = new UmbracoEntity.EntityProperty { - entity.AdditionalData[propertyDto.PropertyAlias] = new UmbracoEntity.EntityProperty - { - PropertyEditorAlias = propertyDto.PropertyEditorAlias, - Value = propertyDto.NTextValue.IsNullOrWhiteSpace() - ? propertyDto.NVarcharValue - : propertyDto.NTextValue.ConvertToJsonIfPossible() - }; - } + PropertyEditorAlias = propertyDto.PropertyEditorAlias, + Value = propertyDto.NTextValue.IsNullOrWhiteSpace() + ? propertyDto.NVarcharValue + : propertyDto.NTextValue.ConvertToJsonIfPossible() + }; } return entity; diff --git a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs index bf6ff7d09e..bbc193d461 100644 --- a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs @@ -41,7 +41,7 @@ namespace Umbraco.Core.Persistence.Factories LastPasswordChangeDate = dto.LastPasswordChangeDate ?? DateTime.MinValue }; - foreach (var app in dto.User2AppDtos) + foreach (var app in dto.User2AppDtos.EmptyNull()) { user.AddAllowedSection(app.AppAlias); } diff --git a/src/Umbraco.Core/Persistence/FaultHandling/RetryDbConnection.cs b/src/Umbraco.Core/Persistence/FaultHandling/RetryDbConnection.cs new file mode 100644 index 0000000000..ee67774dc1 --- /dev/null +++ b/src/Umbraco.Core/Persistence/FaultHandling/RetryDbConnection.cs @@ -0,0 +1,222 @@ +using System; +using System.Data; +using System.Data.Common; +using NPoco; +using Transaction = System.Transactions.Transaction; + +namespace Umbraco.Core.Persistence.FaultHandling +{ + class RetryDbConnection : DbConnection + { + private DbConnection _inner; + private readonly RetryPolicy _conRetryPolicy; + private readonly RetryPolicy _cmdRetryPolicy; + + public RetryDbConnection(DbConnection connection, RetryPolicy conRetryPolicy, RetryPolicy cmdRetryPolicy) + { + _inner = connection; + _inner.StateChange += StateChangeHandler; + + _conRetryPolicy = conRetryPolicy ?? RetryPolicy.NoRetry; + _cmdRetryPolicy = cmdRetryPolicy; + } + + public DbConnection Inner { get { return _inner; } } + + public override string ConnectionString { get { return _inner.ConnectionString; } set { _inner.ConnectionString = value; } } + + protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) + { + return _inner.BeginTransaction(isolationLevel); + } + + protected override bool CanRaiseEvents + { + get { return true; } + } + + public override void ChangeDatabase(string databaseName) + { + _inner.ChangeDatabase(databaseName); + } + + public override void Close() + { + _inner.Close(); + } + + public override int ConnectionTimeout + { + get { return _inner.ConnectionTimeout; } + } + + protected override DbCommand CreateDbCommand() + { + return new FaultHandlingDbCommand(this, _inner.CreateCommand(), _cmdRetryPolicy); + } + + public override string DataSource + { + get { return _inner.DataSource; } + } + + public override string Database + { + get { return _inner.Database; } + } + + protected override void Dispose(bool disposing) + { + if (disposing && _inner != null) + { + _inner.StateChange -= StateChangeHandler; + _inner.Dispose(); + } + _inner = null; + base.Dispose(disposing); + } + + public override void EnlistTransaction(Transaction transaction) + { + _inner.EnlistTransaction(transaction); + } + + public override DataTable GetSchema() + { + return _inner.GetSchema(); + } + + public override DataTable GetSchema(string collectionName) + { + return _inner.GetSchema(collectionName); + } + + public override DataTable GetSchema(string collectionName, string[] restrictionValues) + { + return _inner.GetSchema(collectionName, restrictionValues); + } + + public override void Open() + { + _conRetryPolicy.ExecuteAction(_inner.Open); + } + + public override string ServerVersion + { + get { return _inner.ServerVersion; } + } + + public override ConnectionState State + { + get { return _inner.State; } + } + + private void StateChangeHandler(object sender, StateChangeEventArgs stateChangeEventArguments) + { + OnStateChange(stateChangeEventArguments); + } + + public void Ensure() + { + // verify whether or not the connection is valid and is open. This code may be retried therefore + // it is important to ensure that a connection is re-established should it have previously failed + if (State != ConnectionState.Open) + Open(); + } + } + + class FaultHandlingDbCommand : DbCommand + { + private RetryDbConnection _connection; + private DbCommand _inner; + private readonly RetryPolicy _cmdRetryPolicy; + + public FaultHandlingDbCommand(RetryDbConnection connection, DbCommand command, RetryPolicy cmdRetryPolicy) + { + _connection = connection; + _inner = command; + _cmdRetryPolicy = cmdRetryPolicy ?? RetryPolicy.NoRetry; + } + + protected override void Dispose(bool disposing) + { + if (disposing && _inner != null) + _inner.Dispose(); + _inner = null; + base.Dispose(disposing); + } + + public override void Cancel() + { + _inner.Cancel(); + } + + public override string CommandText { get { return _inner.CommandText; } set { _inner.CommandText = value; } } + + public override int CommandTimeout { get { return _inner.CommandTimeout; } set { _inner.CommandTimeout = value; } } + + public override CommandType CommandType { get { return _inner.CommandType; } set { _inner.CommandType = value; } } + + protected override DbConnection DbConnection + { + get + { + return _connection; + } + set + { + if (value == null) throw new ArgumentNullException("value"); + var connection = value as RetryDbConnection; + if (connection == null) throw new ArgumentException("Value is not a FaultHandlingDbConnection instance."); + if (_connection != null && _connection != connection) throw new Exception("Value is another FaultHandlingDbConnection instance."); + _connection = connection; + _inner.Connection = connection.Inner; + } + } + + protected override DbParameter CreateDbParameter() + { + return _inner.CreateParameter(); + } + + protected override DbParameterCollection DbParameterCollection + { + get { return _inner.Parameters; } + } + + protected override DbTransaction DbTransaction { get { return _inner.Transaction; } set { _inner.Transaction = value; } } + + public override bool DesignTimeVisible { get; set; } + + protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) + { + return Execute(() => _inner.ExecuteReader(behavior)); + } + + public override int ExecuteNonQuery() + { + return Execute(() => _inner.ExecuteNonQuery()); + } + + public override object ExecuteScalar() + { + return Execute(() => _inner.ExecuteScalar()); + } + + private T Execute(Func f) + { + return _cmdRetryPolicy.ExecuteAction(() => + { + _connection.Ensure(); + return f(); + }); + } + + public override void Prepare() + { + _inner.Prepare(); + } + + public override UpdateRowSource UpdatedRowSource { get { return _inner.UpdatedRowSource; } set { _inner.UpdatedRowSource = value; } } + } +} diff --git a/src/Umbraco.Core/Persistence/LockedRepository.cs b/src/Umbraco.Core/Persistence/LockedRepository.cs index b5d2d672f2..c067e84288 100644 --- a/src/Umbraco.Core/Persistence/LockedRepository.cs +++ b/src/Umbraco.Core/Persistence/LockedRepository.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; @@ -7,14 +8,14 @@ namespace Umbraco.Core.Persistence internal class LockedRepository where TRepository : IDisposable, IRepository { - public LockedRepository(Transaction transaction, IDatabaseUnitOfWork unitOfWork, TRepository repository) + public LockedRepository(ITransaction transaction, IDatabaseUnitOfWork unitOfWork, TRepository repository) { Transaction = transaction; UnitOfWork = unitOfWork; Repository = repository; } - public Transaction Transaction { get; private set; } + public ITransaction Transaction { get; private set; } public IDatabaseUnitOfWork UnitOfWork { get; private set; } public TRepository Repository { get; private set; } diff --git a/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs b/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs index ff373df2bf..7f64daa899 100644 --- a/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; +using NPoco; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Mappers diff --git a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs index a622bcda8c..808a932670 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Mappers public MappingResolver(IServiceContainer container, ILogger logger, Func> assignedMapperTypes) : base(container, logger, assignedMapperTypes) { - + } /// @@ -36,7 +36,7 @@ namespace Umbraco.Core.Persistence.Mappers { return _mapperCache.GetOrAdd(type, type1 => { - + //first check if we can resolve it by attribute var byAttribute = TryGetMapperByAttribute(type); @@ -54,7 +54,7 @@ namespace Umbraco.Core.Persistence.Mappers /// /// private Attempt TryGetMapperByAttribute(Type entityType) - { + { //check if any of the mappers are assigned to this type var mapper = Values.FirstOrDefault( x => x.GetType().GetCustomAttributes(false) @@ -66,7 +66,7 @@ namespace Umbraco.Core.Persistence.Mappers } return Attempt.Succeed(mapper); - } + } internal string GetMapping(Type type, string propertyName) { diff --git a/src/Umbraco.Core/Persistence/Mappers/PetaPocoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/PetaPocoMapper.cs deleted file mode 100644 index fd516073ce..0000000000 --- a/src/Umbraco.Core/Persistence/Mappers/PetaPocoMapper.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Reflection; - -namespace Umbraco.Core.Persistence.Mappers -{ - /// - /// Represents the PetaPocoMapper, which is the implementation of the IMapper interface. - /// This is currently only used to ensure that nullable dates are not saved to the database. - /// - public class PetaPocoMapper : IMapper - { - public void GetTableInfo(Type t, TableInfo ti) - { - } - - public bool MapPropertyToColumn(Type t, PropertyInfo pi, ref string columnName, ref bool resultColumn) - { - return true; - } - - public Func GetFromDbConverter(PropertyInfo pi, Type sourceType) - { - return null; - } - - public Func GetToDbConverter(Type sourceType) - { - //We need this check to ensure that PetaPoco doesn't try to insert an invalid - //date from a nullable DateTime property. - if (sourceType == typeof(DateTime)) - { - return datetimeVal => - { - var datetime = datetimeVal as DateTime?; - if (datetime.HasValue && datetime.Value > DateTime.MinValue) - return datetime.Value; - - return null; - }; - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/PocoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/PocoMapper.cs new file mode 100644 index 0000000000..281e05499c --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/PocoMapper.cs @@ -0,0 +1,31 @@ +using System; +using System.Reflection; +using NPoco; + +namespace Umbraco.Core.Persistence.Mappers +{ + /// + /// Extends NPoco default mapper and ensures that nullable dates are not saved to the database. + /// + public class PocoMapper : DefaultMapper + { + public override Func GetToDbConverter(Type destType, MemberInfo sourceMemberInfo) + { + // ensures that NPoco does not try to insert an invalid date + // from a nullable DateTime property + if (sourceMemberInfo.GetMemberInfoType() == typeof(DateTime)) + { + return datetimeVal => + { + var datetime = datetimeVal as DateTime?; + if (datetime.HasValue && datetime.Value > DateTime.MinValue) + return datetime.Value; + + return null; + }; + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs b/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs index b162eba305..4440e7d2e3 100644 --- a/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs +++ b/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs b/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs index c8d36de915..4ea66b869f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs @@ -1,4 +1,6 @@ -namespace Umbraco.Core.Persistence.Migrations +using NPoco; + +namespace Umbraco.Core.Persistence.Migrations { /// /// Marker interface for migration expressions diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 7e70adb10f..66d9c8be0c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index f789c18aa1..e89d7367ec 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Events; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs index 70821d301f..966a0715c7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.Migrations.Syntax.Alter; using Umbraco.Core.Persistence.Migrations.Syntax.Create; @@ -79,5 +80,10 @@ namespace Umbraco.Core.Persistence.Migrations { return new IfDatabaseBuilder(Context, SqlSyntax, databaseProviders); } + + protected Sql Sql() + { + return NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, Context.Database)); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs index c2f0b6051d..8126a402f2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs index 6c3ef66735..8a0e0d7063 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index 3c70cf6bcb..dbb98c877f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; using log4net; +using NPoco; using Semver; using Umbraco.Core.Configuration; using Umbraco.Core.Events; @@ -51,7 +52,7 @@ namespace Umbraco.Core.Persistence.Migrations /// /// Executes the migrations against the database. /// - /// The PetaPoco Database, which the migrations will be run against + /// The NPoco Database, which the migrations will be run against /// /// /// Boolean indicating whether this is an upgrade or downgrade @@ -67,7 +68,7 @@ namespace Umbraco.Core.Persistence.Migrations ? OrderedUpgradeMigrations(foundMigrations).ToList() : OrderedDowngradeMigrations(foundMigrations).ToList(); - + if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, _productName, true), this)) { _logger.Warn("Migration was cancelled by an event"); @@ -164,9 +165,9 @@ namespace Umbraco.Core.Persistence.Migrations } internal MigrationContext InitializeMigrations( - List migrations, - Database database, - DatabaseProviders databaseProvider, + List migrations, + Database database, + DatabaseProviders databaseProvider, ISqlSyntaxProvider sqlSyntax, bool isUpgrade = true) { @@ -242,7 +243,7 @@ namespace Umbraco.Core.Persistence.Migrations var exeSql = sb.ToString(); _logger.Info("Executing sql statement " + i + ": " + exeSql); database.Execute(exeSql); - + //restart the string builder sb.Remove(0, sb.Length); } @@ -259,7 +260,7 @@ namespace Umbraco.Core.Persistence.Migrations database.Execute(exeSql); } } - + i++; } @@ -273,9 +274,9 @@ namespace Umbraco.Core.Persistence.Migrations var exists = _migrationEntryService.FindEntry(_productName, _targetVersion); if (exists == null) { - _migrationEntryService.CreateEntry(_productName, _targetVersion); + _migrationEntryService.CreateEntry(_productName, _targetVersion); } - + } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/ExecuteBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/ExecuteBuilder.cs index 549a4a0c66..5d8bc6b965 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/ExecuteBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/ExecuteBuilder.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence.Migrations.Syntax.Execute.Expressions; using Umbraco.Core.Persistence.SqlSyntax; diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteCodeStatementExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteCodeStatementExpression.cs index c5ab17db44..87ff16f31f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteCodeStatementExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteCodeStatementExpression.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute.Expressions diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/IExecuteBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/IExecuteBuilder.cs index 46717e0a3f..1d4c8e3f55 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/IExecuteBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/IExecuteBuilder.cs @@ -1,4 +1,5 @@ using System; +using NPoco; namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute { diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs index c99a1f95f8..db1ebde5d9 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Persistence.SqlSyntax; +using NPoco; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions { diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs index d65fc90bcc..121d6d7ff3 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs @@ -9,6 +9,7 @@ using System.Web.Script.Serialization; using System.Xml; using System.Xml.Linq; using Newtonsoft.Json; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -33,8 +34,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven { if (database != null) { - var dtSql = new Sql().Select("nodeId").From(SqlSyntax) - .Where(SqlSyntax, dto => dto.PropertyEditorAlias == Constants.PropertyEditors.RelatedLinksAlias); + var dtSql = Sql().Select("nodeId").From() + .Where(dto => dto.PropertyEditorAlias == Constants.PropertyEditors.RelatedLinksAlias); var dataTypeIds = database.Fetch(dtSql); if (!dataTypeIds.Any()) return string.Empty; diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs index fe600f6b69..c8ba7325a6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs index 4d017dd230..c040fd7349 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -28,12 +29,12 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer Constants.ObjectTypes.MemberTypeGuid, }; - var sql = new Sql() + var sql = NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, Context.Database)) .Select("umbracoNode.id,cmsContentType.alias,umbracoNode.nodeObjectType") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .WhereIn(SqlSyntax, x => x.NodeObjectType, objectTypes); + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .WhereIn(x => x.NodeObjectType, objectTypes); var rows = Context.Database.Fetch(sql); diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs index 00915e1947..323248d5d5 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs @@ -1,4 +1,5 @@ using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -17,7 +18,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer public override void Up() { var mediaListviewIncludeProperties = Context.Database.Fetch( - new Sql().Select("*").From(SqlSyntax).Where(SqlSyntax, x => x.Id == -9)).FirstOrDefault(); + Sql().SelectAll().From().Where(x => x.Id == -9)).FirstOrDefault(); if (mediaListviewIncludeProperties != null) { if (mediaListviewIncludeProperties.Value.Contains("\"alias\":\"sort\"")) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs index 50f78ca66d..5c61c03723 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs @@ -1,4 +1,5 @@ using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -18,7 +19,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeOn public override void Up() { - var userData = Context.Database.Fetch(new Sql().Select("*").From(SqlSyntax)); + var userData = Context.Database.Fetch(Sql().SelectAll().From()); foreach (var user in userData.Where(x => x.UserLanguage.Contains("_"))) { var languageParts = user.UserLanguage.Split('_'); diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs index 91b4bd6438..06a3995c36 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -25,7 +26,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeTw List migrations = null; Execute.Code(db => { - migrations = Context.Database.Fetch(new Sql().Select("*").From(SqlSyntax)); + migrations = Context.Database.Fetch(Sql().SelectAll().From()); return string.Empty; }); Delete.FromTable("umbracoMigration").AllRows(); diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs index eea56031d4..7bc94cdaba 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs @@ -1,6 +1,7 @@ using System; using System.Data; using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -45,7 +46,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe .WithColumn("languageISOCode").AsString(10).Nullable() .WithColumn("languageCultureName").AsString(50).Nullable(); - var currentData = this.Context.Database.Fetch(new Sql().Select("*").From(SqlSyntax)); + var currentData = Context.Database.Fetch(Sql().SelectAll().From()); foreach (var languageDto in currentData) { Insert.IntoTable("umbracoLanguage_TEMP") diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs index 8ef10b178f..c5ca312123 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -74,7 +75,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe Execute.Code(database => { //NOTE: we are using dynamic because we need to get the data in a column that no longer exists in the schema - var templates = database.Fetch(new Sql().Select("*").From(SqlSyntax)); + var templates = database.Fetch(Sql().SelectAll().From()); foreach (var template in templates) { var sql = string.Format(SqlSyntax.UpdateData, diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs index de7c4e09aa..19d44ba3f9 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Linq; using System.Xml.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -25,7 +26,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe if (tables.InvariantContains("umbracoAccess")) { //don't run if data is already there. - var dataExists = Context.Database.Fetch(new Sql().Select("*").From(SqlSyntax)); + var dataExists = Context.Database.Fetch(Sql().SelectAll().From()); if (dataExists.Any()) return; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs index 6c4f6ea97b..3b82a02c47 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs @@ -1,4 +1,5 @@ using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -34,7 +35,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero if (adminUserType.DefaultPermissions.Contains("7") == false) { adminUserType.DefaultPermissions = adminUserType.DefaultPermissions + "7"; - database.Save(adminUserType); + database.Save(adminUserType); } } @@ -50,7 +51,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero if (adminUserType.DefaultPermissions.Contains("7")) { adminUserType.DefaultPermissions = adminUserType.DefaultPermissions.Replace("7", ""); - database.Save(adminUserType); + database.Save(adminUserType); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs index a0b64a9830..311672f237 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs index 9a2b47d79d..b96aedaca2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs similarity index 87% rename from src/Umbraco.Core/Persistence/PetaPocoExtensions.cs rename to src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs index 4c8d72ceec..b7e3407176 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs @@ -1,331 +1,337 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Data.SqlClient; -using System.Linq; -using System.Text.RegularExpressions; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Core.Persistence -{ - public static class PetaPocoExtensions - { - // NOTE - // - // proper way to do it with TSQL and SQLCE - // IF EXISTS (SELECT ... FROM table WITH (UPDLOCK,HOLDLOCK)) WHERE ...) - // BEGIN - // UPDATE table SET ... WHERE ... - // END - // ELSE - // BEGIN - // INSERT INTO table (...) VALUES (...) - // END - // - // works in READ COMMITED, TSQL & SQLCE lock the constraint even if it does not exist, so INSERT is OK - // - // proper way to do it with MySQL - // IF EXISTS (SELECT ... FROM table WHERE ... FOR UPDATE) - // BEGIN - // UPDATE table SET ... WHERE ... - // END - // ELSE - // BEGIN - // INSERT INTO table (...) VALUES (...) - // END - // - // MySQL locks the constraint ONLY if it exists, so INSERT may fail... - // in theory, happens in READ COMMITTED but not REPEATABLE READ - // http://www.percona.com/blog/2012/08/28/differences-between-read-committed-and-repeatable-read-transaction-isolation-levels/ - // but according to - // http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html - // it won't work for exact index value (only ranges) so really... - // - // MySQL should do - // INSERT INTO table (...) VALUES (...) ON DUPLICATE KEY UPDATE ... - // - // also the lock is released when the transaction is committed - // not sure if that can have unexpected consequences on our code? - // - // so... for the time being, let's do with that somewhat crazy solution below... - - /// - /// Safely inserts a record, or updates if it exists, based on a unique constraint. - /// - /// - /// - /// The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object - /// passed in will contain the updated value. - /// - /// We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE - /// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting - /// isolation levels globally. We want to keep it simple for the time being and manage it manually. - /// We handle it by trying to update, then insert, etc. until something works, or we get bored. - /// Note that with proper transactions, if T2 begins after T1 then we are sure that the database will contain T2's value - /// once T1 and T2 have completed. Whereas here, it could contain T1's value. - /// - internal static RecordPersistenceType InsertOrUpdate(this Database db, T poco) - where T : class - { - return db.InsertOrUpdate(poco, null, null); - } - - /// - /// Safely inserts a record, or updates if it exists, based on a unique constraint. - /// - /// - /// - /// - /// If the entity has a composite key they you need to specify the update command explicitly - /// The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object - /// passed in will contain the updated value. - /// - /// We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE - /// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting - /// isolation levels globally. We want to keep it simple for the time being and manage it manually. - /// We handle it by trying to update, then insert, etc. until something works, or we get bored. - /// Note that with proper transactions, if T2 begins after T1 then we are sure that the database will contain T2's value - /// once T1 and T2 have completed. Whereas here, it could contain T1's value. - /// - internal static RecordPersistenceType InsertOrUpdate(this Database db, - T poco, - string updateCommand, - object updateArgs) - where T : class - { - if (poco == null) - throw new ArgumentNullException("poco"); - - // try to update - var rowCount = updateCommand.IsNullOrWhiteSpace() - ? db.Update(poco) - : db.Update(updateCommand, updateArgs); - if (rowCount > 0) - return RecordPersistenceType.Update; - - // failed: does not exist, need to insert - // RC1 race cond here: another thread may insert a record with the same constraint - - var i = 0; - while (i++ < 4) - { - try - { - // try to insert - db.Insert(poco); - return RecordPersistenceType.Insert; - } - catch (SqlException) // TODO: need to find out if all db will throw that exception - probably OK - { - // failed: exists (due to race cond RC1) - // RC2 race cond here: another thread may remove the record - - // try to update - rowCount = updateCommand.IsNullOrWhiteSpace() - ? db.Update(poco) - : db.Update(updateCommand, updateArgs); - if (rowCount > 0) - return RecordPersistenceType.Update; - - // failed: does not exist (due to race cond RC2), need to insert - // loop - } - } - - // this can go on forever... have to break at some point and report an error. - throw new DataException("Record could not be inserted or updated."); - } - - /// - /// This will escape single @ symbols for peta poco values so it doesn't think it's a parameter - /// - /// - /// - public static string EscapeAtSymbols(string value) - { - if (value.Contains("@")) - { - //this fancy regex will only match a single @ not a double, etc... - var regex = new Regex("(?(this Database db, ISqlSyntaxProvider sqlSyntax, IEnumerable collection) - { - //don't do anything if there are no records. - if (collection.Any() == false) - return; - - using (var tr = db.GetTransaction()) - { - db.BulkInsertRecords(sqlSyntax, collection, tr, true); - } - } - - /// - /// Performs the bulk insertion in the context of a current transaction with an optional parameter to complete the transaction - /// when finished - /// - /// - /// - /// - /// - /// - /// - public static void BulkInsertRecords(this Database db, ISqlSyntaxProvider sqlSyntax, IEnumerable collection, Transaction tr, bool commitTrans = false) - { - //don't do anything if there are no records. - if (collection.Any() == false) - return; - - try - { - //if it is sql ce or it is a sql server version less than 2008, we need to do individual inserts. - var sqlServerSyntax = sqlSyntax as SqlServerSyntaxProvider; - if ((sqlServerSyntax != null && (int)sqlServerSyntax.VersionName.Value < (int)SqlServerVersionName.V2008) - || sqlSyntax is SqlCeSyntaxProvider) - { - //SqlCe doesn't support bulk insert statements! - - foreach (var poco in collection) - { - db.Insert(poco); - } - } - else - { - string[] sqlStatements; - var cmds = db.GenerateBulkInsertCommand(collection, db.Connection, out sqlStatements); - for (var i = 0; i < sqlStatements.Length; i++) - { - using (var cmd = cmds[i]) - { - cmd.CommandText = sqlStatements[i]; - cmd.ExecuteNonQuery(); - } - } - } - - if (commitTrans) - { - tr.Complete(); - } - } - catch - { - if (commitTrans) - { - tr.Dispose(); - } - throw; - } - } - - /// - /// Creates a bulk insert command - /// - /// - /// - /// - /// - /// - /// Sql commands with populated command parameters required to execute the sql statement - /// - /// The limits for number of parameters are 2100 (in sql server, I think there's many more allowed in mysql). So - /// we need to detect that many params and split somehow. - /// For some reason the 2100 limit is not actually allowed even though the exception from sql server mentions 2100 as a max, perhaps it is 2099 - /// that is max. I've reduced it to 2000 anyways. - /// - internal static IDbCommand[] GenerateBulkInsertCommand( - this Database db, - IEnumerable collection, - IDbConnection connection, - out string[] sql) - { - //A filter used below a few times to get all columns except result cols and not the primary key if it is auto-incremental - Func, bool> includeColumn = (data, column) => - { - if (column.Value.ResultColumn) return false; - if (data.TableInfo.AutoIncrement && column.Key == data.TableInfo.PrimaryKey) return false; - return true; - }; - - var pd = Database.PocoData.ForType(typeof(T)); - var tableName = db.EscapeTableName(pd.TableInfo.TableName); - - //get all columns to include and format for sql - var cols = string.Join(", ", - pd.Columns - .Where(c => includeColumn(pd, c)) - .Select(c => tableName + "." + db.EscapeSqlIdentifier(c.Key)).ToArray()); - - var itemArray = collection.ToArray(); - - //calculate number of parameters per item - var paramsPerItem = pd.Columns.Count(i => includeColumn(pd, i)); - - //Example calc: - // Given: we have 4168 items in the itemArray, each item contains 8 command parameters (values to be inserterted) - // 2100 / 8 = 262.5 - // Math.Floor(2100 / 8) = 262 items per trans - // 4168 / 262 = 15.908... = there will be 16 trans in total - - //all items will be included if we have disabled db parameters - var itemsPerTrans = Math.Floor(2000.00 / paramsPerItem); - //there will only be one transaction if we have disabled db parameters - var numTrans = Math.Ceiling(itemArray.Length / itemsPerTrans); - - var sqlQueries = new List(); - var commands = new List(); - - for (var tIndex = 0; tIndex < numTrans; tIndex++) - { - var itemsForTrans = itemArray - .Skip(tIndex * (int)itemsPerTrans) - .Take((int)itemsPerTrans); - - var cmd = db.CreateCommand(connection, ""); - var pocoValues = new List(); - var index = 0; - foreach (var poco in itemsForTrans) - { - var values = new List(); - //get all columns except result cols and not the primary key if it is auto-incremental - foreach (var i in pd.Columns.Where(x => includeColumn(pd, x))) - { - db.AddParam(cmd, i.Value.GetValue(poco), "@"); - values.Add(string.Format("{0}{1}", "@", index++)); - } - pocoValues.Add("(" + string.Join(",", values.ToArray()) + ")"); - } - - var sqlResult = string.Format("INSERT INTO {0} ({1}) VALUES {2}", tableName, cols, string.Join(", ", pocoValues)); - sqlQueries.Add(sqlResult); - commands.Add(cmd); - } - - sql = sqlQueries.ToArray(); - - return commands.ToArray(); - } - - public static void TruncateTable(this Database db, ISqlSyntaxProvider sqlSyntax, string tableName) - { - var sql = new Sql(string.Format( - sqlSyntax.TruncateTable, - sqlSyntax.GetQuotedTableName(tableName))); - db.Execute(sql); - } - - - } - - +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.SqlClient; +using System.Linq; +using System.Text.RegularExpressions; +using NPoco; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence +{ + /// + /// Provides extension methods to NPoco Database class. + /// + public static class NPocoDatabaseExtensions + { + // NOTE + // + // proper way to do it with TSQL and SQLCE + // IF EXISTS (SELECT ... FROM table WITH (UPDLOCK,HOLDLOCK)) WHERE ...) + // BEGIN + // UPDATE table SET ... WHERE ... + // END + // ELSE + // BEGIN + // INSERT INTO table (...) VALUES (...) + // END + // + // works in READ COMMITED, TSQL & SQLCE lock the constraint even if it does not exist, so INSERT is OK + // + // proper way to do it with MySQL + // IF EXISTS (SELECT ... FROM table WHERE ... FOR UPDATE) + // BEGIN + // UPDATE table SET ... WHERE ... + // END + // ELSE + // BEGIN + // INSERT INTO table (...) VALUES (...) + // END + // + // MySQL locks the constraint ONLY if it exists, so INSERT may fail... + // in theory, happens in READ COMMITTED but not REPEATABLE READ + // http://www.percona.com/blog/2012/08/28/differences-between-read-committed-and-repeatable-read-transaction-isolation-levels/ + // but according to + // http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html + // it won't work for exact index value (only ranges) so really... + // + // MySQL should do + // INSERT INTO table (...) VALUES (...) ON DUPLICATE KEY UPDATE ... + // + // also the lock is released when the transaction is committed + // not sure if that can have unexpected consequences on our code? + // + // so... for the time being, let's do with that somewhat crazy solution below... + + /// + /// Safely inserts a record, or updates if it exists, based on a unique constraint. + /// + /// + /// + /// The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object + /// passed in will contain the updated value. + /// + /// We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE + /// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting + /// isolation levels globally. We want to keep it simple for the time being and manage it manually. + /// We handle it by trying to update, then insert, etc. until something works, or we get bored. + /// Note that with proper transactions, if T2 begins after T1 then we are sure that the database will contain T2's value + /// once T1 and T2 have completed. Whereas here, it could contain T1's value. + /// + internal static RecordPersistenceType InsertOrUpdate(this Database db, T poco) + where T : class + { + return db.InsertOrUpdate(poco, null, null); + } + + /// + /// Safely inserts a record, or updates if it exists, based on a unique constraint. + /// + /// + /// + /// + /// If the entity has a composite key they you need to specify the update command explicitly + /// The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object + /// passed in will contain the updated value. + /// + /// We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE + /// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting + /// isolation levels globally. We want to keep it simple for the time being and manage it manually. + /// We handle it by trying to update, then insert, etc. until something works, or we get bored. + /// Note that with proper transactions, if T2 begins after T1 then we are sure that the database will contain T2's value + /// once T1 and T2 have completed. Whereas here, it could contain T1's value. + /// + internal static RecordPersistenceType InsertOrUpdate(this Database db, + T poco, + string updateCommand, + object updateArgs) + where T : class + { + if (poco == null) + throw new ArgumentNullException("poco"); + + // try to update + var rowCount = updateCommand.IsNullOrWhiteSpace() + ? db.Update(poco) + : db.Update(updateCommand, updateArgs); + if (rowCount > 0) + return RecordPersistenceType.Update; + + // failed: does not exist, need to insert + // RC1 race cond here: another thread may insert a record with the same constraint + + var i = 0; + while (i++ < 4) + { + try + { + // try to insert + db.Insert(poco); + return RecordPersistenceType.Insert; + } + catch (SqlException) // TODO: need to find out if all db will throw that exception - probably OK + { + // failed: exists (due to race cond RC1) + // RC2 race cond here: another thread may remove the record + + // try to update + rowCount = updateCommand.IsNullOrWhiteSpace() + ? db.Update(poco) + : db.Update(updateCommand, updateArgs); + if (rowCount > 0) + return RecordPersistenceType.Update; + + // failed: does not exist (due to race cond RC2), need to insert + // loop + } + } + + // this can go on forever... have to break at some point and report an error. + throw new DataException("Record could not be inserted or updated."); + } + + /// + /// This will escape single @ symbols for npoco values so it doesn't think it's a parameter + /// + /// + /// + public static string EscapeAtSymbols(string value) + { + if (value.Contains("@")) + { + //this fancy regex will only match a single @ not a double, etc... + var regex = new Regex("(?(this Database db, ISqlSyntaxProvider sqlSyntax, IEnumerable collection) + { + //don't do anything if there are no records. + if (collection.Any() == false) + return; + + using (var tr = db.GetTransaction()) + { + db.BulkInsertRecords(sqlSyntax, collection, tr, true); + } + } + + /// + /// Performs the bulk insertion in the context of a current transaction with an optional parameter to complete the transaction + /// when finished + /// + /// + /// + /// + /// + /// + /// + public static void BulkInsertRecords(this Database db, ISqlSyntaxProvider sqlSyntax, IEnumerable collection, ITransaction tr, bool commitTrans = false) + { + //don't do anything if there are no records. + if (collection.Any() == false) + return; + + try + { + //if it is sql ce or it is a sql server version less than 2008, we need to do individual inserts. + var sqlServerSyntax = sqlSyntax as SqlServerSyntaxProvider; + if ((sqlServerSyntax != null && (int)sqlServerSyntax.VersionName.Value < (int)SqlServerVersionName.V2008) + || sqlSyntax is SqlCeSyntaxProvider) + { + //SqlCe doesn't support bulk insert statements! + + foreach (var poco in collection) + { + db.Insert(poco); + } + } + else + { + string[] sqlStatements; + var cmds = db.GenerateBulkInsertCommand(collection, db.Connection, out sqlStatements); + for (var i = 0; i < sqlStatements.Length; i++) + { + using (var cmd = cmds[i]) + { + cmd.CommandText = sqlStatements[i]; + cmd.ExecuteNonQuery(); + } + } + } + + if (commitTrans) + { + tr.Complete(); + } + } + catch + { + if (commitTrans) + { + tr.Dispose(); + } + throw; + } + } + + /// + /// Creates a bulk insert command + /// + /// + /// + /// + /// + /// + /// Sql commands with populated command parameters required to execute the sql statement + /// + /// The limits for number of parameters are 2100 (in sql server, I think there's many more allowed in mysql). So + /// we need to detect that many params and split somehow. + /// For some reason the 2100 limit is not actually allowed even though the exception from sql server mentions 2100 as a max, perhaps it is 2099 + /// that is max. I've reduced it to 2000 anyways. + /// + internal static IDbCommand[] GenerateBulkInsertCommand( + this Database db, + IEnumerable collection, + DbConnection connection, + out string[] sql) + { + //A filter used below a few times to get all columns except result cols and not the primary key if it is auto-incremental + Func, bool> includeColumn = (data, column) => + { + if (column.Value.ResultColumn) return false; + if (data.TableInfo.AutoIncrement && column.Key == data.TableInfo.PrimaryKey) return false; + return true; + }; + + var pd = db.PocoDataFactory.ForType(typeof(T)); + var tableName = db.DatabaseType.EscapeTableName(pd.TableInfo.TableName); + + //get all columns to include and format for sql + var cols = string.Join(", ", + pd.Columns + .Where(c => includeColumn(pd, c)) + .Select(c => tableName + "." + db.DatabaseType.EscapeSqlIdentifier(c.Key)).ToArray()); + + var itemArray = collection.ToArray(); + + //calculate number of parameters per item + var paramsPerItem = pd.Columns.Count(i => includeColumn(pd, i)); + + //Example calc: + // Given: we have 4168 items in the itemArray, each item contains 8 command parameters (values to be inserterted) + // 2100 / 8 = 262.5 + // Math.Floor(2100 / 8) = 262 items per trans + // 4168 / 262 = 15.908... = there will be 16 trans in total + + //all items will be included if we have disabled db parameters + var itemsPerTrans = Math.Floor(2000.00 / paramsPerItem); + //there will only be one transaction if we have disabled db parameters + var numTrans = Math.Ceiling(itemArray.Length / itemsPerTrans); + + var sqlQueries = new List(); + var commands = new List(); + + for (var tIndex = 0; tIndex < numTrans; tIndex++) + { + var itemsForTrans = itemArray + .Skip(tIndex * (int)itemsPerTrans) + .Take((int)itemsPerTrans); + + var cmd = db.CreateCommand(connection, ""); + var pocoValues = new List(); + var index = 0; + foreach (var poco in itemsForTrans) + { + var values = new List(); + //get all columns except result cols and not the primary key if it is auto-incremental + var prefix = db.DatabaseType.GetParameterPrefix(cmd.Connection.ConnectionString); + foreach (var i in pd.Columns.Where(x => includeColumn(pd, x))) + { + db.AddParameter(cmd, i.Value.GetValue(poco)); + values.Add(prefix + index++); + } + pocoValues.Add("(" + string.Join(",", values.ToArray()) + ")"); + } + + var sqlResult = string.Format("INSERT INTO {0} ({1}) VALUES {2}", tableName, cols, string.Join(", ", pocoValues)); + sqlQueries.Add(sqlResult); + commands.Add(cmd); + } + + sql = sqlQueries.ToArray(); + + return commands.ToArray(); + } + + public static void TruncateTable(this Database db, ISqlSyntaxProvider sqlSyntax, string tableName) + { + var sql = new Sql(string.Format( + sqlSyntax.TruncateTable, + sqlSyntax.GetQuotedTableName(tableName))); + db.Execute(sql); + } + + public static IsolationLevel GetCurrentTransactionIsolationLevel(this Database database) + { + var transaction = database.Transaction; + return transaction == null ? IsolationLevel.Unspecified : transaction.IsolationLevel; + } + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs deleted file mode 100644 index a174255746..0000000000 --- a/src/Umbraco.Core/Persistence/PetaPoco.cs +++ /dev/null @@ -1,2504 +0,0 @@ -/* PetaPoco v4.0.3 - A Tiny ORMish thing for your POCO's. - * Copyright © 2011 Topten Software. All Rights Reserved. - * - * Apache License 2.0 - http://www.toptensoftware.com/petapoco/license - * - * Special thanks to Rob Conery (@robconery) for original inspiration (ie:Massive) and for - * use of Subsonic's T4 templates, Rob Sullivan (@DataChomp) for hard core DBA advice - * and Adam Schroder (@schotime) for lots of suggestions, improvements and Oracle support - */ - -// Define PETAPOCO_NO_DYNAMIC in your project settings on .NET 3.5 - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Caching; -using System.Security; -using System.Security.Permissions; -using System.Text; -using System.Configuration; -using System.Data.Common; -using System.Data; -using System.Text.RegularExpressions; -using System.Reflection; -using System.Reflection.Emit; -using System.Linq.Expressions; - -namespace Umbraco.Core.Persistence -{ - // Poco's marked [Explicit] require all column properties to be marked - [AttributeUsage(AttributeTargets.Class)] - public class ExplicitColumnsAttribute : Attribute - { - } - // For non-explicit pocos, causes a property to be ignored - [AttributeUsage(AttributeTargets.Property)] - public class IgnoreAttribute : Attribute - { - } - - // For explicit pocos, marks property as a column and optionally supplies column name - [AttributeUsage(AttributeTargets.Property)] - public class ColumnAttribute : Attribute - { - public ColumnAttribute() { } - public ColumnAttribute(string name) { Name = name; } - public string Name { get; set; } - } - - // For explicit pocos, marks property as a result column and optionally supplies column name - [AttributeUsage(AttributeTargets.Property)] - public class ResultColumnAttribute : ColumnAttribute - { - public ResultColumnAttribute() { } - public ResultColumnAttribute(string name) : base(name) { } - } - - // Specify the table name of a poco - [AttributeUsage(AttributeTargets.Class)] - public class TableNameAttribute : Attribute - { - public TableNameAttribute(string tableName) - { - Value = tableName; - } - public string Value { get; private set; } - } - - // Specific the primary key of a poco class (and optional sequence name for Oracle) - [AttributeUsage(AttributeTargets.Class)] - public class PrimaryKeyAttribute : Attribute - { - public PrimaryKeyAttribute(string primaryKey) - { - Value = primaryKey; - autoIncrement = true; - } - - public string Value { get; private set; } - public string sequenceName { get; set; } - public bool autoIncrement { get; set; } - } - - [AttributeUsage(AttributeTargets.Property)] - public class AutoJoinAttribute : Attribute - { - public AutoJoinAttribute() { } - } - - // Results from paged request - public class Page - { - public long CurrentPage { get; set; } - public long TotalPages { get; set; } - public long TotalItems { get; set; } - public long ItemsPerPage { get; set; } - public List Items { get; set; } - public object Context { get; set; } - } - - // Pass as parameter value to force to DBType.AnsiString - public class AnsiString - { - public AnsiString(string str) - { - Value = str; - } - public string Value { get; private set; } - } - - // Used by IMapper to override table bindings for an object - public class TableInfo - { - public string TableName { get; set; } - public string PrimaryKey { get; set; } - public bool AutoIncrement { get; set; } - public string SequenceName { get; set; } - } - - // Optionally provide an implementation of this to Database.Mapper - public interface IMapper - { - void GetTableInfo(Type t, TableInfo ti); - bool MapPropertyToColumn(Type t, PropertyInfo pi, ref string columnName, ref bool resultColumn); - Func GetFromDbConverter(PropertyInfo pi, Type SourceType); - Func GetToDbConverter(Type SourceType); - } - - // This will be merged with IMapper in the next major version - public interface IMapper2 : IMapper - { - Func GetFromDbConverter(Type DestType, Type SourceType); - } - - // Database class ... this is where most of the action happens - public class Database : IDisposable - { - public Database(IDbConnection connection) - { - _sharedConnection = connection; - _connectionString = connection.ConnectionString; - _sharedConnectionDepth = 2; // Prevent closing external connection - CommonConstruct(); - } - - public Database(string connectionString, string providerName) - { - _connectionString = connectionString; - _providerName = providerName; - CommonConstruct(); - } - - public Database(string connectionString, DbProviderFactory provider) - { - _connectionString = connectionString; - _factory = provider; - CommonConstruct(); - } - - public Database(string connectionStringName) - { - // Use first? - if (connectionStringName == "") - connectionStringName = ConfigurationManager.ConnectionStrings[0].Name; - - // Work out connection string and provider name - var providerName = "System.Data.SqlClient"; - if (ConfigurationManager.ConnectionStrings[connectionStringName] != null) - { - if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName)) - providerName = ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName; - } - else - { - throw new InvalidOperationException("Can't find a connection string with the name '" + connectionStringName + "'"); - } - - // Store factory and connection string - _connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; - _providerName = providerName; - CommonConstruct(); - } - - enum DBType - { - SqlServer, - SqlServerCE, - MySql, - PostgreSQL, - Oracle, - SQLite - } - DBType _dbType = DBType.SqlServer; - - // Common initialization - private void CommonConstruct() - { - _transactionDepth = 0; - EnableAutoSelect = true; - EnableNamedParams = true; - ForceDateTimesToUtc = true; - - if (_providerName != null) - _factory = DbProviderFactories.GetFactory(_providerName); - - string dbtype = (_factory == null ? _sharedConnection.GetType() : _factory.GetType()).Name; - - if (dbtype.StartsWith("MySql")) _dbType = DBType.MySql; - else if (dbtype.StartsWith("SqlCe")) _dbType = DBType.SqlServerCE; - else if (dbtype.StartsWith("Npgsql")) _dbType = DBType.PostgreSQL; - else if (dbtype.StartsWith("Oracle")) _dbType = DBType.Oracle; - else if (dbtype.StartsWith("SQLite")) _dbType = DBType.SQLite; - - if (_dbType == DBType.MySql && _connectionString != null && _connectionString.IndexOf("Allow User Variables=true") >= 0) - _paramPrefix = "?"; - if (_dbType == DBType.Oracle) - _paramPrefix = ":"; - - // by default use MSSQL default ReadCommitted level - //TODO change to RepeatableRead - but that is breaking - _isolationLevel = IsolationLevel.ReadCommitted; - } - - // Automatically close one open shared connection - public void Dispose() - { - // Automatically close one open connection reference - // (Works with KeepConnectionAlive and manually opening a shared connection) - CloseSharedConnection(); - } - - // Set to true to keep the first opened connection alive until this object is disposed - public bool KeepConnectionAlive { get; set; } - - // Open a connection (can be nested) - public void OpenSharedConnection() - { - if (_sharedConnectionDepth == 0) - { - _sharedConnection = _factory.CreateConnection(); - _sharedConnection.ConnectionString = _connectionString; - _sharedConnection.OpenWithRetry();//Changed .Open() => .OpenWithRetry() extension method - - // ensure we have the proper isolation level, as levels can leak in pools - // read http://stackoverflow.com/questions/9851415/sql-server-isolation-level-leaks-across-pooled-connections - // and http://stackoverflow.com/questions/641120/what-exec-sp-reset-connection-shown-in-sql-profiler-means - // - // NPoco has that code in OpenSharedConnectionImp (commented out?) - //using (var cmd = _sharedConnection.CreateCommand()) - //{ - // cmd.CommandText = GetSqlForTransactionLevel(_isolationLevel); - // cmd.CommandTimeout = CommandTimeout; - // cmd.ExecuteNonQuery(); - //} - // - // although MSDN documentation for SQL CE clearly states that the above method - // should work, it fails & reports an error parsing the query on 'TRANSACTION', - // and Google is no help (others have faced the same issue... no solution). So, - // switching to another method that does work on all databases. - var tr = _sharedConnection.BeginTransaction(_isolationLevel); - tr.Commit(); - tr.Dispose(); - - _sharedConnection = OnConnectionOpened(_sharedConnection); - - if (KeepConnectionAlive) - _sharedConnectionDepth++; // Make sure you call Dispose - } - _sharedConnectionDepth++; - } - - // Close a previously opened connection - public void CloseSharedConnection() - { - if (_sharedConnectionDepth > 0) - { - _sharedConnectionDepth--; - if (_sharedConnectionDepth == 0) - { - OnConnectionClosing(_sharedConnection); - _sharedConnection.Dispose(); - _sharedConnection = null; - } - } - } - - // Access to our shared connection - public IDbConnection Connection - { - get { return _sharedConnection; } - } - - // Helper to create a transaction scope - public Transaction GetTransaction() - { - return GetTransaction(_isolationLevel); - } - - public Transaction GetTransaction(IsolationLevel isolationLevel) - { - return new Transaction(this, isolationLevel); - } - - public IsolationLevel CurrentTransactionIsolationLevel - { - get { return _transaction == null ? IsolationLevel.Unspecified : _transaction.IsolationLevel; } - } - - // Use by derived repo generated by T4 templates - public virtual void OnBeginTransaction() { } - public virtual void OnEndTransaction() { } - - // Start a new transaction, can be nested, every call must be - // matched by a call to AbortTransaction or CompleteTransaction - // Use `using (var scope=db.Transaction) { scope.Complete(); }` to ensure correct semantics - public void BeginTransaction() - { - BeginTransaction(_isolationLevel); - } - - public void BeginTransaction(IsolationLevel isolationLevel) - { - _transactionDepth++; - - if (_transactionDepth == 1) - { - OpenSharedConnection(); - _transaction = _sharedConnection.BeginTransaction(isolationLevel); - _transactionCancelled = false; - OnBeginTransaction(); - } - else if (isolationLevel > _transaction.IsolationLevel) - throw new Exception("Already in a transaction with a lower isolation level."); - } - - // Internal helper to cleanup transaction stuff - void CleanupTransaction() - { - OnEndTransaction(); - - if (_transactionCancelled) - _transaction.Rollback(); - else - _transaction.Commit(); - - _transaction.Dispose(); - _transaction = null; - - CloseSharedConnection(); - } - - // Abort the entire outer most transaction scope - public void AbortTransaction() - { - _transactionCancelled = true; - //TODO what shall we do if transactionDepth is already zero? - if ((--_transactionDepth) == 0) - CleanupTransaction(); - } - - // Complete the transaction - public void CompleteTransaction() - { - //TODO what shall we do if transactionDepth is already zero? - if ((--_transactionDepth) == 0) - CleanupTransaction(); - } - - // in NPoco this is in DatabaseType - private static string GetSqlForTransactionLevel(IsolationLevel isolationLevel) - { - switch (isolationLevel) - { - case IsolationLevel.ReadCommitted: - return "SET TRANSACTION ISOLATION LEVEL READ COMMITTED"; - case IsolationLevel.ReadUncommitted: - return "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"; - case IsolationLevel.RepeatableRead: - return "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"; - case IsolationLevel.Serializable: - return "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"; - case IsolationLevel.Snapshot: - return "SET TRANSACTION ISOLATION LEVEL SNAPSHOT"; - default: - return "SET TRANSACTION ISOLATION LEVEL READ COMMITTED"; - } - } - - // Helper to handle named parameters from object properties - static Regex rxParams = new Regex(@"(? args_dest) - { - return rxParams.Replace(_sql, m => - { - string param = m.Value.Substring(1); - - object arg_val; - - int paramIndex; - if (int.TryParse(param, out paramIndex)) - { - // Numbered parameter - if (paramIndex < 0 || paramIndex >= args_src.Length) - throw new ArgumentOutOfRangeException(string.Format("Parameter '@{0}' specified but only {1} parameters supplied (in `{2}`)", paramIndex, args_src.Length, _sql)); - arg_val = args_src[paramIndex]; - } - else - { - // Look for a property on one of the arguments with this name - bool found = false; - arg_val = null; - foreach (var o in args_src) - { - var pi = o.GetType().GetProperty(param); - if (pi != null) - { - arg_val = pi.GetValue(o, null); - found = true; - break; - } - } - - if (!found) - throw new ArgumentException(string.Format("Parameter '@{0}' specified but none of the passed arguments have a property with this name (in '{1}')", param, _sql)); - } - - // Expand collections to parameter lists - if ((arg_val as System.Collections.IEnumerable) != null && - (arg_val as string) == null && - (arg_val as byte[]) == null) - { - var sb = new StringBuilder(); - foreach (var i in arg_val as System.Collections.IEnumerable) - { - sb.Append((sb.Length == 0 ? "@" : ",@") + args_dest.Count.ToString()); - args_dest.Add(i); - } - return sb.ToString(); - } - else - { - args_dest.Add(arg_val); - return "@" + (args_dest.Count - 1).ToString(); - } - } - ); - } - - // Add a parameter to a DB command - internal void AddParam(IDbCommand cmd, object item, string ParameterPrefix) - { - // Convert value to from poco type to db type - if (Database.Mapper != null && item!=null) - { - var fn = Database.Mapper.GetToDbConverter(item.GetType()); - if (fn!=null) - item = fn(item); - } - - // Support passed in parameters - var idbParam = item as IDbDataParameter; - if (idbParam != null) - { - idbParam.ParameterName = string.Format("{0}{1}", ParameterPrefix, cmd.Parameters.Count); - cmd.Parameters.Add(idbParam); - return; - } - - var p = cmd.CreateParameter(); - p.ParameterName = string.Format("{0}{1}", ParameterPrefix, cmd.Parameters.Count); - if (item == null) - { - p.Value = DBNull.Value; - } - else - { - var t = item.GetType(); - if (t.IsEnum) // PostgreSQL .NET driver wont cast enum to int - { - p.Value = (int)item; - } - else if (t == typeof(Guid)) - { - p.Value = item.ToString(); - p.DbType = DbType.String; - p.Size = 40; - } - else if (t == typeof(string)) - { - // out of memory exception occurs if trying to save more than 4000 characters to SQL Server CE NText column. - //Set before attempting to set Size, or Size will always max out at 4000 - if ((item as string).Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter") - p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null); - - p.Size = (item as string).Length + 1; - if(p.Size < 4000) - p.Size = Math.Max((item as string).Length + 1, 4000); // Help query plan caching by using common size - - p.Value = item; - } - else if (t == typeof(AnsiString)) - { - // Thanks @DataChomp for pointing out the SQL Server indexing performance hit of using wrong string type on varchar - p.Size = Math.Max((item as AnsiString).Value.Length + 1, 4000); - p.Value = (item as AnsiString).Value; - p.DbType = DbType.AnsiString; - } - else if (t == typeof(bool) && _dbType != DBType.PostgreSQL) - { - p.Value = ((bool)item) ? 1 : 0; - } - else if (item.GetType().Name == "SqlGeography") //SqlGeography is a CLR Type - { - p.GetType().GetProperty("UdtTypeName").SetValue(p, "geography", null); //geography is the equivalent SQL Server Type - p.Value = item; - } - - else if (item.GetType().Name == "SqlGeometry") //SqlGeometry is a CLR Type - { - p.GetType().GetProperty("UdtTypeName").SetValue(p, "geometry", null); //geography is the equivalent SQL Server Type - p.Value = item; - } - else - { - p.Value = item; - } - } - - cmd.Parameters.Add(p); - } - - // Create a command - static Regex rxParamsPrefix = new Regex(@"(?(); - sql = ProcessParams(sql, args, new_args); - args = new_args.ToArray(); - } - - // Perform parameter prefix replacements - if (_paramPrefix != "@") - sql = rxParamsPrefix.Replace(sql, m => _paramPrefix + m.Value.Substring(1)); - sql = sql.Replace("@@", "@"); // <- double @@ escapes a single @ - - // Create the command and add parameters - IDbCommand cmd = connection.CreateCommand(); - cmd.Connection = connection; - cmd.CommandText = sql; - cmd.Transaction = _transaction; - foreach (var item in args) - { - AddParam(cmd, item, _paramPrefix); - } - - if (_dbType == DBType.Oracle) - { - cmd.GetType().GetProperty("BindByName").SetValue(cmd, true, null); - } - - if (!String.IsNullOrEmpty(sql)) - DoPreExecute(cmd); - - return cmd; - } - - // Override this to log/capture exceptions - public virtual void OnException(Exception x) - { - System.Diagnostics.Debug.WriteLine(x.ToString()); - System.Diagnostics.Debug.WriteLine(LastCommand); - } - - // Override this to log commands, or modify command before execution - public virtual IDbConnection OnConnectionOpened(IDbConnection conn) { return conn; } - public virtual void OnConnectionClosing(IDbConnection conn) { } - public virtual void OnExecutingCommand(IDbCommand cmd) { } - public virtual void OnExecutedCommand(IDbCommand cmd) { } - - // Execute a non-query command - public int Execute(string sql, params object[] args) - { - try - { - OpenSharedConnection(); - try - { - using (var cmd = CreateCommand(_sharedConnection, sql, args)) - { - var retv=cmd.ExecuteNonQueryWithRetry(); - OnExecutedCommand(cmd); - return retv; - } - } - finally - { - CloseSharedConnection(); - } - } - catch (Exception x) - { - OnException(x); - throw; - } - } - - public int Execute(Sql sql) - { - return Execute(sql.SQL, sql.Arguments); - } - - // Execute and cast a scalar property - public T ExecuteScalar(string sql, params object[] args) - { - try - { - OpenSharedConnection(); - try - { - using (var cmd = CreateCommand(_sharedConnection, sql, args)) - { - object val = cmd.ExecuteScalarWithRetry(); - OnExecutedCommand(cmd); - - if (val == null || val == DBNull.Value) - return default(T); - - Type t = typeof(T); - Type u = Nullable.GetUnderlyingType(t); - - return (T)Convert.ChangeType(val, u ?? t); - } - } - finally - { - CloseSharedConnection(); - } - } - catch (Exception x) - { - OnException(x); - throw; - } - } - - public T ExecuteScalar(Sql sql) - { - return ExecuteScalar(sql.SQL, sql.Arguments); - } - - Regex rxSelect = new Regex(@"\A\s*(SELECT|EXECUTE|CALL)\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline); - Regex rxFrom = new Regex(@"\A\s*FROM\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline); - string AddSelectClause(string sql) - { - if (sql.StartsWith(";")) - return sql.Substring(1); - - if (!rxSelect.IsMatch(sql)) - { - var pd = PocoData.ForType(typeof(T)); - var tableName = EscapeTableName(pd.TableInfo.TableName); - string cols = string.Join(", ", (from c in pd.QueryColumns select tableName + "." + EscapeSqlIdentifier(c)).ToArray()); - if (!rxFrom.IsMatch(sql)) - sql = string.Format("SELECT {0} FROM {1} {2}", cols, tableName, sql); - else - sql = string.Format("SELECT {0} {1}", cols, sql); - } - return sql; - } - - public bool EnableAutoSelect { get; set; } - public bool EnableNamedParams { get; set; } - public bool ForceDateTimesToUtc { get; set; } - - // Return a typed list of pocos - public List Fetch(string sql, params object[] args) - { - return Query(sql, args).ToList(); - } - - public List Fetch(Sql sql) - { - return Fetch(sql.SQL, sql.Arguments); - } - - static Regex rxColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); - static Regex rxDistinct = new Regex(@"\ADISTINCT\s", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); - public static bool SplitSqlForPaging(string sql, out string sqlCount, out string sqlSelectRemoved, out string sqlOrderBy) - { - sqlSelectRemoved = null; - sqlCount = null; - sqlOrderBy = null; - - // Extract the columns from "SELECT FROM" - var m = rxColumns.Match(sql); - if (!m.Success) - return false; - - // Save column list and replace with COUNT(*) - Group g = m.Groups[1]; - sqlSelectRemoved = sql.Substring(g.Index); - - if (rxDistinct.IsMatch(sqlSelectRemoved)) - sqlCount = sql.Substring(0, g.Index) + "COUNT(" + m.Groups[1].ToString().Trim() + ") " + sql.Substring(g.Index + g.Length); - else - sqlCount = sql.Substring(0, g.Index) + "COUNT(*) " + sql.Substring(g.Index + g.Length); - - - // Look for an "ORDER BY " clause - m = rxOrderBy.Match(sqlCount); - if (!m.Success) - { - sqlOrderBy = null; - } - else - { - g = m.Groups[0]; - sqlOrderBy = g.ToString(); - sqlCount = sqlCount.Substring(0, g.Index) + sqlCount.Substring(g.Index + g.Length); - } - - return true; - } - - public void BuildPageQueries(long skip, long take, string sql, ref object[] args, out string sqlCount, out string sqlPage) - { - // Add auto select clause - if (EnableAutoSelect) - sql = AddSelectClause(sql); - - // Split the SQL into the bits we need - string sqlSelectRemoved, sqlOrderBy; - if (!SplitSqlForPaging(sql, out sqlCount, out sqlSelectRemoved, out sqlOrderBy)) - throw new Exception("Unable to parse SQL statement for paged query"); - if (_dbType == DBType.Oracle && sqlSelectRemoved.StartsWith("*")) - throw new Exception("Query must alias '*' when performing a paged query.\neg. select t.* from table t order by t.id"); - - // Build the SQL for the actual final result - if (_dbType == DBType.SqlServer || _dbType == DBType.Oracle) - { - sqlSelectRemoved = rxOrderBy.Replace(sqlSelectRemoved, ""); - if (rxDistinct.IsMatch(sqlSelectRemoved)) - { - sqlSelectRemoved = "peta_inner.* FROM (SELECT " + sqlSelectRemoved + ") peta_inner"; - } - sqlPage = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn>@{2} AND peta_rn<=@{3}", - sqlOrderBy==null ? "ORDER BY (SELECT NULL)" : sqlOrderBy, sqlSelectRemoved, args.Length, args.Length + 1); - args = args.Concat(new object[] { skip, skip+take }).ToArray(); - } - else if (_dbType == DBType.SqlServerCE) - { - sqlPage = string.Format("{0}\nOFFSET @{1} ROWS FETCH NEXT @{2} ROWS ONLY", sql, args.Length, args.Length + 1); - args = args.Concat(new object[] { skip, take }).ToArray(); - } - else - { - sqlPage = string.Format("{0}\nLIMIT @{1} OFFSET @{2}", sql, args.Length, args.Length + 1); - args = args.Concat(new object[] { take, skip }).ToArray(); - } - - } - - // Fetch a page - public Page Page(long page, long itemsPerPage, string sql, params object[] args) - { - string sqlCount, sqlPage; - BuildPageQueries((page-1)*itemsPerPage, itemsPerPage, sql, ref args, out sqlCount, out sqlPage); - - // Save the one-time command time out and use it for both queries - int saveTimeout = OneTimeCommandTimeout; - - // Setup the paged result - var result = new Page(); - result.CurrentPage = page; - result.ItemsPerPage = itemsPerPage; - result.TotalItems = ExecuteScalar(sqlCount, args); - result.TotalPages = result.TotalItems / itemsPerPage; - if ((result.TotalItems % itemsPerPage) != 0) - result.TotalPages++; - - OneTimeCommandTimeout = saveTimeout; - - // Get the records - result.Items = Fetch(sqlPage, args); - - // Done - return result; - } - - public Page Page(long page, long itemsPerPage, Sql sql) - { - return Page(page, itemsPerPage, sql.SQL, sql.Arguments); - } - - - public List Fetch(long page, long itemsPerPage, string sql, params object[] args) - { - return SkipTake((page - 1) * itemsPerPage, itemsPerPage, sql, args); - } - - public List Fetch(long page, long itemsPerPage, Sql sql) - { - return SkipTake((page - 1) * itemsPerPage, itemsPerPage, sql.SQL, sql.Arguments); - } - - public List SkipTake(long skip, long take, string sql, params object[] args) - { - string sqlCount, sqlPage; - BuildPageQueries(skip, take, sql, ref args, out sqlCount, out sqlPage); - return Fetch(sqlPage, args); - } - - public List SkipTake(long skip, long take, Sql sql) - { - return SkipTake(skip, take, sql.SQL, sql.Arguments); - } - - // Return an enumerable collection of pocos - public IEnumerable Query(string sql, params object[] args) - { - if (EnableAutoSelect) - sql = AddSelectClause(sql); - - OpenSharedConnection(); - try - { - using (var cmd = CreateCommand(_sharedConnection, sql, args)) - { - IDataReader r; - var pd = PocoData.ForType(typeof(T)); - try - { - r = cmd.ExecuteReaderWithRetry(); - OnExecutedCommand(cmd); - } - catch (Exception x) - { - OnException(x); - throw; - } - var factory = pd.GetFactory(cmd.CommandText, _sharedConnection.ConnectionString, ForceDateTimesToUtc, 0, r.FieldCount, r) as Func; - using (r) - { - while (true) - { - T poco; - try - { - if (!r.Read()) - yield break; - poco = factory(r); - } - catch (Exception x) - { - OnException(x); - throw; - } - - yield return poco; - } - } - } - } - finally - { - CloseSharedConnection(); - } - } - - // Multi Fetch - public List Fetch(Func cb, string sql, params object[] args) { return Query(cb, sql, args).ToList(); } - public List Fetch(Func cb, string sql, params object[] args) { return Query(cb, sql, args).ToList(); } - public List Fetch(Func cb, string sql, params object[] args) { return Query(cb, sql, args).ToList(); } - public List Fetch(Func cb, string sql, params object[] args) { return Query(cb, sql, args).ToList(); } - - // Multi Query - public IEnumerable Query(Func cb, string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2) }, cb, sql, args); } - public IEnumerable Query(Func cb, string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3)}, cb, sql, args); } - public IEnumerable Query(Func cb, string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4)}, cb, sql, args); } - public IEnumerable Query(Func cb, string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, cb, sql, args); } - - // Multi Fetch (SQL builder) - public List Fetch(Func cb, Sql sql) { return Query(cb, sql.SQL, sql.Arguments).ToList(); } - public List Fetch(Func cb, Sql sql) { return Query(cb, sql.SQL, sql.Arguments).ToList(); } - public List Fetch(Func cb, Sql sql) { return Query(cb, sql.SQL, sql.Arguments).ToList(); } - public List Fetch(Func cb, Sql sql) { return Query(cb, sql.SQL, sql.Arguments).ToList(); } - - // Multi Query (SQL builder) - public IEnumerable Query(Func cb, Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2) }, cb, sql.SQL, sql.Arguments); } - public IEnumerable Query(Func cb, Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, cb, sql.SQL, sql.Arguments); } - public IEnumerable Query(Func cb, Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, cb, sql.SQL, sql.Arguments); } - public IEnumerable Query(Func cb, Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, cb, sql.SQL, sql.Arguments); } - - // Multi Fetch (Simple) - public List Fetch(string sql, params object[] args) { return Query(sql, args).ToList(); } - public List Fetch(string sql, params object[] args) { return Query(sql, args).ToList(); } - public List Fetch(string sql, params object[] args) { return Query(sql, args).ToList(); } - public List Fetch(string sql, params object[] args) { return Query(sql, args).ToList(); } - - // Multi Query (Simple) - public IEnumerable Query(string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2) }, null, sql, args); } - public IEnumerable Query(string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null, sql, args); } - public IEnumerable Query(string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null, sql, args); } - public IEnumerable Query(string sql, params object[] args) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, null, sql, args); } - - // Multi Fetch (Simple) (SQL builder) - public List Fetch(Sql sql) { return Query(sql.SQL, sql.Arguments).ToList(); } - public List Fetch(Sql sql) { return Query(sql.SQL, sql.Arguments).ToList(); } - public List Fetch(Sql sql) { return Query(sql.SQL, sql.Arguments).ToList(); } - public List Fetch(Sql sql) { return Query(sql.SQL, sql.Arguments).ToList(); } - - // Multi Query (Simple) (SQL builder) - public IEnumerable Query(Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2) }, null, sql.SQL, sql.Arguments); } - public IEnumerable Query(Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null, sql.SQL, sql.Arguments); } - public IEnumerable Query(Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null, sql.SQL, sql.Arguments); } - public IEnumerable Query(Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, null, sql.SQL, sql.Arguments); } - - // Automagically guess the property relationships between various POCOs and create a delegate that will set them up - Delegate GetAutoMapper(Type[] types) - { - // Build a key - var kb = new StringBuilder(); - foreach (var t in types) - { - kb.Append(t.ToString()); - kb.Append(":"); - } - var key = kb.ToString(); - - // Check cache - RWLock.EnterReadLock(); - try - { - Delegate mapper; - if (AutoMappers.TryGetValue(key, out mapper)) - return mapper; - } - finally - { - RWLock.ExitReadLock(); - } - - // Create it - RWLock.EnterWriteLock(); - try - { - // Try again - Delegate mapper; - if (AutoMappers.TryGetValue(key, out mapper)) - return mapper; - - // Create a method - var m = new DynamicMethod("petapoco_automapper", types[0], types, true); - var il = m.GetILGenerator(); - - for (int i = 1; i < types.Length; i++) - { - bool handled = false; - for (int j = i - 1; j >= 0; j--) - { - // Find the property - var candidates = from p in types[j].GetProperties() where p.PropertyType == types[i] select p; - if (candidates.Any() == false) - continue; - if (candidates.Count() > 1) - throw new InvalidOperationException(string.Format("Can't auto join {0} as {1} has more than one property of type {0}", types[i], types[j])); - - // Generate code - il.Emit(OpCodes.Ldarg_S, j); - il.Emit(OpCodes.Ldarg_S, i); - il.Emit(OpCodes.Callvirt, candidates.First().GetSetMethod(true)); - handled = true; - } - - if (!handled) - throw new InvalidOperationException(string.Format("Can't auto join {0}", types[i])); - } - - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ret); - - // Cache it - var del = m.CreateDelegate(Expression.GetFuncType(types.Concat(types.Take(1)).ToArray())); - AutoMappers.Add(key, del); - return del; - } - finally - { - RWLock.ExitWriteLock(); - } - } - - // Find the split point in a result set for two different pocos and return the poco factory for the first - Delegate FindSplitPoint(Type typeThis, Type typeNext, string sql, IDataReader r, ref int pos) - { - // Last? - if (typeNext == null) - return PocoData.ForType(typeThis).GetFactory(sql, _sharedConnection.ConnectionString, ForceDateTimesToUtc, pos, r.FieldCount - pos, r); - - // Get PocoData for the two types - PocoData pdThis = PocoData.ForType(typeThis); - PocoData pdNext = PocoData.ForType(typeNext); - - // Find split point - int firstColumn = pos; - var usedColumns = new Dictionary(); - for (; pos < r.FieldCount; pos++) - { - // Split if field name has already been used, or if the field doesn't exist in current poco but does in the next - string fieldName = r.GetName(pos); - if (usedColumns.ContainsKey(fieldName) || (!pdThis.Columns.ContainsKey(fieldName) && pdNext.Columns.ContainsKey(fieldName))) - { - return pdThis.GetFactory(sql, _sharedConnection.ConnectionString, ForceDateTimesToUtc, firstColumn, pos - firstColumn, r); - } - usedColumns.Add(fieldName, true); - } - - throw new InvalidOperationException(string.Format("Couldn't find split point between {0} and {1}", typeThis, typeNext)); - } - - - // Instance data used by the Multipoco factory delegate - essentially a list of the nested poco factories to call - public class MultiPocoFactory - { - - public MultiPocoFactory(IEnumerable dels) - { - Delegates = new List(dels); - } - private List Delegates { get; set; } - private Delegate GetItem(int index) { return Delegates[index]; } - - /// - /// Calls the delegate at the specified index and returns its values - /// - /// - /// - /// - private object CallDelegate(int index, IDataReader reader) - { - var d = GetItem(index); - var output = d.DynamicInvoke(reader); - return output; - } - - /// - /// Calls the callback delegate and passes in the output of all delegates as the parameters - /// - /// - /// - /// - /// - /// - public TRet CallCallback(Delegate callback, IDataReader dr, int count) - { - var args = new List(); - for(var i = 0;i CreateMultiPocoFactory(Type[] types, string sql, IDataReader r) - { - // Call each delegate - var dels = new List(); - int pos = 0; - for (int i=0; i mpFactory.CallCallback(arg3, reader, types.Length); - } - - // Various cached stuff - static Dictionary MultiPocoFactories = new Dictionary(); - static Dictionary AutoMappers = new Dictionary(); - static System.Threading.ReaderWriterLockSlim RWLock = new System.Threading.ReaderWriterLockSlim(); - - // Get (or create) the multi-poco factory for a query - Func GetMultiPocoFactory(Type[] types, string sql, IDataReader r) - { - // Build a key string (this is crap, should address this at some point) - var kb = new StringBuilder(); - kb.Append(typeof(TRet).ToString()); - kb.Append(":"); - foreach (var t in types) - { - kb.Append(":"); - kb.Append(t.ToString()); - } - kb.Append(":"); kb.Append(_sharedConnection.ConnectionString); - kb.Append(":"); kb.Append(ForceDateTimesToUtc); - kb.Append(":"); kb.Append(sql); - string key = kb.ToString(); - - // Check cache - RWLock.EnterReadLock(); - try - { - object oFactory; - if (MultiPocoFactories.TryGetValue(key, out oFactory)) - { - //mpFactory = oFactory; - return (Func)oFactory; - } - } - finally - { - RWLock.ExitReadLock(); - } - - // Cache it - RWLock.EnterWriteLock(); - try - { - // Check again - object oFactory; ; - if (MultiPocoFactories.TryGetValue(key, out oFactory)) - { - return (Func)oFactory; - } - - // Create the factory - var factory = CreateMultiPocoFactory(types, sql, r); - - MultiPocoFactories.Add(key, factory); - return factory; - } - finally - { - RWLock.ExitWriteLock(); - } - - } - - // Actual implementation of the multi-poco query - public IEnumerable Query(Type[] types, Delegate cb, string sql, params object[] args) - { - OpenSharedConnection(); - try - { - using (var cmd = CreateCommand(_sharedConnection, sql, args)) - { - IDataReader r; - try - { - r = cmd.ExecuteReaderWithRetry(); - OnExecutedCommand(cmd); - } - catch (Exception x) - { - OnException(x); - throw; - } - var factory = GetMultiPocoFactory(types, sql, r); - if (cb == null) - cb = GetAutoMapper(types.ToArray()); - bool bNeedTerminator=false; - using (r) - { - while (true) - { - TRet poco; - try - { - if (!r.Read()) - break; - poco = factory(r, cb); - } - catch (Exception x) - { - OnException(x); - throw; - } - - if (poco != null) - yield return poco; - else - bNeedTerminator = true; - } - if (bNeedTerminator) - { - var poco = (TRet)(cb as Delegate).DynamicInvoke(new object[types.Length]); - if (poco != null) - yield return poco; - else - yield break; - } - } - } - } - finally - { - CloseSharedConnection(); - } - } - - - public IEnumerable Query(Sql sql) - { - return Query(sql.SQL, sql.Arguments); - } - - public bool Exists(object primaryKey) - { - return FirstOrDefault(string.Format("WHERE {0}=@0", EscapeSqlIdentifier(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey)), primaryKey) != null; - } - public T Single(object primaryKey) - { - return Single(string.Format("WHERE {0}=@0", EscapeSqlIdentifier(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey)), primaryKey); - } - public T SingleOrDefault(object primaryKey) - { - return SingleOrDefault(string.Format("WHERE {0}=@0", EscapeSqlIdentifier(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey)), primaryKey); - } - public T Single(string sql, params object[] args) - { - return Query(sql, args).Single(); - } - public T SingleOrDefault(string sql, params object[] args) - { - return Query(sql, args).SingleOrDefault(); - } - public T First(string sql, params object[] args) - { - return Query(sql, args).First(); - } - public T FirstOrDefault(string sql, params object[] args) - { - return Query(sql, args).FirstOrDefault(); - } - - public T Single(Sql sql) - { - return Query(sql).Single(); - } - public T SingleOrDefault(Sql sql) - { - return Query(sql).SingleOrDefault(); - } - public T First(Sql sql) - { - return Query(sql).First(); - } - public T FirstOrDefault(Sql sql) - { - return Query(sql).FirstOrDefault(); - } - - public string EscapeTableName(string str) - { - // Assume table names with "dot", or opening sq is already escaped - return str.IndexOf('.') >= 0 ? str : EscapeSqlIdentifier(str); - } - public string EscapeSqlIdentifier(string str) - { - switch (_dbType) - { - case DBType.MySql: - return string.Format("`{0}`", str); - - case DBType.PostgreSQL: - case DBType.Oracle: - return string.Format("\"{0}\"", str); - - default: - return string.Format("[{0}]", str); - } - } - - public object Insert(string tableName, string primaryKeyName, object poco) - { - return Insert(tableName, primaryKeyName, true, poco); - } - - // Insert a poco into a table. If the poco has a property with the same name - // as the primary key the id of the new record is assigned to it. Either way, - // the new id is returned. - public object Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco) - { - try - { - OpenSharedConnection(); - try - { - using (var cmd = CreateCommand(_sharedConnection, "")) - { - var pd = PocoData.ForObject(poco, primaryKeyName); - var names = new List(); - var values = new List(); - var index = 0; - foreach (var i in pd.Columns) - { - // Don't insert result columns - if (i.Value.ResultColumn) - continue; - - // Don't insert the primary key (except under oracle where we need bring in the next sequence value) - if (autoIncrement && primaryKeyName != null && string.Compare(i.Key, primaryKeyName, true)==0) - { - if (_dbType == DBType.Oracle && !string.IsNullOrEmpty(pd.TableInfo.SequenceName)) - { - names.Add(i.Key); - values.Add(string.Format("{0}.nextval", pd.TableInfo.SequenceName)); - } - continue; - } - - names.Add(EscapeSqlIdentifier(i.Key)); - values.Add(string.Format("{0}{1}", _paramPrefix, index++)); - AddParam(cmd, i.Value.GetValue(poco), _paramPrefix); - } - - cmd.CommandText = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", - EscapeTableName(tableName), - string.Join(",", names.ToArray()), - string.Join(",", values.ToArray()) - ); - - if (!autoIncrement) - { - DoPreExecute(cmd); - cmd.ExecuteNonQueryWithRetry(); - OnExecutedCommand(cmd); - return true; - } - - - object id; - switch (_dbType) - { - case DBType.SqlServerCE: - DoPreExecute(cmd); - cmd.ExecuteNonQueryWithRetry(); - OnExecutedCommand(cmd); - id = ExecuteScalar("SELECT @@@IDENTITY AS NewID;"); - break; - case DBType.SqlServer: - cmd.CommandText += ";\nSELECT SCOPE_IDENTITY() AS NewID;"; - DoPreExecute(cmd); - id = cmd.ExecuteScalarWithRetry(); - OnExecutedCommand(cmd); - break; - case DBType.PostgreSQL: - if (primaryKeyName != null) - { - cmd.CommandText += string.Format("returning {0} as NewID", EscapeSqlIdentifier(primaryKeyName)); - DoPreExecute(cmd); - id = cmd.ExecuteScalarWithRetry(); - } - else - { - id = -1; - DoPreExecute(cmd); - cmd.ExecuteNonQueryWithRetry(); - } - OnExecutedCommand(cmd); - break; - case DBType.Oracle: - if (primaryKeyName != null) - { - cmd.CommandText += string.Format(" returning {0} into :newid", EscapeSqlIdentifier(primaryKeyName)); - var param = cmd.CreateParameter(); - param.ParameterName = ":newid"; - param.Value = DBNull.Value; - param.Direction = ParameterDirection.ReturnValue; - param.DbType = DbType.Int64; - cmd.Parameters.Add(param); - DoPreExecute(cmd); - cmd.ExecuteNonQueryWithRetry(); - id = param.Value; - } - else - { - id = -1; - DoPreExecute(cmd); - cmd.ExecuteNonQueryWithRetry(); - } - OnExecutedCommand(cmd); - break; - case DBType.SQLite: - if (primaryKeyName != null) - { - cmd.CommandText += ";\nSELECT last_insert_rowid();"; - DoPreExecute(cmd); - id = cmd.ExecuteScalarWithRetry(); - } - else - { - id = -1; - DoPreExecute(cmd); - cmd.ExecuteNonQueryWithRetry(); - } - OnExecutedCommand(cmd); - break; - default: - cmd.CommandText += ";\nSELECT @@IDENTITY AS NewID;"; - DoPreExecute(cmd); - id = cmd.ExecuteScalarWithRetry(); - OnExecutedCommand(cmd); - break; - } - - - // Assign the ID back to the primary key property - if (primaryKeyName != null) - { - PocoColumn pc; - if (pd.Columns.TryGetValue(primaryKeyName, out pc)) - { - pc.SetValue(poco, pc.ChangeType(id)); - } - } - - return id; - } - } - finally - { - CloseSharedConnection(); - } - } - catch (Exception x) - { - OnException(x); - throw; - } - } - - // Insert an annotated poco object - public object Insert(object poco) - { - var pd = PocoData.ForType(poco.GetType()); - return Insert(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, pd.TableInfo.AutoIncrement, poco); - } - - public int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue) - { - return Update(tableName, primaryKeyName, poco, primaryKeyValue, null); - } - - - // Update a record with values from a poco. primary key value can be either supplied or read from the poco - public int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable columns) - { - try - { - OpenSharedConnection(); - try - { - using (var cmd = CreateCommand(_sharedConnection, "")) - { - var sb = new StringBuilder(); - var index = 0; - var pd = PocoData.ForObject(poco,primaryKeyName); - if (columns == null) - { - foreach (var i in pd.Columns) - { - // Don't update the primary key, but grab the value if we don't have it - if (string.Compare(i.Key, primaryKeyName, true) == 0) - { - if (primaryKeyValue == null) - primaryKeyValue = i.Value.GetValue(poco); - continue; - } - - // Dont update result only columns - if (i.Value.ResultColumn) - continue; - - // Build the sql - if (index > 0) - sb.Append(", "); - sb.AppendFormat("{0} = {1}{2}", EscapeSqlIdentifier(i.Key), _paramPrefix, index++); - - // Store the parameter in the command - AddParam(cmd, i.Value.GetValue(poco), _paramPrefix); - } - } - else - { - foreach (var colname in columns) - { - var pc = pd.Columns[colname]; - - // Build the sql - if (index > 0) - sb.Append(", "); - sb.AppendFormat("{0} = {1}{2}", EscapeSqlIdentifier(colname), _paramPrefix, index++); - - // Store the parameter in the command - AddParam(cmd, pc.GetValue(poco), _paramPrefix); - } - - // Grab primary key value - if (primaryKeyValue == null) - { - var pc = pd.Columns[primaryKeyName]; - primaryKeyValue = pc.GetValue(poco); - } - - } - - cmd.CommandText = string.Format("UPDATE {0} SET {1} WHERE {2} = {3}{4}", - EscapeTableName(tableName), sb.ToString(), EscapeSqlIdentifier(primaryKeyName), _paramPrefix, index++); - AddParam(cmd, primaryKeyValue, _paramPrefix); - - DoPreExecute(cmd); - - // Do it - var retv=cmd.ExecuteNonQueryWithRetry(); - OnExecutedCommand(cmd); - return retv; - } - } - finally - { - CloseSharedConnection(); - } - } - catch (Exception x) - { - OnException(x); - throw; - } - } - - public int Update(string tableName, string primaryKeyName, object poco) - { - return Update(tableName, primaryKeyName, poco, null); - } - - public int Update(string tableName, string primaryKeyName, object poco, IEnumerable columns) - { - return Update(tableName, primaryKeyName, poco, null, columns); - } - - public int Update(object poco, IEnumerable columns) - { - return Update(poco, null, columns); - } - - public int Update(object poco) - { - return Update(poco, null, null); - } - - public int Update(object poco, object primaryKeyValue) - { - return Update(poco, primaryKeyValue, null); - } - public int Update(object poco, object primaryKeyValue, IEnumerable columns) - { - var pd = PocoData.ForType(poco.GetType()); - return Update(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, poco, primaryKeyValue, columns); - } - - public int Update(string sql, params object[] args) - { - var pd = PocoData.ForType(typeof(T)); - return Execute(string.Format("UPDATE {0} {1}", EscapeTableName(pd.TableInfo.TableName), sql), args); - } - - public int Update(Sql sql) - { - var pd = PocoData.ForType(typeof(T)); - return Execute(new Sql(string.Format("UPDATE {0}", EscapeTableName(pd.TableInfo.TableName))).Append(sql)); - } - - public int Delete(string tableName, string primaryKeyName, object poco) - { - return Delete(tableName, primaryKeyName, poco, null); - } - - public int Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue) - { - // If primary key value not specified, pick it up from the object - if (primaryKeyValue == null) - { - var pd = PocoData.ForObject(poco,primaryKeyName); - PocoColumn pc; - if (pd.Columns.TryGetValue(primaryKeyName, out pc)) - { - primaryKeyValue = pc.GetValue(poco); - } - } - - // Do it - var sql = string.Format("DELETE FROM {0} WHERE {1}=@0", EscapeTableName(tableName), EscapeSqlIdentifier(primaryKeyName)); - return Execute(sql, primaryKeyValue); - } - - public int Delete(object poco) - { - var pd = PocoData.ForType(poco.GetType()); - return Delete(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, poco); - } - - public int Delete(object pocoOrPrimaryKey) - { - if (pocoOrPrimaryKey.GetType() == typeof(T)) - return Delete(pocoOrPrimaryKey); - var pd = PocoData.ForType(typeof(T)); - return Delete(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, null, pocoOrPrimaryKey); - } - - public int Delete(string sql, params object[] args) - { - var pd = PocoData.ForType(typeof(T)); - return Execute(string.Format("DELETE FROM {0} {1}", EscapeTableName(pd.TableInfo.TableName), sql), args); - } - - public int Delete(Sql sql) - { - var pd = PocoData.ForType(typeof(T)); - return Execute(new Sql(string.Format("DELETE FROM {0}", EscapeTableName(pd.TableInfo.TableName))).Append(sql)); - } - - // Check if a poco represents a new record - public bool IsNew(string primaryKeyName, object poco) - { - var pd = PocoData.ForObject(poco, primaryKeyName); - object pk; - PocoColumn pc; - if (pd.Columns.TryGetValue(primaryKeyName, out pc)) - { - pk = pc.GetValue(poco); - } -#if !PETAPOCO_NO_DYNAMIC - else if (poco.GetType() == typeof(System.Dynamic.ExpandoObject)) - { - return true; - } -#endif - else - { - var pi = poco.GetType().GetProperty(primaryKeyName); - if (pi == null) - throw new ArgumentException(string.Format("The object doesn't have a property matching the primary key column name '{0}'", primaryKeyName)); - pk = pi.GetValue(poco, null); - } - - if (pk == null) - return true; - - var type = pk.GetType(); - - if (type.IsValueType) - { - // Common primary key types - if (type == typeof(long)) - return (long)pk == 0; - else if (type == typeof(ulong)) - return (ulong)pk == 0; - else if (type == typeof(int)) - return (int)pk == 0; - else if (type == typeof(uint)) - return (uint)pk == 0; - - // Create a default instance and compare - return pk == Activator.CreateInstance(pk.GetType()); - } - else - { - return pk == null; - } - } - - public bool IsNew(object poco) - { - var pd = PocoData.ForType(poco.GetType()); - if (!pd.TableInfo.AutoIncrement) - throw new InvalidOperationException("IsNew() and Save() are only supported on tables with auto-increment/identity primary key columns"); - return IsNew(pd.TableInfo.PrimaryKey, poco); - } - - // Insert new record or Update existing record - public void Save(string tableName, string primaryKeyName, object poco) - { - if (IsNew(primaryKeyName, poco)) - { - Insert(tableName, primaryKeyName, true, poco); - } - else - { - Update(tableName, primaryKeyName, poco); - } - } - - public void Save(object poco) - { - var pd = PocoData.ForType(poco.GetType()); - Save(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, poco); - } - - public int CommandTimeout { get; set; } - public int OneTimeCommandTimeout { get; set; } - - void DoPreExecute(IDbCommand cmd) - { - // Setup command timeout - if (OneTimeCommandTimeout != 0) - { - cmd.CommandTimeout = OneTimeCommandTimeout; - OneTimeCommandTimeout = 0; - } - else if (CommandTimeout!=0) - { - cmd.CommandTimeout = CommandTimeout; - } - - // Call hook - OnExecutingCommand(cmd); - - // Save it - _lastSql = cmd.CommandText; - _lastArgs = (from IDataParameter parameter in cmd.Parameters select parameter.Value).ToArray(); - } - - public string LastSQL { get { return _lastSql; } } - public object[] LastArgs { get { return _lastArgs; } } - public string LastCommand - { - get { return FormatCommand(_lastSql, _lastArgs); } - } - - public string FormatCommand(IDbCommand cmd) - { - return FormatCommand(cmd.CommandText, (from IDataParameter parameter in cmd.Parameters select parameter.Value).ToArray()); - } - - public string FormatCommand(string sql, object[] args) - { - var sb = new StringBuilder(); - if (sql == null) - return ""; - sb.Append(sql); - if (args != null && args.Length > 0) - { - sb.Append("\n"); - for (int i = 0; i < args.Length; i++) - { - sb.AppendFormat("\t -> {0}{1} [{2}] = \"{3}\"\n", _paramPrefix, i, args[i].GetType().Name, args[i]); - } - sb.Remove(sb.Length - 1, 1); - } - return sb.ToString(); - } - - - public static IMapper Mapper - { - get; - set; - } - - public class PocoColumn - { - public string ColumnName; - public PropertyInfo PropertyInfo; - public bool ResultColumn; - public virtual void SetValue(object target, object val) { PropertyInfo.SetValue(target, val, null); } - public virtual object GetValue(object target) { return PropertyInfo.GetValue(target, null); } - public virtual object ChangeType(object val) { return Convert.ChangeType(val, PropertyInfo.PropertyType); } - } - public class ExpandoColumn : PocoColumn - { - public override void SetValue(object target, object val) { (target as IDictionary)[ColumnName]=val; } - public override object GetValue(object target) - { - object val=null; - (target as IDictionary).TryGetValue(ColumnName, out val); - return val; - } - public override object ChangeType(object val) { return val; } - } - - /// - /// Container for a Memory cache object - /// - /// - /// Better to have one memory cache instance than many so it's memory management can be handled more effectively - /// http://stackoverflow.com/questions/8463962/using-multiple-instances-of-memorycache - /// - internal class ManagedCache - { - public ObjectCache GetCache() - { - return ObjectCache; - } - - static readonly ObjectCache ObjectCache = new MemoryCache("NPoco"); - - } - - public class PocoData - { - //USE ONLY FOR TESTING - internal static bool UseLongKeys = false; - //USE ONLY FOR TESTING - default is one hr - internal static int SlidingExpirationSeconds = 3600; - - public static PocoData ForObject(object o, string primaryKeyName) - { - var t = o.GetType(); -#if !PETAPOCO_NO_DYNAMIC - if (t == typeof(System.Dynamic.ExpandoObject)) - { - var pd = new PocoData(); - pd.TableInfo = new TableInfo(); - pd.Columns = new Dictionary(StringComparer.OrdinalIgnoreCase); - pd.Columns.Add(primaryKeyName, new ExpandoColumn() { ColumnName = primaryKeyName }); - pd.TableInfo.PrimaryKey = primaryKeyName; - pd.TableInfo.AutoIncrement = true; - foreach (var col in (o as IDictionary).Keys) - { - if (col!=primaryKeyName) - pd.Columns.Add(col, new ExpandoColumn() { ColumnName = col }); - } - return pd; - } - else -#endif - return ForType(t); - } - - public static PocoData ForType(Type t) - { -#if !PETAPOCO_NO_DYNAMIC - if (t == typeof(System.Dynamic.ExpandoObject)) - throw new InvalidOperationException("Can't use dynamic types with this method"); -#endif - // Check cache - InnerLock.EnterReadLock(); - PocoData pd; - try - { - if (m_PocoDatas.TryGetValue(t, out pd)) - return pd; - } - finally - { - InnerLock.ExitReadLock(); - } - - - // Cache it - InnerLock.EnterWriteLock(); - try - { - // Check again - if (m_PocoDatas.TryGetValue(t, out pd)) - return pd; - - // Create it - pd = new PocoData(t); - - m_PocoDatas.Add(t, pd); - } - finally - { - InnerLock.ExitWriteLock(); - } - - return pd; - } - - public PocoData() - { - } - - public PocoData(Type t) - { - type = t; - TableInfo=new TableInfo(); - - // Get the table name - var a = t.GetCustomAttributes(typeof(TableNameAttribute), true); - TableInfo.TableName = a.Length == 0 ? t.Name : (a[0] as TableNameAttribute).Value; - - // Get the primary key - a = t.GetCustomAttributes(typeof(PrimaryKeyAttribute), true); - TableInfo.PrimaryKey = a.Length == 0 ? "ID" : (a[0] as PrimaryKeyAttribute).Value; - TableInfo.SequenceName = a.Length == 0 ? null : (a[0] as PrimaryKeyAttribute).sequenceName; - TableInfo.AutoIncrement = a.Length == 0 ? false : (a[0] as PrimaryKeyAttribute).autoIncrement; - - // Call column mapper - if (Database.Mapper != null) - Database.Mapper.GetTableInfo(t, TableInfo); - - // Work out bound properties - bool ExplicitColumns = t.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Length > 0; - Columns = new Dictionary(StringComparer.OrdinalIgnoreCase); - - foreach (var pi in t.GetProperties()) - { - // Work out if properties is to be included - var ColAttrs = pi.GetCustomAttributes(typeof(ColumnAttribute), true); - if (ExplicitColumns) - { - if (ColAttrs.Length == 0) - continue; - } - else - { - if (pi.GetCustomAttributes(typeof(IgnoreAttribute), true).Length != 0) - continue; - } - - var pc = new PocoColumn(); - pc.PropertyInfo = pi; - - // Work out the DB column name - if (ColAttrs.Length > 0) - { - var colattr = (ColumnAttribute)ColAttrs[0]; - pc.ColumnName = colattr.Name; - if ((colattr as ResultColumnAttribute) != null) - pc.ResultColumn = true; - } - if (pc.ColumnName == null) - { - pc.ColumnName = pi.Name; - if (Database.Mapper != null && !Database.Mapper.MapPropertyToColumn(t, pi, ref pc.ColumnName, ref pc.ResultColumn)) - continue; - } - - // Store it - Columns.Add(pc.ColumnName, pc); - } - - // Build column list for automatic select - QueryColumns = (from c in Columns where !c.Value.ResultColumn select c.Key).ToArray(); - - } - - static bool IsIntegralType(Type t) - { - var tc = Type.GetTypeCode(t); - return tc >= TypeCode.SByte && tc <= TypeCode.UInt64; - } - - - - // Create factory function that can convert a IDataReader record into a POCO - public Delegate GetFactory(string sql, string connString, bool ForceDateTimesToUtc, int firstColumn, int countColumns, IDataReader r) - { - - //TODO: It would be nice to remove the irrelevant SQL parts - for a mapping operation anything after the SELECT clause isn't required. - // This would ensure less duplicate entries that get cached, currently both of these queries would be cached even though they are - // returning the same structured data: - // SELECT * FROM MyTable ORDER BY MyColumn - // SELECT * FROM MyTable ORDER BY MyColumn DESC - - string key; - if (UseLongKeys) - { - key = string.Format("{0}:{1}:{2}:{3}:{4}", sql, connString, ForceDateTimesToUtc, firstColumn, countColumns); - } - else - { - //Create a hashed key, we don't want to store so much string data in memory - var combiner = new HashCodeCombiner(); - combiner.AddCaseInsensitiveString(sql); - combiner.AddCaseInsensitiveString(connString); - combiner.AddObject(ForceDateTimesToUtc); - combiner.AddInt(firstColumn); - combiner.AddInt(countColumns); - key = combiner.GetCombinedHashCode(); - } - - - var objectCache = _managedCache.GetCache(); - - Func factory = () => - { - // Create the method - var m = new DynamicMethod("petapoco_factory_" + objectCache.GetCount(), type, new Type[] { typeof(IDataReader) }, true); - var il = m.GetILGenerator(); - -#if !PETAPOCO_NO_DYNAMIC - if (type == typeof(object)) - { - // var poco=new T() - il.Emit(OpCodes.Newobj, typeof(System.Dynamic.ExpandoObject).GetConstructor(Type.EmptyTypes)); // obj - - MethodInfo fnAdd = typeof(IDictionary).GetMethod("Add"); - - // Enumerate all fields generating a set assignment for the column - for (int i = firstColumn; i < firstColumn + countColumns; i++) - { - var srcType = r.GetFieldType(i); - - il.Emit(OpCodes.Dup); // obj, obj - il.Emit(OpCodes.Ldstr, r.GetName(i)); // obj, obj, fieldname - - // Get the converter - Func converter = null; - if (Database.Mapper != null) - converter = Database.Mapper.GetFromDbConverter(null, srcType); - if (ForceDateTimesToUtc && converter == null && srcType == typeof(DateTime)) - converter = delegate(object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); }; - - // Setup stack for call to converter - AddConverterToStack(il, converter); - - // r[i] - il.Emit(OpCodes.Ldarg_0); // obj, obj, fieldname, converter?, rdr - il.Emit(OpCodes.Ldc_I4, i); // obj, obj, fieldname, converter?, rdr,i - il.Emit(OpCodes.Callvirt, fnGetValue); // obj, obj, fieldname, converter?, value - - // Convert DBNull to null - il.Emit(OpCodes.Dup); // obj, obj, fieldname, converter?, value, value - il.Emit(OpCodes.Isinst, typeof(DBNull)); // obj, obj, fieldname, converter?, value, (value or null) - var lblNotNull = il.DefineLabel(); - il.Emit(OpCodes.Brfalse_S, lblNotNull); // obj, obj, fieldname, converter?, value - il.Emit(OpCodes.Pop); // obj, obj, fieldname, converter? - if (converter != null) - il.Emit(OpCodes.Pop); // obj, obj, fieldname, - il.Emit(OpCodes.Ldnull); // obj, obj, fieldname, null - if (converter != null) - { - var lblReady = il.DefineLabel(); - il.Emit(OpCodes.Br_S, lblReady); - il.MarkLabel(lblNotNull); - il.Emit(OpCodes.Callvirt, fnInvoke); - il.MarkLabel(lblReady); - } - else - { - il.MarkLabel(lblNotNull); - } - - il.Emit(OpCodes.Callvirt, fnAdd); - } - } - else -#endif - if (type.IsValueType || type == typeof(string) || type == typeof(byte[])) - { - // Do we need to install a converter? - var srcType = r.GetFieldType(0); - var converter = GetConverter(ForceDateTimesToUtc, null, srcType, type); - - // "if (!rdr.IsDBNull(i))" - il.Emit(OpCodes.Ldarg_0); // rdr - il.Emit(OpCodes.Ldc_I4_0); // rdr,0 - il.Emit(OpCodes.Callvirt, fnIsDBNull); // bool - var lblCont = il.DefineLabel(); - il.Emit(OpCodes.Brfalse_S, lblCont); - il.Emit(OpCodes.Ldnull); // null - var lblFin = il.DefineLabel(); - il.Emit(OpCodes.Br_S, lblFin); - - il.MarkLabel(lblCont); - - // Setup stack for call to converter - AddConverterToStack(il, converter); - - il.Emit(OpCodes.Ldarg_0); // rdr - il.Emit(OpCodes.Ldc_I4_0); // rdr,0 - il.Emit(OpCodes.Callvirt, fnGetValue); // value - - // Call the converter - if (converter != null) - il.Emit(OpCodes.Callvirt, fnInvoke); - - il.MarkLabel(lblFin); - il.Emit(OpCodes.Unbox_Any, type); // value converted - } - else - { - // var poco=new T() - il.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null)); - - // Enumerate all fields generating a set assignment for the column - for (int i = firstColumn; i < firstColumn + countColumns; i++) - { - // Get the PocoColumn for this db column, ignore if not known - PocoColumn pc; - if (!Columns.TryGetValue(r.GetName(i), out pc)) - continue; - - // Get the source type for this column - var srcType = r.GetFieldType(i); - var dstType = pc.PropertyInfo.PropertyType; - - // "if (!rdr.IsDBNull(i))" - il.Emit(OpCodes.Ldarg_0); // poco,rdr - il.Emit(OpCodes.Ldc_I4, i); // poco,rdr,i - il.Emit(OpCodes.Callvirt, fnIsDBNull); // poco,bool - var lblNext = il.DefineLabel(); - il.Emit(OpCodes.Brtrue_S, lblNext); // poco - - il.Emit(OpCodes.Dup); // poco,poco - - // Do we need to install a converter? - var converter = GetConverter(ForceDateTimesToUtc, pc, srcType, dstType); - - // Fast - bool Handled = false; - if (converter == null) - { - var valuegetter = typeof(IDataRecord).GetMethod("Get" + srcType.Name, new Type[] { typeof(int) }); - if (valuegetter != null - && valuegetter.ReturnType == srcType - && (valuegetter.ReturnType == dstType || valuegetter.ReturnType == Nullable.GetUnderlyingType(dstType))) - { - il.Emit(OpCodes.Ldarg_0); // *,rdr - il.Emit(OpCodes.Ldc_I4, i); // *,rdr,i - il.Emit(OpCodes.Callvirt, valuegetter); // *,value - - // Convert to Nullable - if (Nullable.GetUnderlyingType(dstType) != null) - { - il.Emit(OpCodes.Newobj, dstType.GetConstructor(new Type[] { Nullable.GetUnderlyingType(dstType) })); - } - - il.Emit(OpCodes.Callvirt, pc.PropertyInfo.GetSetMethod(true)); // poco - Handled = true; - } - } - - // Not so fast - if (!Handled) - { - // Setup stack for call to converter - AddConverterToStack(il, converter); - - // "value = rdr.GetValue(i)" - il.Emit(OpCodes.Ldarg_0); // *,rdr - il.Emit(OpCodes.Ldc_I4, i); // *,rdr,i - il.Emit(OpCodes.Callvirt, fnGetValue); // *,value - - // Call the converter - if (converter != null) - il.Emit(OpCodes.Callvirt, fnInvoke); - - // Assign it - il.Emit(OpCodes.Unbox_Any, pc.PropertyInfo.PropertyType); // poco,poco,value - il.Emit(OpCodes.Callvirt, pc.PropertyInfo.GetSetMethod(true)); // poco - } - - il.MarkLabel(lblNext); - } - - var fnOnLoaded = RecurseInheritedTypes(type, (x) => x.GetMethod("OnLoaded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null)); - if (fnOnLoaded != null) - { - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Callvirt, fnOnLoaded); - } - } - - il.Emit(OpCodes.Ret); - - // return it - var del = m.CreateDelegate(Expression.GetFuncType(typeof(IDataReader), type)); - - return del; - }; - - //lazy usage of AddOrGetExisting ref: http://stackoverflow.com/questions/10559279/how-to-deal-with-costly-building-operations-using-memorycache/15894928#15894928 - var newValue = new Lazy(factory); - // the line belows returns existing item or adds the new value if it doesn't exist - var value = (Lazy)objectCache.AddOrGetExisting(key, newValue, new CacheItemPolicy - { - //sliding expiration of 1 hr, if the same key isn't used in this - // timeframe it will be removed from the cache - SlidingExpiration = new TimeSpan(0, 0, SlidingExpirationSeconds) - }); - return (value ?? newValue).Value; // Lazy handles the locking itself - - } - - private static void AddConverterToStack(ILGenerator il, Func converter) - { - if (converter != null) - { - // Add the converter - int converterIndex = m_Converters.Count; - m_Converters.Add(converter); - - // Generate IL to push the converter onto the stack - il.Emit(OpCodes.Ldsfld, fldConverters); - il.Emit(OpCodes.Ldc_I4, converterIndex); - il.Emit(OpCodes.Callvirt, fnListGetItem); // Converter - } - } - - private static Func GetConverter(bool forceDateTimesToUtc, PocoColumn pc, Type srcType, Type dstType) - { - Func converter = null; - - // Get converter from the mapper - if (Database.Mapper != null) - { - if (pc != null) - { - converter = Database.Mapper.GetFromDbConverter(pc.PropertyInfo, srcType); - } - else - { - var m2 = Database.Mapper as IMapper2; - if (m2 != null) - { - converter = m2.GetFromDbConverter(dstType, srcType); - } - } - } - - // Standard DateTime->Utc mapper - if (forceDateTimesToUtc && converter == null && srcType == typeof(DateTime) && (dstType == typeof(DateTime) || dstType == typeof(DateTime?))) - { - converter = delegate(object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); }; - } - - // Forced type conversion including integral types -> enum - if (converter == null) - { - if (dstType.IsEnum && IsIntegralType(srcType)) - { - if (srcType != typeof(int)) - { - converter = delegate(object src) { return Convert.ChangeType(src, typeof(int), null); }; - } - } - else if (!dstType.IsAssignableFrom(srcType)) - { - converter = delegate(object src) { return Convert.ChangeType(src, dstType, null); }; - } - } - return converter; - } - - - static T RecurseInheritedTypes(Type t, Func cb) - { - while (t != null) - { - T info = cb(t); - if (info != null) - return info; - t = t.BaseType; - } - return default(T); - } - - ManagedCache _managedCache = new ManagedCache(); - static Dictionary m_PocoDatas = new Dictionary(); - static List> m_Converters = new List>(); - static MethodInfo fnGetValue = typeof(IDataRecord).GetMethod("GetValue", new Type[] { typeof(int) }); - static MethodInfo fnIsDBNull = typeof(IDataRecord).GetMethod("IsDBNull"); - static FieldInfo fldConverters = typeof(PocoData).GetField("m_Converters", BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic); - static MethodInfo fnListGetItem = typeof(List>).GetProperty("Item").GetGetMethod(); - static MethodInfo fnInvoke = typeof(Func).GetMethod("Invoke"); - public Type type; - public string[] QueryColumns { get; private set; } - public TableInfo TableInfo { get; private set; } - public Dictionary Columns { get; private set; } - static System.Threading.ReaderWriterLockSlim InnerLock = new System.Threading.ReaderWriterLockSlim(); - - /// - /// Returns a report of the current cache being utilized by PetaPoco - /// - /// - public static string PrintDebugCacheReport(out double totalBytes, out IEnumerable allKeys) - { - var managedCache = new ManagedCache(); - - var sb = new StringBuilder(); - sb.AppendLine("m_PocoDatas:"); - foreach (var pocoData in m_PocoDatas) - { - sb.AppendFormat("\t{0}\n", pocoData.Key); - sb.AppendFormat("\t\tTable:{0} - Col count:{1}\n", pocoData.Value.TableInfo.TableName, pocoData.Value.QueryColumns.Length); - } - - var cache = managedCache.GetCache(); - allKeys = cache.Select(x => x.Key).ToArray(); - - sb.AppendFormat("\tTotal Poco data count:{0}\n", allKeys.Count()); - - var keys = string.Join("", cache.Select(x => x.Key)); - //Bytes in .Net are stored as utf-16 = unicode little endian - totalBytes = Encoding.Unicode.GetByteCount(keys); - - sb.AppendFormat("\tTotal byte for keys:{0}\n", totalBytes); - - sb.AppendLine("\tAll Poco cache items:"); - - foreach (var item in cache) - { - sb.AppendFormat("\t\t Key -> {0}\n", item.Key); - sb.AppendFormat("\t\t Value -> {0}\n", item.Value); - } - - sb.AppendLine("-------------------END REPORT------------------------"); - return sb.ToString(); - } - } - - - // Member variables - string _connectionString; - string _providerName; - DbProviderFactory _factory; - IDbConnection _sharedConnection; - IDbTransaction _transaction; - int _sharedConnectionDepth; - int _transactionDepth; - bool _transactionCancelled; - string _lastSql; - object[] _lastArgs; - string _paramPrefix = "@"; - IsolationLevel _isolationLevel; - } - - // Transaction object helps maintain transaction depth counts - public class Transaction : IDisposable - { - public Transaction(Database db, IsolationLevel isolationLevel) - { - _db = db; - _db.BeginTransaction(isolationLevel); - } - - public virtual void Complete() - { - _db.CompleteTransaction(); - _db = null; - } - - public void Dispose() - { - //TODO prevent multiple calls to Dispose - if (_db != null) - _db.AbortTransaction(); - } - - Database _db; - } - - // Simple helper class for building SQL statments - public class Sql - { - public Sql() - { - } - - public Sql(string sql, params object[] args) - { - _sql = sql; - _args = args; - } - - string _sql; - object[] _args; - Sql _rhs; - string _sqlFinal; - object[] _argsFinal; - - private void Build() - { - // already built? - if (_sqlFinal != null) - return; - - // Build it - var sb = new StringBuilder(); - var args = new List(); - Build(sb, args, null); - _sqlFinal = sb.ToString(); - _argsFinal = args.ToArray(); - } - - public string SQL - { - get - { - Build(); - return _sqlFinal; - } - } - - public object[] Arguments - { - get - { - Build(); - return _argsFinal; - } - } - - public Sql Append(Sql sql) - { - if (_rhs != null) - _rhs.Append(sql); - else - _rhs = sql; - - return this; - } - - public Sql Append(string sql, params object[] args) - { - return Append(new Sql(sql, args)); - } - - static bool Is(Sql sql, string sqltype) - { - return sql != null && sql._sql != null && sql._sql.StartsWith(sqltype, StringComparison.InvariantCultureIgnoreCase); - } - - private void Build(StringBuilder sb, List args, Sql lhs) - { - if (!String.IsNullOrEmpty(_sql)) - { - // Add SQL to the string - if (sb.Length > 0) - { - sb.Append("\n"); - } - - var sql = Database.ProcessParams(_sql, _args, args); - - if (Is(lhs, "WHERE ") && Is(this, "WHERE ")) - sql = "AND " + sql.Substring(6); - if (Is(lhs, "ORDER BY ") && Is(this, "ORDER BY ")) - sql = ", " + sql.Substring(9); - - sb.Append(sql); - } - - // Now do rhs - if (_rhs != null) - _rhs.Build(sb, args, this); - } - - public Sql Where(string sql, params object[] args) - { - return Append(new Sql("WHERE (" + sql + ")", args)); - } - - public Sql OrderBy(params object[] columns) - { - return Append(new Sql("ORDER BY " + String.Join(", ", (from x in columns select x.ToString()).ToArray()))); - } - - public Sql Select(params object[] columns) - { - return Append(new Sql("SELECT " + String.Join(", ", (from x in columns select x.ToString()).ToArray()))); - } - - public Sql From(params object[] tables) - { - return Append(new Sql("FROM " + String.Join(", ", (from x in tables select x.ToString()).ToArray()))); - } - - public Sql GroupBy(params object[] columns) - { - return Append(new Sql("GROUP BY " + String.Join(", ", (from x in columns select x.ToString()).ToArray()))); - } - - private SqlJoinClause Join(string JoinType, string table) - { - return new SqlJoinClause(Append(new Sql(JoinType + table))); - } - - public SqlJoinClause InnerJoin(string table) { return Join("INNER JOIN ", table); } - public SqlJoinClause LeftJoin(string table) { return Join("LEFT JOIN ", table); } - public SqlJoinClause LeftOuterJoin(string table) { return Join("LEFT OUTER JOIN ", table); } - public SqlJoinClause RightJoin(string table) { return Join("RIGHT JOIN ", table); } - - public class SqlJoinClause - { - private readonly Sql _sql; - - public SqlJoinClause(Sql sql) - { - _sql = sql; - } - - public Sql On(string onClause, params object[] args) - { - return _sql.Append("ON " + onClause, args); - } - } - } - -} diff --git a/src/Umbraco.Core/Persistence/PetaPocoCommandExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoCommandExtensions.cs deleted file mode 100644 index f1b41f2420..0000000000 --- a/src/Umbraco.Core/Persistence/PetaPocoCommandExtensions.cs +++ /dev/null @@ -1,277 +0,0 @@ -using System; -using System.Data; -using System.Data.SqlClient; -using Umbraco.Core.Persistence.FaultHandling; - -namespace Umbraco.Core.Persistence -{ - /// - /// Provides a set of extension methods adding retry capabilities into the standard implementation, which is used in PetaPoco. - /// - public static class PetaPocoCommandExtensions - { - #region ExecuteNonQueryWithRetry method implementations - /// - /// Executes a Transact-SQL statement against the connection and returns the number of rows affected. Uses the default retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// The number of rows affected. - public static int ExecuteNonQueryWithRetry(this IDbCommand command) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteNonQueryWithRetry(command, RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Executes a Transact-SQL statement against the connection and returns the number of rows affected. Uses the specified retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// The retry policy defining whether to retry a command if a connection fails while executing the command. - /// The number of rows affected. - public static int ExecuteNonQueryWithRetry(this IDbCommand command, RetryPolicy retryPolicy) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteNonQueryWithRetry(command, retryPolicy, RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Executes a Transact-SQL statement against the connection and returns the number of rows affected. Uses the specified retry policy when executing the command. - /// Uses a separate specified retry policy when establishing a connection. - /// - /// The command object that is required as per extension method declaration. - /// The command retry policy defining whether to retry a command if it fails while executing. - /// The connection retry policy defining whether to re-establish a connection if it drops while executing the command. - /// The number of rows affected. - public static int ExecuteNonQueryWithRetry(this IDbCommand command, RetryPolicy cmdRetryPolicy, RetryPolicy conRetryPolicy) - { - //GuardConnectionIsNotNull(command); - - // Check if retry policy was specified, if not, use the default retry policy. - return (cmdRetryPolicy ?? RetryPolicy.NoRetry).ExecuteAction(() => - { - var hasOpenConnection = EnsureValidConnection(command, conRetryPolicy); - - try - { - return command.ExecuteNonQuery(); - } - finally - { - if (hasOpenConnection && command.Connection != null && command.Connection.State == ConnectionState.Open) - { - //Connection is closed in PetaPoco, so no need to do it here (?) - //command.Connection.Close(); - } - } - }); - } - #endregion - - #region ExecuteReaderWithRetry method implementations - /// - /// Sends the specified command to the connection and builds a SqlDataReader object containing the results. - /// Uses the default retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// A System.Data.IDataReader object. - public static IDataReader ExecuteReaderWithRetry(this IDbCommand command) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteReaderWithRetry(command, RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Sends the specified command to the connection and builds a SqlDataReader object containing the results. - /// Uses the specified retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// The retry policy defining whether to retry a command if a connection fails while executing the command. - /// A System.Data.IDataReader object. - public static IDataReader ExecuteReaderWithRetry(this IDbCommand command, RetryPolicy retryPolicy) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteReaderWithRetry(command, retryPolicy, RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Sends the specified command to the connection and builds a SqlDataReader object containing the results. - /// Uses the specified retry policy when executing the command. Uses a separate specified retry policy when - /// establishing a connection. - /// - /// The command object that is required as per extension method declaration. - /// The command retry policy defining whether to retry a command if it fails while executing. - /// The connection retry policy defining whether to re-establish a connection if it drops while executing the command. - /// A System.Data.IDataReader object. - public static IDataReader ExecuteReaderWithRetry(this IDbCommand command, RetryPolicy cmdRetryPolicy, RetryPolicy conRetryPolicy) - { - //GuardConnectionIsNotNull(command); - - // Check if retry policy was specified, if not, use the default retry policy. - return (cmdRetryPolicy ?? RetryPolicy.NoRetry).ExecuteAction(() => - { - var hasOpenConnection = EnsureValidConnection(command, conRetryPolicy); - - try - { - return command.ExecuteReader(); - } - catch (Exception) - { - if (hasOpenConnection && command.Connection != null && command.Connection.State == ConnectionState.Open) - { - //command.Connection.Close(); - } - - throw; - } - }); - } - - /// - /// Sends the specified command to the connection and builds a SqlDataReader object using one of the - /// CommandBehavior values. Uses the default retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// One of the System.Data.CommandBehavior values. - /// A System.Data.IDataReader object. - public static IDataReader ExecuteReaderWithRetry(this IDbCommand command, CommandBehavior behavior) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteReaderWithRetry(command, behavior, RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Sends the specified command to the connection and builds a SqlDataReader object using one of the - /// CommandBehavior values. Uses the specified retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// One of the System.Data.CommandBehavior values. - /// The retry policy defining whether to retry a command if a connection fails while executing the command. - /// A System.Data.SqlClient.SqlDataReader object. - public static IDataReader ExecuteReaderWithRetry(this IDbCommand command, CommandBehavior behavior, RetryPolicy retryPolicy) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteReaderWithRetry(command, behavior, retryPolicy, RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Sends the specified command to the connection and builds a SqlDataReader object using one of the - /// CommandBehavior values. Uses the specified retry policy when executing the command. - /// Uses a separate specified retry policy when establishing a connection. - /// - /// The command object that is required as per extension method declaration. - /// One of the System.Data.CommandBehavior values. - /// The command retry policy defining whether to retry a command if it fails while executing. - /// The connection retry policy defining whether to re-establish a connection if it drops while executing the command. - /// A System.Data.IDataReader object. - public static IDataReader ExecuteReaderWithRetry(this IDbCommand command, CommandBehavior behavior, RetryPolicy cmdRetryPolicy, RetryPolicy conRetryPolicy) - { - //GuardConnectionIsNotNull(command); - - // Check if retry policy was specified, if not, use the default retry policy. - return (cmdRetryPolicy ?? RetryPolicy.NoRetry).ExecuteAction(() => - { - var hasOpenConnection = EnsureValidConnection(command, conRetryPolicy); - - try - { - return command.ExecuteReader(behavior); - } - catch (Exception) - { - if (hasOpenConnection && command.Connection != null && command.Connection.State == ConnectionState.Open) - { - //command.Connection.Close(); - } - - throw; - } - }); - } - #endregion - - #region ExecuteScalarWithRetry method implementations - /// - /// Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. - /// Uses the default retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// The first column of the first row in the result set, or a null reference if the result set is empty. Returns a maximum of 2033 characters. - public static object ExecuteScalarWithRetry(this IDbCommand command) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteScalarWithRetry(command, RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(connectionString)); - } - - /// - /// Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. - /// Uses the specified retry policy when executing the command. - /// - /// The command object that is required as per extension method declaration. - /// The retry policy defining whether to retry a command if a connection fails while executing the command. - /// The first column of the first row in the result set, or a null reference if the result set is empty. Returns a maximum of 2033 characters. - public static object ExecuteScalarWithRetry(this IDbCommand command, RetryPolicy retryPolicy) - { - var connectionString = command.Connection.ConnectionString ?? string.Empty; - return ExecuteScalarWithRetry(command, retryPolicy, RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString)); - } - /// - /// Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. - /// Uses the specified retry policy when executing the command. Uses a separate specified retry policy when establishing a connection. - /// - /// The command object that is required as per extension method declaration. - /// The command retry policy defining whether to retry a command if it fails while executing. - /// The connection retry policy defining whether to re-establish a connection if it drops while executing the command. - /// The first column of the first row in the result set, or a null reference if the result set is empty. Returns a maximum of 2033 characters. - public static object ExecuteScalarWithRetry(this IDbCommand command, RetryPolicy cmdRetryPolicy, RetryPolicy conRetryPolicy) - { - //GuardConnectionIsNotNull(command); - - // Check if retry policy was specified, if not, use the default retry policy. - return (cmdRetryPolicy ?? RetryPolicy.NoRetry).ExecuteAction(() => - { - var hasOpenConnection = EnsureValidConnection(command, conRetryPolicy); - - try - { - return command.ExecuteScalar(); - } - finally - { - if (hasOpenConnection && command.Connection != null && command.Connection.State == ConnectionState.Open) - { - //Connection is closed in PetaPoco, so no need to do it here (?) - //command.Connection.Close(); - } - } - }); - } - #endregion - - /// - /// Ensure a valid connection in case a connection hasn't been opened by PetaPoco (which shouldn't be possible by the way). - /// - /// - /// - /// - private static bool EnsureValidConnection(IDbCommand command, RetryPolicy retryPolicy) - { - if (command != null) - { - //GuardConnectionIsNotNull(command); - - // Verify whether or not the connection is valid and is open. This code may be retried therefore - // it is important to ensure that a connection is re-established should it have previously failed. - if (command.Connection.State != ConnectionState.Open) - { - // Attempt to open the connection using the retry policy that matches the policy for SQL commands. - command.Connection.OpenWithRetry(retryPolicy); - - return true; - } - } - - return false; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/PetaPocoConnectionExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoConnectionExtensions.cs deleted file mode 100644 index e13608bc31..0000000000 --- a/src/Umbraco.Core/Persistence/PetaPocoConnectionExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Data; -using Umbraco.Core.Persistence.FaultHandling; - -namespace Umbraco.Core.Persistence -{ - /// - /// Provides a set of extension methods adding retry capabilities into the standard interface, which is used in PetaPoco. - /// - public static class PetaPocoConnectionExtensions - { - /// - /// Opens a database connection with the connection settings specified in the ConnectionString property of the connection object. - /// Uses the default retry policy when opening the connection. - /// - /// The connection object that is required as per extension method declaration. - public static void OpenWithRetry(this IDbConnection connection) - { - var connectionString = connection.ConnectionString ?? string.Empty; - var retryPolicy = RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(connectionString); - OpenWithRetry(connection, retryPolicy); - } - - /// - /// Opens a database connection with the connection settings specified in the ConnectionString property of the connection object. - /// Uses the specified retry policy when opening the connection. - /// - /// The connection object that is required as per extension method declaration. - /// The retry policy defining whether to retry a request if the connection fails to be opened. - public static void OpenWithRetry(this IDbConnection connection, RetryPolicy retryPolicy) - { - // Check if retry policy was specified, if not, use the default retry policy. - (retryPolicy != null ? retryPolicy : RetryPolicy.NoRetry).ExecuteAction(connection.Open); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs deleted file mode 100644 index 8603481376..0000000000 --- a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Core.Persistence -{ - /// - /// Extension methods adding strong types to PetaPoco's Sql Builder - /// - public static class PetaPocoSqlExtensions - { - - public static Sql From(this Sql sql, ISqlSyntaxProvider sqlSyntax) - { - var type = typeof(T); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - return sql.From(sqlSyntax.GetQuotedTableName(tableName)); - } - - public static Sql Where(this Sql sql, ISqlSyntaxProvider sqlSyntax, Expression> predicate) - { - var expresionist = new PocoToSqlExpressionHelper(sqlSyntax); - var whereExpression = expresionist.Visit(predicate); - return sql.Where(whereExpression, expresionist.GetSqlParameters()); - } - - public static Sql WhereIn(this Sql sql, ISqlSyntaxProvider sqlSyntax, Expression> fieldSelector, IEnumerable values) - { - var expresionist = new PocoToSqlExpressionHelper(sqlSyntax); - var fieldExpression = expresionist.Visit(fieldSelector); - return sql.Where(fieldExpression + " IN (@values)", new {@values = values}); - } - - public static Sql OrderBy(this Sql sql, ISqlSyntaxProvider sqlSyntax, Expression> columnMember) - { - var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; - var columnName = column.FirstAttribute().Name; - - var type = typeof(TColumn); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - //need to ensure the order by is in brackets, see: https://github.com/toptensoftware/PetaPoco/issues/177 - var syntax = string.Format("({0}.{1})", - sqlSyntax.GetQuotedTableName(tableName), - sqlSyntax.GetQuotedColumnName(columnName)); - - return sql.OrderBy(syntax); - } - - public static Sql OrderByDescending(this Sql sql, ISqlSyntaxProvider sqlSyntax, Expression> columnMember) - { - var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; - var columnName = column.FirstAttribute().Name; - - var type = typeof(TColumn); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - var syntax = string.Format("{0}.{1} DESC", - sqlSyntax.GetQuotedTableName(tableName), - sqlSyntax.GetQuotedColumnName(columnName)); - - return sql.OrderBy(syntax); - } - - public static Sql GroupBy(this Sql sql, ISqlSyntaxProvider sqlProvider, Expression> columnMember) - { - var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; - var columnName = column.FirstAttribute().Name; - - return sql.GroupBy(sqlProvider.GetQuotedColumnName(columnName)); - } - - public static Sql.SqlJoinClause InnerJoin(this Sql sql, ISqlSyntaxProvider sqlSyntax) - { - var type = typeof(T); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - return sql.InnerJoin(sqlSyntax.GetQuotedTableName(tableName)); - } - - public static Sql.SqlJoinClause LeftJoin(this Sql sql, ISqlSyntaxProvider sqlSyntax) - { - var type = typeof(T); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - return sql.LeftJoin(sqlSyntax.GetQuotedTableName(tableName)); - } - - public static Sql.SqlJoinClause LeftOuterJoin(this Sql sql, ISqlSyntaxProvider sqlSyntax) - { - var type = typeof(T); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - return sql.LeftOuterJoin(sqlSyntax.GetQuotedTableName(tableName)); - } - - public static Sql.SqlJoinClause RightJoin(this Sql sql, ISqlSyntaxProvider sqlSyntax) - { - var type = typeof(T); - var tableNameAttribute = type.FirstAttribute(); - string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - - return sql.RightJoin(sqlSyntax.GetQuotedTableName(tableName)); - } - - public static Sql On(this Sql.SqlJoinClause sql, ISqlSyntaxProvider sqlSyntax, Expression> leftMember, - Expression> rightMember, params object[] args) - { - var leftType = typeof(TLeft); - var rightType = typeof(TRight); - var leftTableName = leftType.FirstAttribute().Value; - var rightTableName = rightType.FirstAttribute().Value; - - var left = ExpressionHelper.FindProperty(leftMember) as PropertyInfo; - var right = ExpressionHelper.FindProperty(rightMember) as PropertyInfo; - var leftColumnName = left.FirstAttribute().Name; - var rightColumnName = right.FirstAttribute().Name; - - string onClause = string.Format("{0}.{1} = {2}.{3}", - sqlSyntax.GetQuotedTableName(leftTableName), - sqlSyntax.GetQuotedColumnName(leftColumnName), - sqlSyntax.GetQuotedTableName(rightTableName), - sqlSyntax.GetQuotedColumnName(rightColumnName)); - return sql.On(onClause); - } - - public static Sql OrderByDescending(this Sql sql, params object[] columns) - { - return sql.Append(new Sql("ORDER BY " + String.Join(", ", (from x in columns select x + " DESC").ToArray()))); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs index 05d9646b18..50e1ea0106 100644 --- a/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs +++ b/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs @@ -10,6 +10,8 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Querying { + // fixme.npoco - are we basically duplicating entire parts of NPoco just because of SqlSyntax ?! + internal abstract class BaseExpressionHelper : BaseExpressionHelper { protected BaseExpressionHelper(ISqlSyntaxProvider sqlSyntax) @@ -151,13 +153,13 @@ namespace Umbraco.Core.Persistence.Querying { // deal with (x != true|false) - most common var constRight = b.Right as ConstantExpression; - if (constRight != null && constRight.Type == typeof(bool)) + if (constRight != null && constRight.Type == typeof (bool)) return ((bool) constRight.Value) ? VisitNot(b.Left) : VisitNotNot(b.Left); right = Visit(b.Right); // deal with (true|false != x) - why not var constLeft = b.Left as ConstantExpression; - if (constLeft != null && constLeft.Type == typeof(bool)) + if (constLeft != null && constLeft.Type == typeof (bool)) return ((bool) constLeft.Value) ? VisitNot(b.Right) : VisitNotNot(b.Right); left = Visit(b.Left); } @@ -578,11 +580,11 @@ namespace Umbraco.Core.Persistence.Querying /// /// Logic that is shared with the expression helpers /// - internal class BaseExpressionHelper + internal abstract class BaseExpressionHelper { public ISqlSyntaxProvider SqlSyntax { get; private set; } - public BaseExpressionHelper(ISqlSyntaxProvider sqlSyntax) + protected BaseExpressionHelper(ISqlSyntaxProvider sqlSyntax) { SqlSyntax = sqlSyntax; } diff --git a/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs index 32e86f9512..958854727a 100644 --- a/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs +++ b/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs @@ -1,63 +1,51 @@ using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; -using System.Text; -using Umbraco.Core.Persistence.SqlSyntax; +using NPoco; namespace Umbraco.Core.Persistence.Querying { internal class PocoToSqlExpressionHelper : BaseExpressionHelper { - private readonly Database.PocoData _pd; + private readonly PocoData _pd; - public PocoToSqlExpressionHelper(ISqlSyntaxProvider sqlSyntaxProvider) - : base(sqlSyntaxProvider) + public PocoToSqlExpressionHelper(SqlContext sqlContext) + : base(sqlContext.SqlSyntax) { - _pd = new Database.PocoData(typeof(T)); + _pd = sqlContext.PocoDataFactory.ForType(typeof (T)); } protected override string VisitMemberAccess(MemberExpression m) { - if (m.Expression != null && - m.Expression.NodeType == ExpressionType.Parameter - && m.Expression.Type == typeof(T)) + if (m.Expression != null && m.Expression.NodeType == ExpressionType.Parameter && m.Expression.Type == typeof (T)) { - string field = GetFieldName(_pd, m.Member.Name); + var field = GetFieldName(_pd, m.Member.Name); return field; } if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert) { - string field = GetFieldName(_pd, m.Member.Name); + var field = GetFieldName(_pd, m.Member.Name); return field; } var member = Expression.Convert(m, typeof(object)); var lambda = Expression.Lambda>(member); var getter = lambda.Compile(); - object o = getter(); + var o = getter(); SqlParameters.Add(o); - return string.Format("@{0}", SqlParameters.Count - 1); - - //return GetQuotedValue(o, o != null ? o.GetType() : null); + return $"@{SqlParameters.Count - 1}"; } - protected virtual string GetFieldName(Database.PocoData pocoData, string name) + protected virtual string GetFieldName(PocoData pocoData, string name) { - var column = pocoData.Columns.FirstOrDefault(x => x.Value.PropertyInfo.Name == name); - return string.Format("{0}.{1}", - SqlSyntax.GetQuotedTableName(pocoData.TableInfo.TableName), - SqlSyntax.GetQuotedColumnName(column.Value.ColumnName)); - } + var column = pocoData.Columns.FirstOrDefault(x => x.Value.MemberInfoData.Name == name); + var tableName = SqlSyntax.GetQuotedTableName(pocoData.TableInfo.TableName); + var columnName = SqlSyntax.GetQuotedColumnName(column.Value.ColumnName); - //protected bool IsFieldName(string quotedExp) - //{ - // return true; - //} + return $"{tableName}.{columnName}"; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Querying/SqlTranslator.cs b/src/Umbraco.Core/Persistence/Querying/SqlTranslator.cs index b012293340..94434fca74 100644 --- a/src/Umbraco.Core/Persistence/Querying/SqlTranslator.cs +++ b/src/Umbraco.Core/Persistence/Querying/SqlTranslator.cs @@ -1,4 +1,5 @@ using System; +using NPoco; namespace Umbraco.Core.Persistence.Querying { @@ -8,9 +9,9 @@ namespace Umbraco.Core.Persistence.Querying /// internal class SqlTranslator { - private readonly Sql _sql; + private readonly Sql _sql; - public SqlTranslator(Sql sql, IQuery query) + public SqlTranslator(Sql sql, IQuery query) { if (sql == null) throw new Exception("Sql cannot be null"); @@ -22,7 +23,7 @@ namespace Umbraco.Core.Persistence.Querying } } - public Sql Translate() + public Sql Translate() { return _sql; } diff --git a/src/Umbraco.Core/Persistence/Relators/AccessRulesRelator.cs b/src/Umbraco.Core/Persistence/Relators/AccessRulesRelator.cs deleted file mode 100644 index bcb33f3597..0000000000 --- a/src/Umbraco.Core/Persistence/Relators/AccessRulesRelator.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using Umbraco.Core.Models.Rdbms; - -namespace Umbraco.Core.Persistence.Relators -{ - internal class AccessRulesRelator - { - internal AccessDto Current; - - internal AccessDto Map(AccessDto a, AccessRuleDto p) - { - // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null - // parameters - if (a == null) - return Current; - - // Is this the same AccessDto as the current one we're processing - if (Current != null && Current.Id == a.Id) - { - // Yes, just add this AccessRuleDto to the current AccessDto's collection - if (p.Id != default(Guid)) - { - Current.Rules.Add(p); - } - - - // Return null to indicate we're not done with this AccessDto yet - return null; - } - - // This is a different AccessDto to the current one, or this is the - // first time through and we don't have a Tab yet - - // Save the current AccessDto - var prev = Current; - - // Setup the new current AccessDto - Current = a; - Current.Rules = new List(); - if (p.Id != default(Guid)) - { - Current.Rules.Add(p); - } - - // Return the now populated previous AccessDto (or null if first time through) - return prev; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Relators/DictionaryLanguageTextRelator.cs b/src/Umbraco.Core/Persistence/Relators/DictionaryLanguageTextRelator.cs deleted file mode 100644 index 6e2173471c..0000000000 --- a/src/Umbraco.Core/Persistence/Relators/DictionaryLanguageTextRelator.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models.Rdbms; - -namespace Umbraco.Core.Persistence.Relators -{ - internal class DictionaryLanguageTextRelator - { - internal DictionaryDto Current; - - internal DictionaryDto Map(DictionaryDto a, LanguageTextDto p) - { - // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null - // parameters - if (a == null) - return Current; - - // Is this the same DictionaryItem as the current one we're processing - if (Current != null && Current.UniqueId == a.UniqueId) - { - // Yes, just add this LanguageTextDto to the current DictionaryItem's collection - Current.LanguageTextDtos.Add(p); - - // Return null to indicate we're not done with this DictionaryItem yet - return null; - } - - // This is a different DictionaryItem to the current one, or this is the - // first time through and we don't have a Tab yet - - // Save the current DictionaryItem - var prev = Current; - - // Setup the new current DictionaryItem - Current = a; - Current.LanguageTextDtos = new List(); - Current.LanguageTextDtos.Add(p); - - // Return the now populated previous DictionaryItem (or null if first time through) - return prev; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Relators/GroupPropertyTypeRelator.cs b/src/Umbraco.Core/Persistence/Relators/GroupPropertyTypeRelator.cs deleted file mode 100644 index 616882f068..0000000000 --- a/src/Umbraco.Core/Persistence/Relators/GroupPropertyTypeRelator.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models.Rdbms; - -namespace Umbraco.Core.Persistence.Relators -{ - internal class GroupPropertyTypeRelator - { - internal PropertyTypeGroupDto current; - - internal PropertyTypeGroupDto Map(PropertyTypeGroupDto a, PropertyTypeDto p, DataTypeDto d) - { - // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null - // parameters - if (a == null) - return current; - - //Set the PropertyTypeDto's DataTypeDto object - if (p.DataTypeId == d.DataTypeId) - p.DataTypeDto = d; - - // Is this the same Group as the current one we're processing - if (current != null && current.Id == a.Id) - { - // Yes, just add this PropertyType to the current Group's collection of PropertyTypes - current.PropertyTypeDtos.Add(p); - - // Return null to indicate we're not done with this Group yet - return null; - } - - // This is a different Group to the current one, or this is the - // first time through and we don't have a Tab yet - - // Save the current Group - var prev = current; - - // Setup the new current Group - current = a; - current.PropertyTypeDtos = new List(); - current.PropertyTypeDtos.Add(p); - - // Return the now populated previous Tab (or null if first time through) - return prev; - } - - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Relators/MacroPropertyRelator.cs b/src/Umbraco.Core/Persistence/Relators/MacroPropertyRelator.cs deleted file mode 100644 index 2f457edfd8..0000000000 --- a/src/Umbraco.Core/Persistence/Relators/MacroPropertyRelator.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models.Rdbms; - -namespace Umbraco.Core.Persistence.Relators -{ - //internal class TaskUserRelator - //{ - // internal TaskDto Current; - - // internal TaskDto Map(TaskDto a, UserDto p) - // { - // // Terminating call. Since we can return null from this function - // // we need to be ready for PetaPoco to callback later with null - // // parameters - // if (a == null) - // return Current; - - // // Is this the same TaskDto as the current one we're processing - // if (Current != null && Current.Id == a.Id) - // { - // // Yes, set the user - // Current.MacroPropertyDtos.Add(p); - - // // Return null to indicate we're not done with this Macro yet - // return null; - // } - - // // This is a different Macro to the current one, or this is the - // // first time through and we don't have one yet - - // // Save the current Macro - // var prev = Current; - - // // Setup the new current Macro - // Current = a; - // Current.MacroPropertyDtos = new List(); - // //this can be null since we are doing a left join - // if (p.Alias != null) - // { - // Current.MacroPropertyDtos.Add(p); - // } - - // // Return the now populated previous Macro (or null if first time through) - // return prev; - // } - //} - - internal class MacroPropertyRelator - { - internal MacroDto Current; - - internal MacroDto Map(MacroDto a, MacroPropertyDto p) - { - // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null - // parameters - if (a == null) - return Current; - - // Is this the same DictionaryItem as the current one we're processing - if (Current != null && Current.Id == a.Id) - { - // Yes, just add this MacroPropertyDtos to the current item's collection - Current.MacroPropertyDtos.Add(p); - - // Return null to indicate we're not done with this Macro yet - return null; - } - - // This is a different Macro to the current one, or this is the - // first time through and we don't have one yet - - // Save the current Macro - var prev = Current; - - // Setup the new current Macro - Current = a; - Current.MacroPropertyDtos = new List(); - //this can be null since we are doing a left join - if (p.Alias != null) - { - Current.MacroPropertyDtos.Add(p); - } - - // Return the now populated previous Macro (or null if first time through) - return prev; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs b/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs deleted file mode 100644 index bf307ea594..0000000000 --- a/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models.Rdbms; - -namespace Umbraco.Core.Persistence.Relators -{ - internal class PropertyTypePropertyGroupRelator - { - internal MemberTypeReadOnlyDto Current; - - internal MemberTypeReadOnlyDto Map(MemberTypeReadOnlyDto a, PropertyTypeReadOnlyDto p, PropertyTypeGroupReadOnlyDto g) - { - // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null - // parameters - if (a == null) - return Current; - - // Is this the same MemberTypeReadOnlyDto as the current one we're processing - if (Current != null && Current.UniqueId == a.UniqueId) - { - //This property may already be added so we need to check for that - if (p.Id.HasValue && Current.PropertyTypes.Any(x => x.Id == p.Id.Value) == false) - { - // Add this PropertyTypeReadOnlyDto to the current MemberTypeReadOnlyDto's collection - Current.PropertyTypes.Add(p); - } - - if (g.Id.HasValue && Current.PropertyTypeGroups != null && Current.PropertyTypeGroups.Any(x => x.Id == g.Id.Value) == false) - { - Current.PropertyTypeGroups.Add(g); - } - - // Return null to indicate we're not done with this MemberTypeReadOnlyDto yet - return null; - } - - // This is a different MemberTypeReadOnlyDto to the current one, or this is the - // first time through and we don't have a Tab yet - - // Save the current MemberTypeReadOnlyDto - var prev = Current; - - // Setup the new current MemberTypeReadOnlyDto - Current = a; - Current.PropertyTypes = new List(); - //this can be null since we are doing a left join - if (p.Id.HasValue) - { - Current.PropertyTypes.Add(p); - } - - Current.PropertyTypeGroups = new List(); - if (g.Id.HasValue) - { - Current.PropertyTypeGroups.Add(g); - } - - // Return the now populated previous MemberTypeReadOnlyDto (or null if first time through) - return prev; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs b/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs deleted file mode 100644 index 923348e729..0000000000 --- a/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models.Rdbms; - -namespace Umbraco.Core.Persistence.Relators -{ - internal class UserSectionRelator - { - internal UserDto Current; - - internal UserDto Map(UserDto a, User2AppDto p) - { - // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null - // parameters - if (a == null) - return Current; - - // Is this the same DictionaryItem as the current one we're processing - if (Current != null && Current.Id == a.Id) - { - if (p.AppAlias.IsNullOrWhiteSpace() == false) - { - // Yes, just add this User2AppDto to the current item's collection - Current.User2AppDtos.Add(p); - } - - // Return null to indicate we're not done with this User yet - return null; - } - - // This is a different User to the current one, or this is the - // first time through and we don't have one yet - - // Save the current User - var prev = Current; - - // Setup the new current User - Current = a; - Current.User2AppDtos = new List(); - //this can be null since we are doing a left join - if (p.AppAlias.IsNullOrWhiteSpace() == false) - { - Current.User2AppDtos.Add(p); - } - - // Return the now populated previous User (or null if first time through) - return prev; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/AuditRepository.cs b/src/Umbraco.Core/Persistence/Repositories/AuditRepository.cs index 710dbf1d30..4d3fc22a06 100644 --- a/src/Umbraco.Core/Persistence/Repositories/AuditRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/AuditRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; @@ -11,7 +12,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class AuditRepository : PetaPocoRepositoryBase, IAuditRepository + internal class AuditRepository : NPocoRepositoryBase, IAuditRepository { public AuditRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -63,11 +64,17 @@ namespace Umbraco.Core.Persistence.Repositories return dtos.Select(x => new AuditItem(x.NodeId, x.Comment, Enum.Parse(x.Header), x.UserId)).ToArray(); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); + return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs index e40460ee7d..d07ee15926 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Xml.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; @@ -14,7 +15,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Private class to handle preview insert/update based on standard principles and units of work with transactions /// - internal class ContentPreviewRepository : PetaPocoRepositoryBase> + internal class ContentPreviewRepository : NPocoRepositoryBase> where TContent : IContentBase { public ContentPreviewRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) @@ -38,7 +39,7 @@ namespace Umbraco.Core.Persistence.Repositories throw new NotImplementedException(); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { throw new NotImplementedException(); } diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 56f0af8490..c68fa123b1 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -7,6 +7,8 @@ using System.Linq.Expressions; using System.Net.Http.Headers; using System.Text; using System.Xml.Linq; +using NPoco; +using StackExchange.Profiling.Helpers.Dapper; using Umbraco.Core.Configuration; using Umbraco.Core.Dynamics; using Umbraco.Core.IO; @@ -63,10 +65,10 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false) .Where(GetBaseWhereClause(), new { Id = id }) - .Where(SqlSyntax, x => x.Newest) - .OrderByDescending(SqlSyntax, x => x.VersionDate); + .Where(x => x.Newest) + .OrderByDescending(x => x.VersionDate); - var dto = Database.Fetch(sql).FirstOrDefault(); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return null; @@ -85,9 +87,9 @@ namespace Umbraco.Core.Persistence.Repositories } //we only want the newest ones with this method - sql.Where(SqlSyntax, x => x.Newest); + sql.Where(x => x.Newest); - return ProcessQuery(sql); + return MapQueryDtos(Database.Fetch(sql)); } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -95,18 +97,18 @@ namespace Umbraco.Core.Persistence.Repositories var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate() - .Where(SqlSyntax, x => x.Newest) - .OrderByDescending(SqlSyntax, x => x.VersionDate) - .OrderBy(SqlSyntax, x => x.SortOrder); + .Where(x => x.Newest) + .OrderByDescending(x => x.VersionDate) + .OrderBy(x => x.SortOrder); - return ProcessQuery(sql); + return MapQueryDtos(Database.Fetch(sql)); } #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { var sqlx = string.Format("LEFT OUTER JOIN {0} {1} ON ({1}.{2}={0}.{2} AND {1}.{3}=1)", SqlSyntax.GetQuotedTableName("cmsDocument"), @@ -114,23 +116,32 @@ namespace Umbraco.Core.Persistence.Repositories SqlSyntax.GetQuotedColumnName("nodeId"), SqlSyntax.GetQuotedColumnName("published")); - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) + var sql = Sql(); - // cannot do this because PetaPoco does not know how to alias the table + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select(rr => + rr.Select(rrr => + rrr.Select())) + .Select(tableAlias: "cmsDocument2")); + + sql + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + + // cannot do this because NPoco does not know how to alias the table //.LeftOuterJoin() //.On(left => left.NodeId, right => right.NodeId) // so have to rely on writing our own SQL .Append(sqlx/*, new { @published = true }*/) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; } @@ -180,11 +191,11 @@ namespace Umbraco.Core.Persistence.Repositories //Remove all the data first, if anything fails after this it's no problem the transaction will be reverted if (contentTypeIds == null) { - var subQuery = new Sql() + var subQuery = Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId); var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Database.Execute(deleteSql); @@ -194,13 +205,13 @@ namespace Umbraco.Core.Persistence.Repositories foreach (var id in contentTypeIds) { var id1 = id; - var subQuery = new Sql() + var subQuery = Sql() .Select("cmsDocument.nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.Published) - .Where(SqlSyntax, dto => dto.ContentTypeId == id1); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.Published) + .Where( dto => dto.ContentTypeId == id1); var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Database.Execute(deleteSql); @@ -228,7 +239,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, Transaction tr, int pageSize) + private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, ITransaction tr, int pageSize) { var pageIndex = 0; var total = long.MinValue; @@ -240,10 +251,9 @@ namespace Umbraco.Core.Persistence.Repositories // because that method is used to query 'latest' content items where in this case we don't necessarily // want latest content items because a pulished content item might not actually be the latest. // see: http://issues.umbraco.org/issue/U4-6322 & http://issues.umbraco.org/issue/U4-5982 - var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, - new Tuple("cmsDocument", "nodeId"), - ProcessQuery, "Path", Direction.Ascending); - + var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, + MapQueryDtos, "Path", Direction.Ascending); + var xmlItems = (from descendant in descendants let xml = serializer(descendant) select new ContentXmlDto { NodeId = descendant.Id, Xml = xml.ToDataString() }).ToArray(); @@ -261,9 +271,9 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false); sql.Where("cmsContentVersion.VersionId = @VersionId", new { VersionId = versionId }); - sql.OrderByDescending(SqlSyntax, x => x.VersionDate); + sql.OrderByDescending(x => x.VersionDate); - var dto = Database.Fetch(sql).FirstOrDefault(); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return null; @@ -275,13 +285,13 @@ namespace Umbraco.Core.Persistence.Repositories public override void DeleteVersion(Guid versionId) { - var sql = new Sql() - .Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .Where(SqlSyntax, x => x.VersionId == versionId) - .Where(SqlSyntax, x => x.Newest != true); - var dto = Database.Fetch(sql).FirstOrDefault(); + var sql = Sql() + .SelectAll() + .From() + .InnerJoin().On(left => left.VersionId, right => right.VersionId) + .Where(x => x.VersionId == versionId) + .Where(x => x.Newest != true); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return; @@ -295,14 +305,14 @@ namespace Umbraco.Core.Persistence.Repositories public override void DeleteVersions(int id, DateTime versionDate) { - var sql = new Sql() - .Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .Where(SqlSyntax, x => x.NodeId == id) - .Where(SqlSyntax, x => x.VersionDate < versionDate) - .Where(SqlSyntax, x => x.Newest != true); - var list = Database.Fetch(sql); + var sql = Sql() + .SelectAll() + .From() + .InnerJoin().On(left => left.VersionId, right => right.VersionId) + .Where(x => x.NodeId == id) + .Where(x => x.VersionDate < versionDate) + .Where(x => x.Newest != true); + var list = Database.Fetch(sql); if (list.Any() == false) return; using (var transaction = Database.GetTransaction()) @@ -330,14 +340,14 @@ namespace Umbraco.Core.Persistence.Repositories protected override void PersistDeletedItem(IContent entity) { - //We need to clear out all access rules but we need to do this in a manual way since + //We need to clear out all access rules but we need to do this in a manual way since // nothing in that table is joined to a content id - var subQuery = new Sql() + var subQuery = Sql() .Select("umbracoAccessRule.accessId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.AccessId, right => right.Id) - .Where(SqlSyntax, dto => dto.NodeId == entity.Id); + .From() + .InnerJoin() + .On(left => left.AccessId, right => right.Id) + .Where(dto => dto.NodeId == entity.Id); Database.Execute(SqlSyntax.GetDeleteSubquery("umbracoAccessRule", "accessId", subQuery)); //now let the normal delete clauses take care of everything else @@ -377,7 +387,7 @@ namespace Umbraco.Core.Persistence.Repositories nodeDto.Path = parent.Path; nodeDto.Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)); nodeDto.SortOrder = sortOrder; - var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); + var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); //Update with new correct path nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId); @@ -390,7 +400,7 @@ namespace Umbraco.Core.Persistence.Repositories entity.Level = level; //Assign the same permissions to it as the parent node - // http://issues.umbraco.org/issue/U4-2161 + // http://issues.umbraco.org/issue/U4-2161 var permissionsRepo = new PermissionRepository(UnitOfWork, _cacheHelper, SqlSyntax); var parentPermissions = permissionsRepo.GetPermissionsForEntity(entity.ParentId).ToArray(); //if there are parent permissions then assign them, otherwise leave null and permissions will become the @@ -661,12 +671,12 @@ namespace Umbraco.Core.Persistence.Repositories var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate() - .Where(SqlSyntax, x => x.Published) - .OrderBy(SqlSyntax, x => x.Level) - .OrderBy(SqlSyntax, x => x.SortOrder); + .Where(x => x.Published) + .OrderBy(x => x.Level) + .OrderBy(x => x.SortOrder); //NOTE: This doesn't allow properties to be part of the query - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); foreach (var dto in dtos) { @@ -689,8 +699,8 @@ namespace Umbraco.Core.Persistence.Repositories public int CountPublished() { - var sql = GetBaseQuery(true).Where(SqlSyntax, x => x.Trashed == false) - .Where(SqlSyntax, x => x.Published == true); + var sql = GetBaseQuery(true).Where(x => x.Trashed == false) + .Where(x => x.Published == true); return Database.ExecuteScalar(sql); } @@ -716,7 +726,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - /// + /// public void AssignEntityPermission(IContent entity, char permission, IEnumerable userIds) { var repo = new PermissionRepository(UnitOfWork, _cacheHelper, SqlSyntax); @@ -772,26 +782,14 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetPagedResultsByQuery(IQuery query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, string filter = "") { - - //NOTE: This uses the GetBaseQuery method but that does not take into account the required 'newest' field which is - // what we always require for a paged result, so we'll ensure it's included in the filter - - var args = new List(); - var sbWhere = new StringBuilder("AND (cmsDocument.newest = 1)"); - + var filterSql = Sql().Append("AND (cmsDocument.newest = 1)"); if (filter.IsNullOrWhiteSpace() == false) - { - sbWhere.Append(" AND (cmsDocument." + SqlSyntax.GetQuotedColumnName("text") + " LIKE @" + args.Count + ")"); - args.Add("%" + filter + "%"); - } - - Func> filterCallback = () => new Tuple(sbWhere.ToString(), args.ToArray()); - - return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, - new Tuple("cmsDocument", "nodeId"), - ProcessQuery, orderBy, orderDirection, - filterCallback); + filterSql.Append("AND (cmsDocument." + SqlSyntax.GetQuotedColumnName("text") + " LIKE @0)", "%" + filter + "%"); + return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, + MapQueryDtos, + orderBy, orderDirection, + filterSql); } /// @@ -801,7 +799,7 @@ namespace Umbraco.Core.Persistence.Repositories /// public XElement GetContentXml(int contentId) { - var sql = new Sql().Select("*").From(SqlSyntax).Where(SqlSyntax, d => d.NodeId == contentId); + var sql = Sql().SelectAll().From().Where(d => d.NodeId == contentId); var dto = Database.SingleOrDefault(sql); if (dto == null) return null; return XElement.Parse(dto.Xml); @@ -815,8 +813,8 @@ namespace Umbraco.Core.Persistence.Repositories /// public XElement GetContentPreviewXml(int contentId, Guid version) { - var sql = new Sql().Select("*").From(SqlSyntax) - .Where(SqlSyntax, d => d.NodeId == contentId && d.VersionId == version); + var sql = Sql().SelectAll().From() + .Where(d => d.NodeId == contentId && d.VersionId == version); var dto = Database.SingleOrDefault(sql); if (dto == null) return null; return XElement.Parse(dto.Xml); @@ -848,11 +846,8 @@ namespace Umbraco.Core.Persistence.Repositories return base.GetDatabaseFieldNameForOrderBy(orderBy); } - private IEnumerable ProcessQuery(Sql sql) + private IEnumerable MapQueryDtos(List dtos) { - //NOTE: This doesn't allow properties to be part of the query - var dtos = Database.Fetch(sql); - //nothing found if (dtos.Any() == false) return Enumerable.Empty(); @@ -884,7 +879,7 @@ namespace Umbraco.Core.Persistence.Repositories d.dto.ContentVersionDto.ContentDto.NodeDto.CreateDate, d.contentType)); - var propertyData = GetPropertyCollection(sql, docDefs); + var propertyData = GetPropertyCollection(docDefs.ToArray()); return dtosWithContentTypes.Select(d => CreateContentFromDto( d.dto, @@ -950,7 +945,7 @@ namespace Umbraco.Core.Persistence.Repositories var docDef = new DocumentDefinition(dto.NodeId, versionId, content.UpdateDate, content.CreateDate, contentType); - var properties = GetPropertyCollection(docSql, new[] { docDef }); + var properties = GetPropertyCollection(new[] { docDef }); content.Properties = properties[dto.NodeId]; @@ -965,10 +960,10 @@ namespace Umbraco.Core.Persistence.Repositories if (EnsureUniqueNaming == false) return nodeName; - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName)); + var sql = Sql() + .SelectAll() + .From() + .Where(x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName)); int uniqueNumber = 1; var currentName = nodeName; diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs index 5055f60ab9..5856bea59a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; +using NPoco; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; using Umbraco.Core.Logging; @@ -16,7 +17,6 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Services; @@ -28,7 +28,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Exposes shared functionality /// - internal abstract class ContentTypeBaseRepository : PetaPocoRepositoryBase, IReadRepository + internal abstract class ContentTypeBaseRepository : NPocoRepositoryBase, IReadRepository where TEntity : class, IContentTypeComposition { protected ContentTypeBaseRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) @@ -92,24 +92,21 @@ namespace Umbraco.Core.Persistence.Repositories /// protected IEnumerable PerformGetByQuery(IQuery query) { - var sqlClause = new Sql(); - sqlClause.Select("*") - .From(SqlSyntax) - .RightJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeGroupId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId); + var sqlClause = Sql() + .SelectAll() + .From() + .RightJoin() + .On(left => left.Id, right => right.PropertyTypeGroupId) + .InnerJoin() + .On(left => left.DataTypeId, right => right.DataTypeId); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate() - .OrderBy(SqlSyntax, x => x.PropertyTypeGroupId); + .OrderBy(x => x.PropertyTypeGroupId); - var dtos = Database.Fetch(new GroupPropertyTypeRelator().Map, sql); - - foreach (var dto in dtos.DistinctBy(x => x.ContentTypeNodeId)) - { - yield return dto.ContentTypeNodeId; - } + return Database + .FetchOneToMany(x => x.PropertyTypeDtos, sql) + .Select(x => x.ContentTypeNodeId).Distinct(); } protected virtual PropertyType CreatePropertyType(string propertyEditorAlias, DataTypeDatabaseType dbType, string propertyTypeAlias) @@ -145,7 +142,7 @@ AND umbracoNode.nodeObjectType = @objectType", nodeDto.Path = parent.Path; nodeDto.Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)); nodeDto.SortOrder = sortOrder; - var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); + var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); //Update with new correct path nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId); @@ -272,15 +269,15 @@ AND umbracoNode.id <> @id", compositionBase.RemovedContentTypeKeyTracker.Any()) { //Find Content based on the current ContentType - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == new Guid(Constants.ObjectTypes.Document)) - .Where(SqlSyntax, x => x.ContentTypeId == entity.Id); + var sql = Sql() + .SelectAll() + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == new Guid(Constants.ObjectTypes.Document)) + .Where(x => x.ContentTypeId == entity.Id); - var contentDtos = Database.Fetch(sql); + var contentDtos = Database.Fetch(sql); //Loop through all tracked keys, which corresponds to the ContentTypes that has been removed from the composition foreach (var key in compositionBase.RemovedContentTypeKeyTracker) { @@ -294,13 +291,13 @@ AND umbracoNode.id <> @id", { var nodeId = contentDto.NodeId; var propertyTypeId = propertyType.Id; - var propertySql = new Sql().Select("cmsPropertyData.id") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, - left => left.PropertyTypeId, right => right.Id) - .Where(SqlSyntax, x => x.NodeId == nodeId) - .Where(SqlSyntax, x => x.Id == propertyTypeId); + var propertySql = Sql() + .Select("cmsPropertyData.id") + .From() + .InnerJoin() + .On(left => left.PropertyTypeId, right => right.Id) + .Where(x => x.NodeId == nodeId) + .Where(x => x.Id == propertyTypeId); //Finally delete the properties that match our criteria for removing a ContentType from the composition Database.Delete(new Sql("WHERE id IN (" + propertySql.SQL + ")", propertySql.Arguments)); @@ -424,30 +421,32 @@ AND umbracoNode.id <> @id", protected IEnumerable GetAllowedContentTypeIds(int id) { - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.AllowedId, right => right.NodeId) - .Where(SqlSyntax, x => x.Id == id); + var sql = Sql() + .SelectAll() + .From() + .LeftJoin() + .On(left => left.AllowedId, right => right.NodeId) + .Where(x => x.Id == id); - var allowedContentTypeDtos = Database.Fetch(sql); + var allowedContentTypeDtos = Database.Fetch(sql); return allowedContentTypeDtos.Select(x => new ContentTypeSort(new Lazy(() => x.AllowedId), x.SortOrder, x.ContentTypeDto.Alias)).ToList(); } protected PropertyGroupCollection GetPropertyGroupCollection(int id, DateTime createDate, DateTime updateDate) { - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeGroupId) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .Where(SqlSyntax, x => x.ContentTypeNodeId == id) - .OrderBy(SqlSyntax, x => x.Id); + var sql = Sql() + .SelectAll() + .From() + .LeftJoin() + .On(left => left.Id, right => right.PropertyTypeGroupId) + .LeftJoin() + .On(left => left.DataTypeId, right => right.DataTypeId) + .Where(x => x.ContentTypeNodeId == id) + .OrderBy(x => x.Id); - var dtos = Database.Fetch(new GroupPropertyTypeRelator().Map, sql); + + var dtos = Database + .Fetch(sql); var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate, CreatePropertyType); var propertyGroups = propertyGroupFactory.BuildEntity(dtos); @@ -456,14 +455,14 @@ AND umbracoNode.id <> @id", protected PropertyTypeCollection GetPropertyTypeCollection(int id, DateTime createDate, DateTime updateDate) { - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .Where(SqlSyntax, x => x.ContentTypeId == id); + var sql = Sql() + .SelectAll() + .From() + .InnerJoin() + .On(left => left.DataTypeId, right => right.DataTypeId) + .Where(x => x.ContentTypeId == id); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); //TODO Move this to a PropertyTypeFactory var list = new List(); @@ -531,11 +530,11 @@ AND umbracoNode.id <> @id", //we cannot try to assign a data type of it's empty if (propertyType.PropertyEditorAlias.IsNullOrWhiteSpace() == false) { - var sql = new Sql() - .Select("*") - .From(SqlSyntax) + var sql = Sql() + .SelectAll() + .From() .Where("propertyEditorAlias = @propertyEditorAlias", new { propertyEditorAlias = propertyType.PropertyEditorAlias }) - .OrderBy(SqlSyntax, typeDto => typeDto.DataTypeId); + .OrderBy(typeDto => typeDto.DataTypeId); var datatype = Database.FirstOrDefault(sql); //we cannot assign a data type if one was not found if (datatype != null) @@ -849,7 +848,7 @@ AND umbracoNode.id <> @id", return mediaType; } - internal static IEnumerable MapContentTypes(Database db, ISqlSyntaxProvider sqlSyntax, + internal static IEnumerable MapContentTypes(Database db, ISqlSyntaxProvider sqlSyntax, out IDictionary> associatedTemplates, out IDictionary> parentContentTypeIds) { diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs index 05dfebc786..02941434db 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; @@ -12,7 +13,6 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Services; @@ -39,7 +39,7 @@ namespace Umbraco.Core.Persistence.Repositories { //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory( - RuntimeCache, GetEntityId, () => PerformGetAll(), + RuntimeCache, GetEntityId, () => PerformGetAll(), //allow this cache to expire expires:true)); } @@ -67,9 +67,9 @@ namespace Umbraco.Core.Persistence.Repositories { var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); - var sql = translator.Translate(); + var sql = translator.Translate(); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); return //This returns a lookup from the GetAll cached looup @@ -79,7 +79,7 @@ namespace Umbraco.Core.Persistence.Repositories //order the result by name .OrderBy(x => x.Name); } - + /// /// Gets all entities of the specified query /// @@ -112,10 +112,11 @@ namespace Umbraco.Core.Persistence.Repositories /// public IEnumerable GetAllContentTypeAliases(params Guid[] objectTypes) { - var sql = new Sql().Select("cmsContentType.alias") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId); + var sql = Sql() + .Select("cmsContentType.alias") + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId); if (objectTypes.Any()) { @@ -125,17 +126,23 @@ namespace Umbraco.Core.Persistence.Repositories return Database.Fetch(sql); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); + var sql = Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.ContentTypeNodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select(rr => + rr.Select())); + + sql + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .LeftJoin() + .On(left => left.ContentTypeNodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; } @@ -169,7 +176,7 @@ namespace Umbraco.Core.Persistence.Repositories { get { return new Guid(Constants.ObjectTypes.DocumentType); } } - + /// /// Deletes a content type /// @@ -188,18 +195,19 @@ namespace Umbraco.Core.Persistence.Repositories PersistDeletedItem((IEntity)child); } - //Before we call the base class methods to run all delete clauses, we need to first + //Before we call the base class methods to run all delete clauses, we need to first // delete all of the property data associated with this document type. Normally this will // be done in the ContentTypeService by deleting all associated content first, but in some cases // like when we switch a document type, there is property data left over that is linked // to the previous document type. So we need to ensure it's removed. - var sql = new Sql().Select("DISTINCT cmsPropertyData.propertytypeid") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.PropertyTypeId, dto => dto.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.ContentTypeId) - .Where(SqlSyntax, dto => dto.NodeId == entity.Id); + var sql = Sql() + .Select("DISTINCT cmsPropertyData.propertytypeid") + .From() + .InnerJoin() + .On(dto => dto.PropertyTypeId, dto => dto.Id) + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.ContentTypeId) + .Where(dto => dto.NodeId == entity.Id); //Delete all cmsPropertyData where propertytypeid EXISTS in the subquery above Database.Execute(SqlSyntax.GetDeleteSubquery("cmsPropertyData", "propertytypeid", sql)); @@ -282,7 +290,7 @@ namespace Umbraco.Core.Persistence.Repositories entity.ResetDirtyProperties(); } - + protected override IContentType PerformGet(Guid id) { //use the underlying GetAll which will force cache all content types diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs index 4b7c8a273a..c6258fe9a8 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Xml.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; @@ -14,7 +15,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Internal class to handle content/published xml insert/update based on standard principles and units of work with transactions /// - internal class ContentXmlRepository : PetaPocoRepositoryBase> + internal class ContentXmlRepository : NPocoRepositoryBase> where TContent : IContentBase { public ContentXmlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) @@ -38,7 +39,7 @@ namespace Umbraco.Core.Persistence.Repositories throw new NotImplementedException(); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { throw new NotImplementedException(); } diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index 5bef1a2b5e..d6c9d05d54 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using System.Threading; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; @@ -25,7 +26,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents a repository for doing CRUD operations for /// - internal class DataTypeDefinitionRepository : PetaPocoRepositoryBase, IDataTypeDefinitionRepository + internal class DataTypeDefinitionRepository : NPocoRepositoryBase, IDataTypeDefinitionRepository { private readonly IContentTypeRepository _contentTypeRepository; private readonly DataTypePreValueRepository _preValRepository; @@ -56,10 +57,10 @@ namespace Umbraco.Core.Persistence.Repositories } else { - dataTypeSql.Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + dataTypeSql.Where(x => x.NodeObjectType == NodeObjectTypeId); } - var dtos = Database.Fetch(dataTypeSql); + var dtos = Database.Fetch(dataTypeSql); return dtos.Select(factory.BuildEntity).ToArray(); } @@ -71,7 +72,7 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); return dtos.Select(factory.BuildEntity).ToArray(); } @@ -111,16 +112,22 @@ namespace Umbraco.Core.Persistence.Repositories #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.DataTypeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select()); + + sql + .From() + .InnerJoin() + .On(left => left.DataTypeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; } @@ -175,7 +182,7 @@ WHERE umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + "= @name", new { n nodeDto.Path = parent.Path; nodeDto.Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)); nodeDto.SortOrder = sortOrder; - var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); + var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); //Update with new correct path nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId); @@ -275,8 +282,8 @@ AND umbracoNode.id <> @id", #endregion - - + + public PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId) { var cached = RuntimeCache.GetCacheItemsByKeySearch(GetPrefixedCacheKey(dataTypeId)); @@ -387,10 +394,11 @@ AND umbracoNode.id <> @id", if (dataType.HasIdentity) { //first just get all pre-values for this data type so we can compare them to see if we need to insert or update or replace - var sql = new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.DataTypeNodeId == dataType.Id) - .OrderBy(SqlSyntax, dto => dto.SortOrder); + var sql = Sql() + .SelectAll() + .From() + .Where(dto => dto.DataTypeNodeId == dataType.Id) + .OrderBy(dto => dto.SortOrder); currentVals = Database.Fetch(sql).ToArray(); } @@ -477,12 +485,12 @@ AND umbracoNode.id <> @id", private string EnsureUniqueNodeName(string nodeName, int id = 0) { - - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId && x.Text.StartsWith(nodeName)); + + var sql = Sql() + .SelectAll() + .From() + .Where(x => x.NodeObjectType == NodeObjectTypeId && x.Text.StartsWith(nodeName)); int uniqueNumber = 1; var currentName = nodeName; @@ -520,7 +528,7 @@ AND umbracoNode.id <> @id", /// /// Private class to handle pre-value crud based on standard principles and units of work with transactions /// - private class DataTypePreValueRepository : PetaPocoRepositoryBase + private class DataTypePreValueRepository : NPocoRepositoryBase { public DataTypePreValueRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -543,7 +551,7 @@ AND umbracoNode.id <> @id", throw new NotImplementedException(); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { throw new NotImplementedException(); } @@ -579,7 +587,7 @@ AND umbracoNode.id <> @id", } //NOTE: We used to check that the Alias was unique for the given DataTypeNodeId prevalues list, BUT - // in reality there is no need to check the uniqueness of this alias because the only way that this code executes is + // in reality there is no need to check the uniqueness of this alias because the only way that this code executes is // based on an IDictionary dictionary being passed to this repository and a dictionary // must have unique aliases by definition, so there is no need for this additional check @@ -599,10 +607,10 @@ AND umbracoNode.id <> @id", { throw new InvalidOperationException("Cannot update a pre value for a data type that has no identity"); } - + //NOTE: We used to check that the Alias was unique for the given DataTypeNodeId prevalues list, BUT // this causes issues when sorting the pre-values (http://issues.umbraco.org/issue/U4-5670) but in reality - // there is no need to check the uniqueness of this alias because the only way that this code executes is + // there is no need to check the uniqueness of this alias because the only way that this code executes is // based on an IDictionary dictionary being passed to this repository and a dictionary // must have unique aliases by definition, so there is no need for this additional check @@ -617,7 +625,7 @@ AND umbracoNode.id <> @id", Database.Update(dto); } - + } internal static class PreValueConverter diff --git a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs index 5d553801d3..c210a783fa 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -10,7 +11,6 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; @@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents a repository for doing CRUD operations for /// - internal class DictionaryRepository : PetaPocoRepositoryBase, IDictionaryRepository + internal class DictionaryRepository : NPocoRepositoryBase, IDictionaryRepository { private readonly IMappingResolver _mappingResolver; @@ -51,9 +51,12 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false) .Where(GetBaseWhereClause(), new { Id = id }) - .OrderBy(SqlSyntax, x => x.UniqueId); + .OrderBy(x => x.UniqueId); + + var dto = Database + .FetchOneToMany(x => x.LanguageTextDtos, sql) + .FirstOrDefault(); - var dto = Database.Fetch(new DictionaryLanguageTextRelator().Map, sql).FirstOrDefault(); if (dto == null) return null; @@ -74,8 +77,9 @@ namespace Umbraco.Core.Persistence.Repositories sql.Where("cmsDictionary.pk in (@ids)", new { ids = ids }); } - return Database.Fetch(new DictionaryLanguageTextRelator().Map, sql) - .Select(dto => ConvertFromDto(dto)); + return Database + .FetchOneToMany(x => x.LanguageTextDtos, sql) + .Select(dto => ConvertFromDto(dto)); } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -83,30 +87,31 @@ namespace Umbraco.Core.Persistence.Repositories var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - sql.OrderBy(SqlSyntax, x => x.UniqueId); + sql.OrderBy(x => x.UniqueId); - return Database.Fetch(new DictionaryLanguageTextRelator().Map, sql) + return Database + .FetchOneToMany(x => x.LanguageTextDtos, sql) .Select(x => ConvertFromDto(x)); } #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); + var sql = Sql(); if (isCount) { - sql.Select("COUNT(*)") - .From(SqlSyntax); + sql.SelectCount() + .From(); } else { - sql.Select("*") - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.UniqueId, right => right.UniqueId); + sql.SelectAll() + .From() + .LeftJoin() + .On(left => left.UniqueId, right => right.UniqueId); } return sql; } @@ -226,7 +231,7 @@ namespace Umbraco.Core.Persistence.Repositories var entity = factory.BuildEntity(dto); var list = new List(); - foreach (var textDto in dto.LanguageTextDtos) + foreach (var textDto in dto.LanguageTextDtos.EmptyNull()) { if (textDto.LanguageId <= 0) continue; @@ -273,15 +278,16 @@ namespace Umbraco.Core.Persistence.Repositories .Select(@group => { var sqlClause = GetBaseQuery(false) - .Where(SqlSyntax, x => x.Parent != null) + .Where(x => x.Parent != null) .Where(string.Format("{0} IN (@parentIds)", SqlSyntax.GetQuotedColumnName("parent")), new { parentIds = @group }); var translator = new SqlTranslator(sqlClause, Query); var sql = translator.Translate(); - sql.OrderBy(SqlSyntax, x => x.UniqueId); + sql.OrderBy(x => x.UniqueId); - return Database.Fetch(new DictionaryLanguageTextRelator().Map, sql) - .Select(x => ConvertFromDto(x)); + return Database + .FetchOneToMany(x=> x.LanguageTextDtos, sql) + .Select(ConvertFromDto); }); }; @@ -305,10 +311,11 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable PerformFetch(Sql sql) { - return Database.Fetch(new DictionaryLanguageTextRelator().Map, sql); + return Database + .FetchOneToMany(x => x.LanguageTextDtos, sql); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { return _dictionaryRepository.GetBaseQuery(isCount); } @@ -362,10 +369,11 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable PerformFetch(Sql sql) { - return Database.Fetch(new DictionaryLanguageTextRelator().Map, sql); + return Database + .FetchOneToMany(x => x.LanguageTextDtos, sql); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { return _dictionaryRepository.GetBaseQuery(isCount); } diff --git a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs index c24c0cd3fa..29de099ab9 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -17,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories { //TODO: We need to get a readonly ISO code for the domain assigned - internal class DomainRepository : PetaPocoRepositoryBase, IDomainRepository + internal class DomainRepository : NPocoRepositoryBase, IDomainRepository { public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -57,19 +58,19 @@ namespace Umbraco.Core.Persistence.Repositories throw new NotSupportedException("This repository does not support this method"); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); + var sql = Sql(); if (isCount) { - sql.Select("COUNT(*)").From(SqlSyntax); + sql.SelectCount().From(); } else { sql.Select("umbracoDomains.*, umbracoLanguage.languageISOCode") - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.DefaultLanguage, dto => dto.Id); + .From() + .LeftJoin() + .On(dto => dto.DefaultLanguage, dto => dto.Id); } return sql; diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs index 3e4c2f7ef6..353caedc00 100644 --- a/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -17,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// An internal repository for managing entity containers such as doc type, media type, data type containers. /// - internal class EntityContainerRepository : PetaPocoRepositoryBase + internal class EntityContainerRepository : NPocoRepositoryBase { private readonly Guid _containerObjectType; @@ -70,7 +71,7 @@ namespace Umbraco.Core.Persistence.Repositories .Where("nodeObjectType=@umbracoObjectTypeId", new { umbracoObjectTypeId = NodeObjectTypeId }) .Where(string.Format("{0} IN (@ids)", SqlSyntax.GetQuotedColumnName("id")), new { ids = @group }); - sql.OrderBy(SqlSyntax, x => x.Level); + sql.OrderBy(x => x.Level); return Database.Fetch(sql).Select(CreateEntity); }); @@ -101,17 +102,14 @@ namespace Umbraco.Core.Persistence.Repositories return entity; } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); + var sql = Sql(); if (isCount) - { - sql.Select("COUNT(*)").From(SqlSyntax); - } + sql.SelectCount(); else - { - sql.Select("*").From(SqlSyntax); - } + sql.SelectAll(); + sql.From(); return sql; } @@ -134,15 +132,15 @@ namespace Umbraco.Core.Persistence.Repositories { EnsureContainerType(entity); - var nodeDto = Database.FirstOrDefault(new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType)); + var nodeDto = Database.FirstOrDefault(Sql().SelectAll() + .From() + .Where(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType)); if (nodeDto == null) return; // move children to the parent so they are not orphans - var childDtos = Database.Fetch(new Sql().Select("*") - .From(SqlSyntax) + var childDtos = Database.Fetch(Sql().SelectAll() + .From() .Where("parentID=@parentID AND (nodeObjectType=@containedObjectType OR nodeObjectType=@containerObjectType)", new { @@ -169,9 +167,9 @@ namespace Umbraco.Core.Persistence.Repositories Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name"); // guard against duplicates - var nodeDto = Database.FirstOrDefault(new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType)); + var nodeDto = Database.FirstOrDefault(Sql().SelectAll() + .From() + .Where(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType)); if (nodeDto != null) throw new InvalidOperationException("A container with the same name already exists."); @@ -180,9 +178,9 @@ namespace Umbraco.Core.Persistence.Repositories var path = "-1"; if (entity.ParentId > -1) { - var parentDto = Database.FirstOrDefault(new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType)); + var parentDto = Database.FirstOrDefault(Sql().SelectAll() + .From() + .Where(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType)); if (parentDto == null) throw new NullReferenceException("Could not find parent container with id " + entity.ParentId); @@ -209,7 +207,7 @@ namespace Umbraco.Core.Persistence.Repositories // insert, get the id, update the path with the id var id = Convert.ToInt32(Database.Insert(nodeDto)); nodeDto.Path = nodeDto.Path + "," + nodeDto.NodeId; - Database.Save(nodeDto); + Database.Save(nodeDto); // refresh the entity entity.Id = id; @@ -230,16 +228,16 @@ namespace Umbraco.Core.Persistence.Repositories Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name"); // find container to update - var nodeDto = Database.FirstOrDefault(new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType)); + var nodeDto = Database.FirstOrDefault(Sql().SelectAll() + .From() + .Where(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType)); if (nodeDto == null) throw new InvalidOperationException("Could not find container with id " + entity.Id); // guard against duplicates - var dupNodeDto = Database.FirstOrDefault(new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType)); + var dupNodeDto = Database.FirstOrDefault(Sql().SelectAll() + .From() + .Where(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType)); if (dupNodeDto != null && dupNodeDto.NodeId != nodeDto.NodeId) throw new InvalidOperationException("A container with the same name already exists."); @@ -251,9 +249,9 @@ namespace Umbraco.Core.Persistence.Repositories nodeDto.Path = "-1"; if (entity.ParentId > -1) { - var parent = Database.FirstOrDefault(new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType)); + var parent = Database.FirstOrDefault( Sql().SelectAll() + .From() + .Where(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType)); if (parent == null) throw new NullReferenceException("Could not find parent container with id " + entity.ParentId); diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs index 190c34fa57..d79fc8aec4 100644 --- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs @@ -1,12 +1,8 @@ using System; using System.Collections.Generic; -using System.Dynamic; -using System.Globalization; using System.Linq; -using System.Reflection; -using System.Text; +using NPoco; using Umbraco.Core.Models; -using Umbraco.Core; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; @@ -14,7 +10,6 @@ using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; -using Umbraco.Core.Strings; namespace Umbraco.Core.Persistence.Repositories { @@ -26,13 +21,12 @@ namespace Umbraco.Core.Persistence.Repositories /// internal class EntityRepository : DisposableObject, IEntityRepository { - private readonly IDatabaseUnitOfWork _work; private readonly ISqlSyntaxProvider _sqlSyntax; private readonly QueryFactory _queryFactory; public EntityRepository(IDatabaseUnitOfWork work, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) { - _work = work; + UnitOfWork = work; _sqlSyntax = sqlSyntax; _queryFactory = new QueryFactory(_sqlSyntax, mappingResolver); } @@ -40,30 +34,23 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Returns the Unit of Work added to the repository /// - protected internal IDatabaseUnitOfWork UnitOfWork - { - get { return _work; } - } + protected internal IDatabaseUnitOfWork UnitOfWork { get; } /// /// Internal for testing purposes /// - internal Guid UnitKey - { - get { return (Guid)_work.Key; } - } + internal Guid UnitKey => (Guid) UnitOfWork.Key; #region Query Methods - public Query Query - { - get { return _queryFactory.Create(); } - } + public Query Query => _queryFactory.Create(); + + public Sql Sql() { return NPoco.Sql.BuilderFor(new SqlContext(_sqlSyntax, UnitOfWork.Database));} public IUmbracoEntity GetByKey(Guid key) { var sql = GetBaseWhere(GetBase, false, false, key); - var nodeDto = _work.Database.FirstOrDefault(sql); + var nodeDto = UnitOfWork.Database.FirstOrDefault(sql); if (nodeDto == null) return null; @@ -75,39 +62,35 @@ namespace Umbraco.Core.Persistence.Repositories public IUmbracoEntity GetByKey(Guid key, Guid objectTypeId) { - bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); - bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); + var isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); + var isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); var sql = GetFullSqlForEntityType(key, isContent, isMedia, objectTypeId); - + if (isMedia) { //for now treat media differently //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields - var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, sql); - - return entities.FirstOrDefault(); + return UnitOfWork.Database + .Fetch(sql) + .Transform(new UmbracoEntityRelator().MapAll) + .FirstOrDefault(); } - else - { - var nodeDto = _work.Database.FirstOrDefault(sql); - if (nodeDto == null) - return null; - var factory = new UmbracoEntityFactory(); - var entity = factory.BuildEntityFromDynamic(nodeDto); + var nodeDto = UnitOfWork.Database.FirstOrDefault(sql); + if (nodeDto == null) + return null; - return entity; - } - - + var factory = new UmbracoEntityFactory(); + var entity = factory.BuildEntityFromDynamic(nodeDto); + + return entity; } public virtual IUmbracoEntity Get(int id) { var sql = GetBaseWhere(GetBase, false, false, id); - var nodeDto = _work.Database.FirstOrDefault(sql); + var nodeDto = UnitOfWork.Database.FirstOrDefault(sql); if (nodeDto == null) return null; @@ -119,63 +102,49 @@ namespace Umbraco.Core.Persistence.Repositories public virtual IUmbracoEntity Get(int id, Guid objectTypeId) { - bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); - bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); + var isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); + var isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); var sql = GetFullSqlForEntityType(id, isContent, isMedia, objectTypeId); - + if (isMedia) { //for now treat media differently //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields - var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, sql); - - return entities.FirstOrDefault(); - } - else - { - var nodeDto = _work.Database.FirstOrDefault(sql); - if (nodeDto == null) - return null; - - var factory = new UmbracoEntityFactory(); - var entity = factory.BuildEntityFromDynamic(nodeDto); - - return entity; + return UnitOfWork.Database + .Fetch(sql) + .Transform(new UmbracoEntityRelator().MapAll) + .FirstOrDefault(); } - + var nodeDto = UnitOfWork.Database.FirstOrDefault(sql); + if (nodeDto == null) + return null; + + var factory = new UmbracoEntityFactory(); + var entity = factory.BuildEntityFromDynamic(nodeDto); + + return entity; } public virtual IEnumerable GetAll(Guid objectTypeId, params int[] ids) { - if (ids.Any()) - { - return PerformGetAll(objectTypeId, sql1 => sql1.Where(" umbracoNode.id in (@ids)", new {ids = ids})); - } - else - { - return PerformGetAll(objectTypeId); - } + return ids.Any() + ? PerformGetAll(objectTypeId, sql1 => sql1.Where(" umbracoNode.id in (@ids)", new { /*ids =*/ ids })) + : PerformGetAll(objectTypeId); } public virtual IEnumerable GetAll(Guid objectTypeId, params Guid[] keys) { - if (keys.Any()) - { - return PerformGetAll(objectTypeId, sql1 => sql1.Where(" umbracoNode.uniqueID in (@keys)", new { keys = keys })); - } - else - { - return PerformGetAll(objectTypeId); - } + return keys.Any() + ? PerformGetAll(objectTypeId, sql1 => sql1.Where(" umbracoNode.uniqueID in (@keys)", new { /*keys =*/ keys })) + : PerformGetAll(objectTypeId); } private IEnumerable PerformGetAll(Guid objectTypeId, Action filter = null) { - bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); - bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); + var isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); + var isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); var sql = GetFullSqlForEntityType(isContent, isMedia, objectTypeId, filter); var factory = new UmbracoEntityFactory(); @@ -184,23 +153,14 @@ namespace Umbraco.Core.Persistence.Repositories { //for now treat media differently //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields - var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, sql); - foreach (var entity in entities) - { - yield return entity; - } + return UnitOfWork.Database + .Fetch(sql) + .Transform(new UmbracoEntityRelator().MapAll); } - else - { - var dtos = _work.Database.Fetch(sql); - foreach (var entity in dtos.Select(dto => factory.BuildEntityFromDynamic(dto))) - { - yield return entity; - } - } - } + var dtos = UnitOfWork.Database.Fetch(sql); + return dtos.Select(dto => (UmbracoEntity) factory.BuildEntityFromDynamic(dto)); + } public virtual IEnumerable GetByQuery(IQuery query) { @@ -208,7 +168,7 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate().Append(GetGroupBy(false, false)); - var dtos = _work.Database.Fetch(sql); + var dtos = UnitOfWork.Database.Fetch(sql); var factory = new UmbracoEntityFactory(); var list = dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList(); @@ -218,12 +178,11 @@ namespace Umbraco.Core.Persistence.Repositories public virtual IEnumerable GetByQuery(IQuery query, Guid objectTypeId) { - - bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); - bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); + var isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); + var isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, null, objectTypeId); - + var translator = new SqlTranslator(sqlClause, query); var entitySql = translator.Translate(); @@ -242,82 +201,80 @@ namespace Umbraco.Core.Persistence.Repositories } }); - //treat media differently for now + //treat media differently for now //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields - var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, mediaSql); - return entities; - } - else - { - //use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData - var finalSql = entitySql.Append(GetGroupBy(isContent, false)); - var dtos = _work.Database.Fetch(finalSql); - return dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList(); + return UnitOfWork.Database + .Fetch(mediaSql) + .Transform(new UmbracoEntityRelator().MapAll); } + + //use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData + var finalSql = entitySql.Append(GetGroupBy(isContent, false)); + var dtos = UnitOfWork.Database.Fetch(finalSql); + return dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList(); } public UmbracoObjectTypes GetObjectType(int id) { - var sql = new Sql().Select("nodeObjectType").From(_sqlSyntax).Where(_sqlSyntax, x => x.NodeId == id); - var nodeObjectTypeId = _work.Database.ExecuteScalar(sql); + var sql = Sql().Select("nodeObjectType").From().Where(x => x.NodeId == id); + var nodeObjectTypeId = UnitOfWork.Database.ExecuteScalar(sql); var objectTypeId = nodeObjectTypeId; return UmbracoObjectTypesExtensions.GetUmbracoObjectType(objectTypeId); } public UmbracoObjectTypes GetObjectType(Guid key) { - var sql = new Sql().Select("nodeObjectType").From(_sqlSyntax).Where(_sqlSyntax, x => x.UniqueId == key); - var nodeObjectTypeId = _work.Database.ExecuteScalar(sql); + var sql = Sql().Select("nodeObjectType").From().Where(x => x.UniqueId == key); + var nodeObjectTypeId = UnitOfWork.Database.ExecuteScalar(sql); var objectTypeId = nodeObjectTypeId; return UmbracoObjectTypesExtensions.GetUmbracoObjectType(objectTypeId); } #endregion - + #region Sql Statements - protected Sql GetFullSqlForEntityType(Guid key, bool isContent, bool isMedia, Guid objectTypeId) + protected Sql GetFullSqlForEntityType(Guid key, bool isContent, bool isMedia, Guid objectTypeId) { var entitySql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, key); - if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false)); - - return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))); + return isMedia + ? GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))) + : entitySql.Append(GetGroupBy(isContent, false)); } - protected Sql GetFullSqlForEntityType(int id, bool isContent, bool isMedia, Guid objectTypeId) + protected Sql GetFullSqlForEntityType(int id, bool isContent, bool isMedia, Guid objectTypeId) { var entitySql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, id); - if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false)); - - return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))); + return isMedia + ? GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))) + : entitySql.Append(GetGroupBy(isContent, false)); } - protected Sql GetFullSqlForEntityType(bool isContent, bool isMedia, Guid objectTypeId, Action filter) + protected Sql GetFullSqlForEntityType(bool isContent, bool isMedia, Guid objectTypeId, Action> filter) { var entitySql = GetBaseWhere(GetBase, isContent, isMedia, filter, objectTypeId); - if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false)); - - return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)), filter); + return isMedia + ? GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)), filter) + : entitySql.Append(GetGroupBy(isContent, false)); } - private Sql GetFullSqlForMedia(Sql entitySql, Action filter = null) + private Sql GetFullSqlForMedia(Sql entitySql, Action> filter = null) { //this will add any dataNvarchar property to the output which can be added to the additional properties - var joinSql = new Sql() + var joinSql = Sql() .Select("contentNodeId, versionId, dataNvarchar, dataNtext, propertyEditorAlias, alias as propertyTypeAlias") - .From(_sqlSyntax) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, dto => dto.Id, dto => dto.PropertyTypeId) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, dto => dto.DataTypeId, dto => dto.DataTypeId) + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .InnerJoin() + .On(dto => dto.Id, dto => dto.PropertyTypeId) + .InnerJoin() + .On(dto => dto.DataTypeId, dto => dto.DataTypeId) .Where("umbracoNode.nodeObjectType = @nodeObjectType", new {nodeObjectType = Constants.ObjectTypes.Media}); if (filter != null) @@ -325,21 +282,22 @@ namespace Umbraco.Core.Persistence.Repositories filter(joinSql); } - //We're going to create a query to query against the entity SQL + //We're going to create a query to query against the entity SQL // because we cannot group by nText columns and we have a COUNT in the entitySql we cannot simply left join // the entitySql query, we have to join the wrapped query to get the ntext in the result - - var wrappedSql = new Sql("SELECT * FROM (") + + var wrappedSql = Sql() + .Append("SELECT * FROM (") .Append(entitySql) - .Append(new Sql(") tmpTbl LEFT JOIN (")) + .Append(") tmpTbl LEFT JOIN (") .Append(joinSql) - .Append(new Sql(") as property ON id = property.contentNodeId")) + .Append(") as property ON id = property.contentNodeId") .OrderBy("sortOrder, id"); return wrappedSql; } - protected virtual Sql GetBase(bool isContent, bool isMedia, Action customFilter) + protected virtual Sql GetBase(bool isContent, bool isMedia, Action> customFilter) { var columns = new List { @@ -369,10 +327,10 @@ namespace Umbraco.Core.Persistence.Repositories //Creates an SQL query to return a single row for the entity - var entitySql = new Sql() + var entitySql = Sql() .Select(columns.ToArray()) .From("umbracoNode umbracoNode"); - + if (isContent || isMedia) { entitySql.InnerJoin("cmsContent content").On("content.nodeId = umbracoNode.id") @@ -395,14 +353,14 @@ namespace Umbraco.Core.Persistence.Repositories return entitySql; } - protected virtual Sql GetBaseWhere(Func, Sql> baseQuery, bool isContent, bool isMedia, Action filter, Guid nodeObjectType) + protected virtual Sql GetBaseWhere(Func>, Sql> baseQuery, bool isContent, bool isMedia, Action> filter, Guid nodeObjectType) { var sql = baseQuery(isContent, isMedia, filter) .Where("umbracoNode.nodeObjectType = @NodeObjectType", new { NodeObjectType = nodeObjectType }); return sql; } - protected virtual Sql GetBaseWhere(Func, Sql> baseQuery, bool isContent, bool isMedia, int id) + protected virtual Sql GetBaseWhere(Func>, Sql> baseQuery, bool isContent, bool isMedia, int id) { var sql = baseQuery(isContent, isMedia, null) .Where("umbracoNode.id = @Id", new { Id = id }) @@ -410,7 +368,7 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - protected virtual Sql GetBaseWhere(Func, Sql> baseQuery, bool isContent, bool isMedia, Guid key) + protected virtual Sql GetBaseWhere(Func>, Sql> baseQuery, bool isContent, bool isMedia, Guid key) { var sql = baseQuery(isContent, isMedia, null) .Where("umbracoNode.uniqueID = @UniqueID", new { UniqueID = key }) @@ -418,7 +376,7 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - protected virtual Sql GetBaseWhere(Func, Sql> baseQuery, bool isContent, bool isMedia, Guid nodeObjectType, int id) + protected virtual Sql GetBaseWhere(Func>, Sql> baseQuery, bool isContent, bool isMedia, Guid nodeObjectType, int id) { var sql = baseQuery(isContent, isMedia, null) .Where("umbracoNode.id = @Id AND umbracoNode.nodeObjectType = @NodeObjectType", @@ -426,7 +384,7 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - protected virtual Sql GetBaseWhere(Func, Sql> baseQuery, bool isContent, bool isMedia, Guid nodeObjectType, Guid key) + protected virtual Sql GetBaseWhere(Func>, Sql> baseQuery, bool isContent, bool isMedia, Guid nodeObjectType, Guid key) { var sql = baseQuery(isContent, isMedia, null) .Where("umbracoNode.uniqueID = @UniqueID AND umbracoNode.nodeObjectType = @NodeObjectType", @@ -434,7 +392,7 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - protected virtual Sql GetGroupBy(bool isContent, bool isMedia, bool includeSort = true) + protected virtual Sql GetGroupBy(bool isContent, bool isMedia, bool includeSort = true) { var columns = new List { @@ -460,9 +418,8 @@ namespace Umbraco.Core.Persistence.Repositories columns.Add("contenttype.thumbnail"); columns.Add("contenttype.isContainer"); } - - var sql = new Sql() - .GroupBy(columns.ToArray()); + + var sql = Sql().GroupBy(columns.ToArray()); if (includeSort) { @@ -471,7 +428,7 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - + #endregion /// @@ -512,7 +469,7 @@ namespace Umbraco.Core.Persistence.Repositories [ResultColumn] public List UmbracoPropertyDtos { get; set; } } - + [ExplicitColumns] internal class UmbracoPropertyDto { @@ -542,52 +499,73 @@ namespace Umbraco.Core.Persistence.Repositories internal UmbracoEntity Current; private readonly UmbracoEntityFactory _factory = new UmbracoEntityFactory(); - internal UmbracoEntity Map(dynamic a, UmbracoPropertyDto p) + public IEnumerable MapAll(IEnumerable input) + { + UmbracoEntity entity; + + foreach (var x in input) + { + entity = Map(x); + if (entity != null) yield return entity; + } + + entity = Map((dynamic) null); + if (entity != null) yield return entity; + } + + // must be called one last time with null in order to return the last one! + public UmbracoEntity Map(dynamic a) { // Terminating call. Since we can return null from this function - // we need to be ready for PetaPoco to callback later with null + // we need to be ready for NPoco to callback later with null // parameters if (a == null) return Current; + string pPropertyEditorAlias = a.propertyEditorAlias; + var pExists = pPropertyEditorAlias != null; + string pPropertyAlias = a.propertyTypeAlias; + string pNTextValue = a.dataNtext; + string pNVarcharValue = a.dataNvarchar; + // Is this the same UmbracoEntity as the current one we're processing if (Current != null && Current.Key == a.uniqueID) { - if (p != null && p.PropertyAlias.IsNullOrWhiteSpace() == false) + if (pExists && pPropertyAlias.IsNullOrWhiteSpace() == false) { // Add this UmbracoProperty to the current additional data - Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + Current.AdditionalData[pPropertyAlias] = new UmbracoEntity.EntityProperty { - PropertyEditorAlias = p.PropertyEditorAlias, - Value = p.NTextValue.IsNullOrWhiteSpace() - ? p.NVarcharValue - : p.NTextValue.ConvertToJsonIfPossible() - }; + PropertyEditorAlias = pPropertyEditorAlias, + Value = pNTextValue.IsNullOrWhiteSpace() + ? pNVarcharValue + : pNTextValue.ConvertToJsonIfPossible() + }; } // Return null to indicate we're not done with this UmbracoEntity yet return null; } - // This is a different UmbracoEntity to the current one, or this is the + // This is a different UmbracoEntity to the current one, or this is the // first time through and we don't have a Tab yet // Save the current UmbracoEntityDto var prev = Current; // Setup the new current UmbracoEntity - + Current = _factory.BuildEntityFromDynamic(a); - if (p != null && p.PropertyAlias.IsNullOrWhiteSpace() == false) + if (pExists && pPropertyAlias.IsNullOrWhiteSpace() == false) { //add the property/create the prop list if null - Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + Current.AdditionalData[pPropertyAlias] = new UmbracoEntity.EntityProperty { - PropertyEditorAlias = p.PropertyEditorAlias, - Value = p.NTextValue.IsNullOrWhiteSpace() - ? p.NVarcharValue - : p.NTextValue.ConvertToJsonIfPossible() + PropertyEditorAlias = pPropertyEditorAlias, + Value = pNTextValue.IsNullOrWhiteSpace() + ? pNVarcharValue + : pNTextValue.ConvertToJsonIfPossible() }; } diff --git a/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs index 249ecef23d..aa5340232d 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ExternalLoginRepository.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.Identity; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Models.Identity; @@ -14,7 +15,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class ExternalLoginRepository : PetaPocoRepositoryBase, IExternalLoginRepository + internal class ExternalLoginRepository : NPocoRepositoryBase, IExternalLoginRepository { public ExternalLoginRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -122,17 +123,14 @@ namespace Umbraco.Core.Persistence.Repositories } } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); + var sql = Sql(); if (isCount) - { - sql.Select("COUNT(*)").From(SqlSyntax); - } + sql.SelectCount(); else - { - sql.Select("*").From(SqlSyntax); - } + sql.SelectAll(); + sql.From(); return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs index 8fbc122821..f0304ffa58 100644 --- a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -18,11 +19,11 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents a repository for doing CRUD operations for /// - internal class LanguageRepository : PetaPocoRepositoryBase, ILanguageRepository + internal class LanguageRepository : NPocoRepositoryBase, ILanguageRepository { public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) - { + { } private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory; @@ -54,9 +55,9 @@ namespace Umbraco.Core.Persistence.Repositories //this needs to be sorted since that is the way legacy worked - default language is the first one!! //even though legacy didn't sort, it should be by id - sql.OrderBy(SqlSyntax, dto => dto.Id); + sql.OrderBy(dto => dto.Id); + - return Database.Fetch(sql).Select(ConvertFromDto); } @@ -70,13 +71,18 @@ namespace Umbraco.Core.Persistence.Repositories #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); return sql; } @@ -166,6 +172,6 @@ namespace Umbraco.Core.Persistence.Repositories return GetAll().FirstOrDefault(x => x.IsoCode.InvariantEquals(isoCode)); } - + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs index 69274032a2..f3dbf6ec34 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -9,13 +10,12 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class MacroRepository : PetaPocoRepositoryBase, IMacroRepository + internal class MacroRepository : NPocoRepositoryBase, IMacroRepository { public MacroRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) @@ -28,7 +28,10 @@ namespace Umbraco.Core.Persistence.Repositories var sql = GetBaseQuery(false); sql.Where(GetBaseWhereClause(), new { Id = id }); - var macroDto = Database.Fetch(new MacroPropertyRelator().Map, sql).FirstOrDefault(); + var macroDto = Database + .FetchOneToMany(x => x.MacroPropertyDtos, sql) + .FirstOrDefault(); + if (macroDto == null) return null; @@ -51,8 +54,10 @@ namespace Umbraco.Core.Persistence.Repositories var sql = GetBaseQuery(false); - return ConvertFromDtos(Database.Fetch(new MacroPropertyRelator().Map, sql)) - .ToArray();// we don't want to re-iterate again! + return Database + .FetchOneToMany(x => x.MacroPropertyDtos, sql) + .Transform(ConvertFromDtos) + .ToArray(); // do it now and once } private IEnumerable PerformGetAllOnIds(params int[] ids) @@ -83,36 +88,23 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - var dtos = Database.Fetch(new MacroPropertyRelator().Map, sql); - - foreach (var dto in dtos) - { - yield return Get(dto.Id); - } + return Database + .FetchOneToMany(x => x.MacroPropertyDtos, sql) + .Select(x => Get(x.Id)); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - if (isCount) - { - sql.Select("COUNT(*)").From(SqlSyntax); - } - else - { - return GetBaseQuery(); - } - return sql; + return isCount ? Sql().SelectCount().From() : GetBaseQuery(); } - private Sql GetBaseQuery() + private Sql GetBaseQuery() { - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.Macro); - return sql; + return Sql() + .SelectAll() + .From() + .LeftJoin() + .On(left => left.Id, right => right.Macro); } protected override string GetBaseWhereClause() @@ -125,7 +117,7 @@ namespace Umbraco.Core.Persistence.Repositories var list = new List { "DELETE FROM cmsMacroProperty WHERE macro = @Id", - "DELETE FROM cmsMacro WHERE id = @Id" + "DELETE FROM cmsMacro WHERE id = @Id" }; return list; } @@ -208,7 +200,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - + } entity.ResetDirtyProperties(); @@ -230,7 +222,7 @@ namespace Umbraco.Core.Persistence.Repositories // { // return GetAll(new int[] {}); // } - + //} } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 2d1098164f..fbdbb8ca55 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Xml.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Dynamics; @@ -54,9 +55,9 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false); sql.Where(GetBaseWhereClause(), new { Id = id }); - sql.OrderByDescending(SqlSyntax, x => x.VersionDate); + sql.OrderByDescending(x => x.VersionDate); - var dto = Database.Fetch(sql).FirstOrDefault(); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return null; @@ -82,25 +83,33 @@ namespace Umbraco.Core.Persistence.Repositories var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate() - .OrderBy(SqlSyntax, x => x.SortOrder); + .OrderBy(x => x.SortOrder); return ProcessQuery(sql); } #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select(rr => + rr.Select())); + + sql + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } @@ -143,9 +152,9 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false); sql.Where("cmsContentVersion.VersionId = @VersionId", new { VersionId = versionId }); - sql.OrderByDescending(SqlSyntax, x => x.VersionDate); + sql.OrderByDescending(x => x.VersionDate); - var dto = Database.Fetch(sql).FirstOrDefault(); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return null; @@ -155,7 +164,7 @@ namespace Umbraco.Core.Persistence.Repositories var factory = new MediaFactory(mediaType, NodeObjectTypeId, dto.NodeId); var media = factory.BuildEntity(dto); - var properties = GetPropertyCollection(sql, new[] { new DocumentDefinition(dto.NodeId, dto.VersionId, media.UpdateDate, media.CreateDate, mediaType) }); + var properties = GetPropertyCollection(new[] { new DocumentDefinition(dto.NodeId, dto.VersionId, media.UpdateDate, media.CreateDate, mediaType) }); media.Properties = properties[dto.NodeId]; @@ -175,12 +184,12 @@ namespace Umbraco.Core.Persistence.Repositories if (contentTypeIds == null) { var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); - var subQuery = new Sql() + var subQuery = Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.NodeObjectType == mediaObjectType); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == mediaObjectType); var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Database.Execute(deleteSql); @@ -191,15 +200,15 @@ namespace Umbraco.Core.Persistence.Repositories { var id1 = id; var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); - var subQuery = new Sql() + var subQuery = Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.NodeObjectType == mediaObjectType) - .Where(SqlSyntax, dto => dto.ContentTypeId == id1); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == mediaObjectType) + .Where(dto => dto.ContentTypeId == id1); var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Database.Execute(deleteSql); @@ -226,7 +235,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, Transaction tr, int pageSize) + private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, ITransaction tr, int pageSize) { var pageIndex = 0; var total = long.MinValue; @@ -262,23 +271,23 @@ namespace Umbraco.Core.Persistence.Repositories umbracoFileValue = string.Concat(mediaPath.Substring(0, underscoreIndex), mediaPath.Substring(dotIndex)); } - Func createSql = url => new Sql().Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) - .Where(SqlSyntax, x => x.Alias == "umbracoFile") - .Where(SqlSyntax, x => x.VarChar == url); + Func createSql = url => Sql().SelectAll() + .From() + .InnerJoin() + .On(left => left.PropertyTypeId, right => right.Id) + .Where(x => x.Alias == "umbracoFile") + .Where(x => x.VarChar == url); var sql = createSql(umbracoFileValue); - var propertyDataDto = Database.Fetch(sql).FirstOrDefault(); + var propertyDataDto = Database.Fetch(sql).FirstOrDefault(); - // If the stripped-down url returns null, we try again with the original url. + // If the stripped-down url returns null, we try again with the original url. // Previously, the function would fail on e.g. "my_x_image.jpg" if (propertyDataDto == null) { sql = createSql(mediaPath); - propertyDataDto = Database.Fetch(sql).FirstOrDefault(); + propertyDataDto = Database.Fetch(sql).FirstOrDefault(); } return propertyDataDto == null ? null : Get(propertyDataDto.NodeId); @@ -332,7 +341,7 @@ namespace Umbraco.Core.Persistence.Repositories nodeDto.Path = parent.Path; nodeDto.Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)); nodeDto.SortOrder = sortOrder; - var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); + var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); //Update with new correct path nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId); @@ -484,28 +493,24 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetPagedResultsByQuery(IQuery query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, string filter = "") { - var args = new List(); - var sbWhere = new StringBuilder(); - Func> filterCallback = null; - if (filter.IsNullOrWhiteSpace() == false) - { - sbWhere.Append("AND (umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + " LIKE @" + args.Count + ")"); - args.Add("%" + filter + "%"); - filterCallback = () => new Tuple(sbWhere.ToString().Trim(), args.ToArray()); - } - - return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, - new Tuple("cmsContentVersion", "contentId"), - ProcessQuery, orderBy, orderDirection, - filterCallback); + var filterSql = filter.IsNullOrWhiteSpace() + ? null + : Sql().Append("AND (umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + " LIKE @0)", "%" + filter + "%"); + return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, + MapQueryDtos, orderBy, orderDirection, + filterSql); } private IEnumerable ProcessQuery(Sql sql) { //NOTE: This doesn't allow properties to be part of the query - var dtos = Database.Fetch(sql); - + var dtos = Database.Fetch(sql); + return MapQueryDtos(dtos); + } + + private IEnumerable MapQueryDtos(List dtos) + { var ids = dtos.Select(x => x.ContentDto.ContentTypeId).ToArray(); //content types @@ -527,7 +532,7 @@ namespace Umbraco.Core.Persistence.Repositories d.contentType)) .ToArray(); - var propertyData = GetPropertyCollection(sql, docDefs); + var propertyData = GetPropertyCollection(docDefs); return dtosWithContentTypes.Select(d => CreateMediaFromDto( d.dto, @@ -573,7 +578,7 @@ namespace Umbraco.Core.Persistence.Repositories var docDef = new DocumentDefinition(dto.NodeId, versionId, media.UpdateDate, media.CreateDate, contentType); - var properties = GetPropertyCollection(docSql, new[] { docDef }); + var properties = GetPropertyCollection(new[] { docDef }); media.Properties = properties[dto.NodeId]; @@ -588,10 +593,10 @@ namespace Umbraco.Core.Persistence.Repositories if (EnsureUniqueNaming == false) return nodeName; - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName)); + var sql = Sql() + .SelectAll() + .From() + .Where(x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName)); int uniqueNumber = 1; var currentName = nodeName; diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs index 4e1654c2ad..3d7eedd246 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; @@ -66,7 +67,7 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); return //This returns a lookup from the GetAll cached looup @@ -90,14 +91,21 @@ namespace Umbraco.Core.Persistence.Repositories : Enumerable.Empty(); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select()); + + sql + .From() + .InnerJoin() + .On( left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs index 291454d9d3..1ff51447ec 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Events; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -19,7 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories { - internal class MemberGroupRepository : PetaPocoRepositoryBase, IMemberGroupRepository + internal class MemberGroupRepository : NPocoRepositoryBase, IMemberGroupRepository { public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -40,24 +41,15 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable PerformGetAll(params int[] ids) { + var sql = Sql() + .SelectAll() + .From() + .Where(dto => dto.NodeObjectType == NodeObjectTypeId); + if (ids.Any()) - { - var sql = new Sql() - .Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeObjectType == NodeObjectTypeId) - .Where("umbracoNode.id in (@ids)", new { ids = ids }); - return Database.Fetch(sql) - .Select(x => _modelFactory.BuildEntity(x)); - } - else - { - var sql = new Sql() - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeObjectType == NodeObjectTypeId); - return Database.Fetch(sql) - .Select(x => _modelFactory.BuildEntity(x)); - } + sql.Where("umbracoNode.id in (@ids)", new { /*ids =*/ ids }); + + return Database.Fetch(sql).Select(x => _modelFactory.BuildEntity(x)); } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -66,16 +58,21 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - return Database.Fetch(sql) - .Select(x => _modelFactory.BuildEntity(x)); + return Database.Fetch(sql).Select(x => _modelFactory.BuildEntity(x)); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From() + .Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } @@ -110,7 +107,7 @@ namespace Umbraco.Core.Persistence.Repositories var group = (MemberGroup)entity; group.AddingEntity(); var dto = _modelFactory.BuildDto(group); - var o = Database.IsNew(dto) ? Convert.ToInt32(Database.Insert(dto)) : Database.Update(dto); + var o = Database.IsNew(dto) ? Convert.ToInt32(Database.Insert(dto)) : Database.Update(dto); group.Id = dto.NodeId; //Set Id on entity to ensure an Id is set //Update with new correct path and id @@ -176,13 +173,13 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetMemberGroupsForMember(int memberId) { - var sql = new Sql(); - sql.Select("umbracoNode.*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.MemberGroup) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.Member == memberId); + var sql = Sql() + .Select("umbracoNode.*") + .From() + .InnerJoin() + .On( dto => dto.NodeId, dto => dto.MemberGroup) + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.Member == memberId); return Database.Fetch(sql) .DistinctBy(dto => dto.NodeId) @@ -192,28 +189,28 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetMemberGroupsForMember(string username) { //find the member by username - var memberSql = new Sql(); var memberObjectType = new Guid(Constants.ObjectTypes.Member); - - memberSql.Select("umbracoNode.id") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == memberObjectType) - .Where(SqlSyntax, x => x.LoginName == username); + + var memberSql = Sql() + .Select("umbracoNode.id") + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .Where( x => x.NodeObjectType == memberObjectType) + .Where(x => x.LoginName == username); var memberIdUsername = Database.Fetch(memberSql).FirstOrDefault(); if (memberIdUsername.HasValue == false) { return Enumerable.Empty(); } - var sql = new Sql(); - sql.Select("umbracoNode.*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.MemberGroup) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.Member == memberIdUsername.Value); + var sql = Sql() + .Select("umbracoNode.*") + .From() + .InnerJoin() + .On( dto => dto.NodeId, dto => dto.MemberGroup) + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.Member == memberIdUsername.Value); return Database.Fetch(sql) .DistinctBy(dto => dto.NodeId) @@ -225,14 +222,15 @@ namespace Umbraco.Core.Persistence.Repositories using (var transaction = Database.GetTransaction()) { //first get the member ids based on the usernames - var memberSql = new Sql(); var memberObjectType = new Guid(Constants.ObjectTypes.Member); - memberSql.Select("umbracoNode.id") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == memberObjectType) - .Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames }); + + var memberSql = Sql() + .Select("umbracoNode.id") + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .Where(x => x.NodeObjectType == memberObjectType) + .Where("cmsMember.LoginName in (@usernames)", new { /*usernames =*/ usernames }); var memberIds = Database.Fetch(memberSql).ToArray(); AssignRolesInternal(memberIds, roleNames); @@ -245,14 +243,15 @@ namespace Umbraco.Core.Persistence.Repositories using (var transaction = Database.GetTransaction()) { //first get the member ids based on the usernames - var memberSql = new Sql(); var memberObjectType = new Guid(Constants.ObjectTypes.Member); - memberSql.Select("umbracoNode.id") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == memberObjectType) - .Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames }); + + var memberSql = Sql() + .Select("umbracoNode.id") + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .Where( x => x.NodeObjectType == memberObjectType) + .Where("cmsMember.LoginName in (@usernames)", new { /*usernames =*/ usernames }); var memberIds = Database.Fetch(memberSql).ToArray(); DissociateRolesInternal(memberIds, roleNames); @@ -276,10 +275,10 @@ namespace Umbraco.Core.Persistence.Repositories //create the missing roles first - var existingSql = new Sql() - .Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeObjectType == NodeObjectTypeId) + var existingSql = Sql() + .SelectAll() + .From() + .Where(dto => dto.NodeObjectType == NodeObjectTypeId) .Where("umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames }); var existingRoles = Database.Fetch(existingSql).Select(x => x.Text); var missingRoles = roleNames.Except(existingRoles); @@ -300,16 +299,16 @@ namespace Umbraco.Core.Persistence.Repositories //get the groups that are currently assigned to any of these members - var assignedSql = new Sql(); - assignedSql.Select(string.Format( + var assignedSql = Sql() + .Select(string.Format( "{0},{1},{2}", SqlSyntax.GetQuotedColumnName("text"), SqlSyntax.GetQuotedColumnName("Member"), SqlSyntax.GetQuotedColumnName("MemberGroup"))) - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.MemberGroup) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.MemberGroup) + .Where(x => x.NodeObjectType == NodeObjectTypeId) .Where("cmsMember2MemberGroup.Member in (@ids)", new { ids = memberIds }); var currentlyAssigned = Database.Fetch(assignedSql).ToArray(); @@ -343,15 +342,15 @@ namespace Umbraco.Core.Persistence.Repositories private void DissociateRolesInternal(int[] memberIds, string[] roleNames) { - var existingSql = new Sql() - .Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, dto => dto.NodeObjectType == NodeObjectTypeId) + var existingSql = Sql() + .SelectAll() + .From() + .Where(dto => dto.NodeObjectType == NodeObjectTypeId) .Where("umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames }); var existingRolesIds = Database.Fetch(existingSql).Select(x => x.NodeId).ToArray(); Database.Execute("DELETE FROM cmsMember2MemberGroup WHERE Member IN (@memberIds) AND MemberGroup IN (@memberGroups)", - new { memberIds = memberIds, memberGroups = existingRolesIds }); + new { /*memberIds =*/ memberIds, memberGroups = existingRolesIds }); } private class AssignedRolesDto diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index e1b2b877e3..a97c716894 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Linq.Expressions; using System.Text; using System.Xml.Linq; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; @@ -16,7 +17,6 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Dynamics; @@ -53,9 +53,9 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false); sql.Where(GetBaseWhereClause(), new { Id = id }); - sql.OrderByDescending(SqlSyntax, x => x.VersionDate); + sql.OrderByDescending(x => x.VersionDate); - var dto = Database.Fetch(sql).FirstOrDefault(); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return null; @@ -74,8 +74,8 @@ namespace Umbraco.Core.Persistence.Repositories sql.Where("umbracoNode.id in (@ids)", new { ids = ids }); } - return ProcessQuery(sql); - + return MapQueryDtos(Database.Fetch(sql)); + } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -93,42 +93,51 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlWithProps, query); var sql = translator.Translate(); - baseQuery.Append(new Sql("WHERE umbracoNode.id IN (" + sql.SQL + ")", sql.Arguments)) - .OrderBy(SqlSyntax, x => x.SortOrder); + baseQuery.Append("WHERE umbracoNode.id IN (" + sql.SQL + ")", sql.Arguments) + .OrderBy(x => x.SortOrder); - return ProcessQuery(baseQuery); + return MapQueryDtos(Database.Fetch(baseQuery)); } else { var translator = new SqlTranslator(baseQuery, query); var sql = translator.Translate() - .OrderBy(SqlSyntax, x => x.SortOrder); + .OrderBy(x => x.SortOrder); - return ProcessQuery(sql); + return MapQueryDtos(Database.Fetch(sql)); } } #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select(rr => + rr.Select(rrr => + rrr.Select()))); + + sql + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) //We're joining the type so we can do a query against the member type - not sure if this adds much overhead or not? // the execution plan says it doesn't so we'll go with that and in that case, it might be worth joining the content // types by default on the document and media repo's so we can query by content type there too. - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } @@ -138,21 +147,20 @@ namespace Umbraco.Core.Persistence.Repositories return "umbracoNode.id = @Id"; } - protected Sql GetNodeIdQueryWithPropertyData() + protected Sql GetNodeIdQueryWithPropertyData() { - var sql = new Sql(); - sql.Select("DISTINCT(umbracoNode.id)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeId, right => right.ContentTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) + return Sql() + .Select("DISTINCT(umbracoNode.id)") + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .LeftJoin().On(left => left.ContentTypeId, right => right.ContentTypeId) + .LeftJoin().On(left => left.DataTypeId, right => right.DataTypeId) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) .Append("AND cmsPropertyData.versionId = cmsContentVersion.VersionId") - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); - return sql; + .Where(x => x.NodeObjectType == NodeObjectTypeId); } protected override IEnumerable GetDeleteClauses() @@ -208,7 +216,7 @@ namespace Umbraco.Core.Persistence.Repositories nodeDto.Path = parent.Path; nodeDto.Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)); nodeDto.SortOrder = sortOrder; - var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); + var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); //Update with new correct path nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId); @@ -239,7 +247,7 @@ namespace Umbraco.Core.Persistence.Repositories //Add Properties // - don't try to save the property if it doesn't exist (or doesn't have an ID) on the content type // - this can occur if the member type doesn't contain the built-in properties that the - // - member object contains. + // - member object contains. var propsToPersist = entity.Properties.Where(x => x.PropertyType.HasIdentity).ToArray(); var propertyDataDtos = propertyFactory.BuildDto(propsToPersist); var keyDictionary = new Dictionary(); @@ -309,9 +317,9 @@ namespace Umbraco.Core.Persistence.Repositories //Updates the current version - cmsContentVersion //Assumes a Version guid exists and Version date (modified date) has been set/updated Database.Update(dto.ContentVersionDto); - + //Updates the cmsMember entry if it has changed - + //NOTE: these cols are the REAL column names in the db var changedCols = new List(); @@ -331,19 +339,19 @@ namespace Umbraco.Core.Persistence.Repositories //only update the changed cols if (changedCols.Count > 0) { - Database.Update(dto, changedCols); + Database.Update(dto, changedCols); } //TODO ContentType for the Member entity //Create the PropertyData for this version - cmsPropertyData - var propertyFactory = new PropertyFactory(entity.ContentType.CompositionPropertyTypes.ToArray(), entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType.CompositionPropertyTypes.ToArray(), entity.Version, entity.Id); var keyDictionary = new Dictionary(); //Add Properties // - don't try to save the property if it doesn't exist (or doesn't have an ID) on the content type // - this can occur if the member type doesn't contain the built-in properties that the - // - member object contains. + // - member object contains. var propsToPersist = entity.Properties.Where(x => x.PropertyType.HasIdentity).ToArray(); var propertyDataDtos = propertyFactory.BuildDto(propsToPersist); @@ -389,12 +397,12 @@ namespace Umbraco.Core.Persistence.Repositories if (contentTypeIds == null) { var memberObjectType = Guid.Parse(Constants.ObjectTypes.Member); - var subQuery = new Sql() + var subQuery = Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.NodeObjectType == memberObjectType); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == memberObjectType); var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Database.Execute(deleteSql); @@ -405,15 +413,15 @@ namespace Umbraco.Core.Persistence.Repositories { var id1 = id; var memberObjectType = Guid.Parse(Constants.ObjectTypes.Member); - var subQuery = new Sql() + var subQuery = Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.NodeObjectType == memberObjectType) - .Where(SqlSyntax, dto => dto.ContentTypeId == id1); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == memberObjectType) + .Where( dto => dto.ContentTypeId == id1); var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Database.Execute(deleteSql); @@ -441,7 +449,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, Transaction tr, int pageSize) + private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, ITransaction tr, int pageSize) { var pageIndex = 0; var total = long.MinValue; @@ -467,9 +475,9 @@ namespace Umbraco.Core.Persistence.Repositories { var sql = GetBaseQuery(false); sql.Where("cmsContentVersion.VersionId = @VersionId", new { VersionId = versionId }); - sql.OrderByDescending(SqlSyntax, x => x.VersionDate); + sql.OrderByDescending(x => x.VersionDate); - var dto = Database.Fetch(sql).FirstOrDefault(); + var dto = Database.Fetch(sql).FirstOrDefault(); if (dto == null) return null; @@ -479,7 +487,7 @@ namespace Umbraco.Core.Persistence.Repositories var factory = new MemberFactory(memberType, NodeObjectTypeId, dto.NodeId); var media = factory.BuildEntity(dto); - var properties = GetPropertyCollection(sql, new[] { new DocumentDefinition(dto.NodeId, dto.ContentVersionDto.VersionId, media.UpdateDate, media.CreateDate, memberType) }); + var properties = GetPropertyCollection(new[] { new DocumentDefinition(dto.NodeId, dto.ContentVersionDto.VersionId, media.UpdateDate, media.CreateDate, memberType) }); media.Properties = properties[dto.NodeId]; @@ -537,8 +545,8 @@ namespace Umbraco.Core.Persistence.Repositories foreach (var batch in inGroups) { var memberIdBatch = batch.Select(x => x.Id); - var sql = new Sql().Select("*").From(SqlSyntax) - .Where(SqlSyntax, dto => dto.MemberGroup == memberGroup.Id) + var sql = Sql().SelectAll().From() + .Where(dto => dto.MemberGroup == memberGroup.Id) .Where("Member IN (@memberIds)", new { memberIds = memberIdBatch }); var memberIdsInGroup = Database.Fetch(sql) .Select(x => x.Member).ToArray(); @@ -560,27 +568,26 @@ namespace Umbraco.Core.Persistence.Repositories var grpQry = QueryFactory.Create().Where(group => group.Name.Equals(groupName)); var memberGroup = _memberGroupRepository.GetByQuery(grpQry).FirstOrDefault(); if (memberGroup == null) return Enumerable.Empty(); - - var subQuery = new Sql().Select("Member").From(SqlSyntax).Where(SqlSyntax, dto => dto.MemberGroup == memberGroup.Id); + + var subQuery = Sql().Select("Member").From().Where(dto => dto.MemberGroup == memberGroup.Id); var sql = GetBaseQuery(false) //TODO: An inner join would be better, though I've read that the query optimizer will always turn a // subquery with an IN clause into an inner join anyways. - .Append(new Sql("WHERE umbracoNode.id IN (" + subQuery.SQL + ")", subQuery.Arguments)) - .OrderByDescending(SqlSyntax, x => x.VersionDate) - .OrderBy(SqlSyntax, x => x.SortOrder); - - return ProcessQuery(sql); + .Append("WHERE umbracoNode.id IN (" + subQuery.SQL + ")", subQuery.Arguments) + .OrderByDescending(x => x.VersionDate) + .OrderBy(x => x.SortOrder); + + return MapQueryDtos(Database.Fetch(sql)); } public bool Exists(string username) { - var sql = new Sql(); - - sql.Select("COUNT(*)") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.LoginName == username); + var sql = Sql() + .SelectCount() + .From() + .Where(x => x.LoginName == username); return Database.ExecuteScalar(sql) > 0; } @@ -594,7 +601,7 @@ namespace Umbraco.Core.Persistence.Repositories //get the COUNT base query var fullSql = GetBaseQuery(true) .Append(new Sql("WHERE umbracoNode.id IN (" + sql.SQL + ")", sql.Arguments)); - + return Database.ExecuteScalar(fullSql); } @@ -612,28 +619,21 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - /// The query supplied will ONLY work with data specifically on the cmsMember table because we are using PetaPoco paging (SQL paging) + /// The query supplied will ONLY work with data specifically on the cmsMember table because we are using NPoco paging (SQL paging) /// public IEnumerable GetPagedResultsByQuery(IQuery query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, string filter = "") { - var args = new List(); - var sbWhere = new StringBuilder(); - Func> filterCallback = null; - if (filter.IsNullOrWhiteSpace() == false) - { - sbWhere.Append("AND ((umbracoNode. " + SqlSyntax.GetQuotedColumnName("text") + " LIKE @" + args.Count + ") " + - "OR (cmsMember.LoginName LIKE @0" + args.Count + "))"); - args.Add("%" + filter + "%"); - filterCallback = () => new Tuple(sbWhere.ToString().Trim(), args.ToArray()); - } + var filterSql = filter.IsNullOrWhiteSpace() + ? null + : Sql().Append("AND ((umbracoNode. " + SqlSyntax.GetQuotedColumnName("text") + " LIKE @0) " + + "OR (cmsMember.LoginName LIKE @0))", "%" + filter + "%"); - return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, - new Tuple("cmsMember", "nodeId"), - ProcessQuery, orderBy, orderDirection, - filterCallback); + return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, + MapQueryDtos, orderBy, orderDirection, + filterSql); } - + public void AddOrUpdateContentXml(IMember content, Func xml) { _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(content, xml)); @@ -658,23 +658,8 @@ namespace Umbraco.Core.Persistence.Repositories return base.GetDatabaseFieldNameForOrderBy(orderBy); } - protected override string GetEntityPropertyNameForOrderBy(string orderBy) + private IEnumerable MapQueryDtos(List dtos) { - //Some custom ones - switch (orderBy.ToUpperInvariant()) - { - case "LOGINNAME": - return "Username"; - } - - return base.GetEntityPropertyNameForOrderBy(orderBy); - } - - private IEnumerable ProcessQuery(Sql sql) - { - //NOTE: This doesn't allow properties to be part of the query - var dtos = Database.Fetch(sql); - var ids = dtos.Select(x => x.ContentVersionDto.ContentDto.ContentTypeId).ToArray(); //content types @@ -695,12 +680,12 @@ namespace Umbraco.Core.Persistence.Repositories d.dto.ContentVersionDto.ContentDto.NodeDto.CreateDate, d.contentType)); - var propertyData = GetPropertyCollection(sql, docDefs); + var propertyData = GetPropertyCollection(docDefs.ToArray()); return dtosWithContentTypes.Select(d => CreateMemberFromDto( d.dto, contentTypes.First(ct => ct.Id == d.dto.ContentVersionDto.ContentDto.ContentTypeId), - propertyData[d.dto.NodeId])); + propertyData[d.dto.NodeId])); } /// @@ -741,7 +726,7 @@ namespace Umbraco.Core.Persistence.Repositories var docDef = new DocumentDefinition(dto.ContentVersionDto.NodeId, versionId, member.UpdateDate, member.CreateDate, memberType); - var properties = GetPropertyCollection(docSql, new[] { docDef }); + var properties = GetPropertyCollection(new[] { docDef }); member.Properties = properties[dto.ContentVersionDto.NodeId]; diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs index 172d2f8296..21f46eb800 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using log4net; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models.EntityBase; @@ -11,7 +12,6 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; @@ -40,7 +40,7 @@ namespace Umbraco.Core.Persistence.Repositories expires: true)); } } - + protected override IMemberType PerformGet(int id) { //use the underlying GetAll which will force cache all content types @@ -56,11 +56,12 @@ namespace Umbraco.Core.Persistence.Repositories var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.id='{0}'", x))); sql.Where(statement); } - sql.OrderByDescending(SqlSyntax, x => x.NodeId); + sql.OrderByDescending(x => x.NodeId); - var dtos = - Database.Fetch( - new PropertyTypePropertyGroupRelator().Map, sql); + var dtos = Database + .Fetch(sql) // cannot use FetchOneToMany because we have 2 collections! + .Transform(MapOneToManies) + .ToList(); return BuildFromDtos(dtos); } @@ -71,57 +72,89 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlSubquery, query); var subquery = translator.Translate(); var sql = GetBaseQuery(false) - .Append(new Sql("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments)) - .OrderBy(SqlSyntax, x => x.SortOrder); + .Append("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments) + .OrderBy(x => x.SortOrder); - var dtos = - Database.Fetch( - new PropertyTypePropertyGroupRelator().Map, sql); + var dtos = Database + .Fetch(sql) // cannot use FetchOneToMany because we have 2 collections! + .Transform(MapOneToManies) + .ToList(); return BuildFromDtos(dtos); } - - protected override Sql GetBaseQuery(bool isCount) - { - var sql = new Sql(); - if (isCount) + private IEnumerable MapOneToManies(IEnumerable dtos) + { + MemberTypeReadOnlyDto acc = null; + foreach (var dto in dtos) { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); - return sql; + if (acc == null) + { + acc = dto; + } + else if (acc.UniqueId == dto.UniqueId) + { + var prop = dto.PropertyTypes.SingleOrDefault(); + var group = dto.PropertyTypeGroups.SingleOrDefault(); + + if (prop != null && prop.Id.HasValue && acc.PropertyTypes.Any(x => x.Id == prop.Id.Value) == false) + acc.PropertyTypes.Add(prop); + + if (group != null && group.Id.HasValue && acc.PropertyTypeGroups.Any(x => x.Id == group.Id.Value) == false) + acc.PropertyTypeGroups.Add(group); + } + else + { + yield return acc; + acc = dto; + } } - sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias", - "cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.mandatory", - "cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", - "cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", - "cmsDataType.propertyEditorAlias", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId", - "cmsPropertyTypeGroup.text AS PropertyGroupName", - "cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder", "cmsPropertyTypeGroup.contenttypeNodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeNodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + if (acc != null) + yield return acc; + } + + protected override Sql GetBaseQuery(bool isCount) + { + if (isCount) + { + return Sql() + .SelectCount() + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); + } + + var sql = Sql() + .Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias", + "cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.mandatory", + "cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", + "cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", + "cmsDataType.propertyEditorAlias", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId", + "cmsPropertyTypeGroup.text AS PropertyGroupName", + "cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder", "cmsPropertyTypeGroup.contenttypeNodeId") + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .LeftJoin().On(left => left.ContentTypeId, right => right.NodeId) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) + .LeftJoin().On(left => left.DataTypeId, right => right.DataTypeId) + .LeftJoin().On(left => left.ContentTypeNodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } - protected Sql GetSubquery() + protected Sql GetSubquery() { - var sql = new Sql() + var sql = Sql() .Select("DISTINCT(umbracoNode.id)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeNodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .LeftJoin().On(left => left.ContentTypeId, right => right.NodeId) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) + .LeftJoin().On(left => left.DataTypeId, right => right.DataTypeId) + .LeftJoin().On(left => left.ContentTypeNodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; } @@ -154,13 +187,13 @@ namespace Umbraco.Core.Persistence.Repositories { get { return new Guid(Constants.ObjectTypes.MemberType); } } - + protected override void PersistNewItem(IMemberType entity) { ValidateAlias(entity); ((MemberType)entity).AddingEntity(); - + //set a default icon if one is not specified if (entity.Icon.IsNullOrWhiteSpace()) { @@ -225,7 +258,7 @@ namespace Umbraco.Core.Persistence.Repositories entity.ResetDirtyProperties(); } - + /// /// Override so we can specify explicit db type's on any property types that are built-in. /// @@ -311,7 +344,7 @@ namespace Umbraco.Core.Persistence.Repositories } /// - /// If this is one of our internal properties - we will manually assign the data type since they must + /// If this is one of our internal properties - we will manually assign the data type since they must /// always correspond to the correct db type no matter what the backing data type is assigned. /// /// @@ -338,7 +371,7 @@ namespace Umbraco.Core.Persistence.Repositories } /// - /// + /// /// /// /// diff --git a/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs index c10e9169a4..1749ae8be3 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MigrationEntryRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Semver; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -13,7 +14,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class MigrationEntryRepository : PetaPocoRepositoryBase, IMigrationEntryRepository + internal class MigrationEntryRepository : NPocoRepositoryBase, IMigrationEntryRepository { public MigrationEntryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -63,11 +64,17 @@ namespace Umbraco.Core.Persistence.Repositories return Database.Fetch(sql).Select(x => factory.BuildEntity(x)); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); + return sql; } @@ -119,9 +126,9 @@ namespace Umbraco.Core.Persistence.Repositories { var versionString = version.ToString(); - var sql = new Sql().Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.Name.InvariantEquals(migrationName) && x.Version == versionString); + var sql = Sql().SelectAll() + .From() + .Where(x => x.Name.InvariantEquals(migrationName) && x.Version == versionString); var result = Database.FirstOrDefault(sql); diff --git a/src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs similarity index 65% rename from src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs rename to src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs index 569865e688..24eeb93fd9 100644 --- a/src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data.SqlServerCe; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Persistence.Mappers; @@ -11,57 +12,49 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { /// - /// Represent an abstract Repository for PetaPoco based repositories + /// Represent an abstract Repository for NPoco based repositories /// /// /// - internal abstract class PetaPocoRepositoryBase : RepositoryBase + internal abstract class NPocoRepositoryBase : RepositoryBase where TEntity : class, IAggregateRoot { - public ISqlSyntaxProvider SqlSyntax { get; private set; } + public ISqlSyntaxProvider SqlSyntax { get; } - private readonly QueryFactory _queryFactory; /// /// Returns the Query factory /// - public override QueryFactory QueryFactory - { - get { return _queryFactory; } - } + public override QueryFactory QueryFactory { get; } /// /// Used to create a new query instance /// /// - public override Query Query - { - get { return QueryFactory.Create(); } - } + public override Query Query => QueryFactory.Create(); - protected PetaPocoRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) + protected NPocoRepositoryBase(IUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger) { - if (sqlSyntax == null) throw new ArgumentNullException("sqlSyntax"); + if (sqlSyntax == null) throw new ArgumentNullException(nameof(sqlSyntax)); SqlSyntax = sqlSyntax; - _queryFactory = new QueryFactory(SqlSyntax, mappingResolver); + QueryFactory = new QueryFactory(SqlSyntax, mappingResolver); } /// /// Returns the database Unit of Work added to the repository /// - protected internal new IDatabaseUnitOfWork UnitOfWork - { - get { return (IDatabaseUnitOfWork)base.UnitOfWork; } - } + protected internal new IDatabaseUnitOfWork UnitOfWork => (IDatabaseUnitOfWork) base.UnitOfWork; - protected UmbracoDatabase Database + protected UmbracoDatabase Database => UnitOfWork.Database; + + protected Sql Sql() { - get { return UnitOfWork.Database; } + return NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, Database)); } #region Abstract Methods - - protected abstract Sql GetBaseQuery(bool isCount); + + protected abstract Sql GetBaseQuery(bool isCount); protected abstract string GetBaseWhereClause(); protected abstract IEnumerable GetDeleteClauses(); protected abstract Guid NodeObjectTypeId { get; } @@ -96,7 +89,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - protected virtual TId GetEntityId(TEntity entity) + protected virtual new TId GetEntityId(TEntity entity) { return (TId)(object)entity.Id; } diff --git a/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs b/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs index 668fdf4b5b..67b36caa86 100644 --- a/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Models.Membership; @@ -23,13 +24,13 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetUserNotifications(IUser user) { - var sql = new Sql() + var sql = NPoco.Sql.BuilderFor(new SqlContext(_sqlSyntax, _unitOfWork.Database)) .Select("DISTINCT umbracoNode.id, umbracoUser2NodeNotify.userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action") - .From(_sqlSyntax) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .Where(_sqlSyntax, dto => dto.UserId == (int)user.Id) - .OrderBy(_sqlSyntax, dto => dto.NodeId); + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .Where(dto => dto.UserId == (int)user.Id) + .OrderBy(dto => dto.NodeId); var dtos = _unitOfWork.Database.Fetch(sql); //need to map the results @@ -50,13 +51,13 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetEntityNotifications(IEntity entity) { - var sql = new Sql() + var sql = NPoco.Sql.BuilderFor(new SqlContext(_sqlSyntax, _unitOfWork.Database)) .Select("DISTINCT umbracoNode.id, umbracoUser2NodeNotify.userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action") - .From(_sqlSyntax) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, dto => dto.NodeId, dto => dto.NodeId) - .Where(_sqlSyntax, dto => dto.NodeId == entity.Id) - .OrderBy(_sqlSyntax, dto => dto.NodeId); + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) + .Where(dto => dto.NodeId == entity.Id) + .OrderBy(dto => dto.NodeId); var dtos = _unitOfWork.Database.Fetch(sql); //need to map the results @@ -81,10 +82,10 @@ namespace Umbraco.Core.Persistence.Repositories public Notification CreateNotification(IUser user, IEntity entity, string action) { - var sql = new Sql() + var sql = NPoco.Sql.BuilderFor(new SqlContext(_sqlSyntax, _unitOfWork.Database)) .Select("DISTINCT nodeObjectType") - .From(_sqlSyntax) - .Where(_sqlSyntax, nodeDto => nodeDto.NodeId == entity.Id); + .From() + .Where(nodeDto => nodeDto.NodeId == entity.Id); var nodeType = _unitOfWork.Database.ExecuteScalar(sql); var dto = new User2NodeNotifyDto() diff --git a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs index 8be1dc1b6d..8b37a2b6f1 100644 --- a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs @@ -4,8 +4,10 @@ using System.Collections.Generic; using System.Dynamic; using System.Globalization; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Web.Caching; +using NPoco; using Umbraco.Core.Events; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Models.Membership; @@ -78,9 +80,9 @@ namespace Umbraco.Core.Persistence.Repositories whereBuilder.Append(")"); } - var sql = new Sql(); - sql.Select("*") - .From(_sqlSyntax) + var sql = NPoco.Sql.BuilderFor(new SqlContext(_sqlSyntax, _unitOfWork.Database)) + .SelectAll() + .From() .Where(whereBuilder.ToString()); //ToArray() to ensure it's all fetched from the db once. @@ -103,11 +105,11 @@ namespace Umbraco.Core.Persistence.Repositories /// public IEnumerable GetPermissionsForEntity(int entityId) { - var sql = new Sql(); - sql.Select("*") - .From(_sqlSyntax) - .Where(_sqlSyntax, dto => dto.NodeId == entityId) - .OrderBy(_sqlSyntax, dto => dto.NodeId); + var sql = NPoco.Sql.BuilderFor(new SqlContext(_sqlSyntax, _unitOfWork.Database)) + .SelectAll() + .From() + .Where(dto => dto.NodeId == entityId) + .OrderBy(dto => dto.NodeId); //ToArray() to ensure it's all fetched from the db once. var result = _unitOfWork.Database.Fetch(sql).ToArray(); diff --git a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs index 3b3538b220..c389bce2f7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -8,13 +9,12 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class PublicAccessRepository : PetaPocoRepositoryBase, IPublicAccessRepository + internal class PublicAccessRepository : NPocoRepositoryBase, IPublicAccessRepository { public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -48,7 +48,7 @@ namespace Umbraco.Core.Persistence.Repositories } var factory = new PublicAccessEntryFactory(); - var dtos = Database.Fetch(new AccessRulesRelator().Map, sql); + var dtos = Database.FetchOneToMany(x => x.Rules, sql); return dtos.Select(factory.BuildEntity); } @@ -59,19 +59,17 @@ namespace Umbraco.Core.Persistence.Repositories var sql = translator.Translate(); var factory = new PublicAccessEntryFactory(); - var dtos = Database.Fetch(new AccessRulesRelator().Map, sql); + var dtos = Database.FetchOneToMany(x => x.Rules, sql); return dtos.Select(factory.BuildEntity); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.AccessId); - - return sql; + return Sql() + .SelectAll() + .From() + .LeftJoin() + .On(left => left.Id, right => right.AccessId); } protected override string GetBaseWhereClause() @@ -164,6 +162,6 @@ namespace Umbraco.Core.Persistence.Repositories return entity.Key; } - + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs index e7b2d664b9..5f6be8eca7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; @@ -109,21 +110,19 @@ namespace Umbraco.Core.Persistence.Repositories /// internal List GetFilesInRecycleBinForUploadField() { - var db = this.Database; - //Issue query to get all trashed content or media that has the Upload field as a property //The value for each field is stored in a list: FilesToDelete() //Alias: Constants.Conventions.Media.File and PropertyEditorAlias: Constants.PropertyEditors.UploadField - var sql = new Sql(); - sql.Select("DISTINCT(dataNvarchar)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) + var sql = Sql() + .Select("DISTINCT(dataNvarchar)") + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.PropertyTypeId, right => right.Id) + .InnerJoin().On(left => left.DataTypeId, right => right.DataTypeId) .Where("umbracoNode.trashed = '1' AND umbracoNode.nodeObjectType = @NodeObjectType AND dataNvarchar IS NOT NULL AND (cmsPropertyType.Alias = @FileAlias OR cmsDataType.propertyEditorAlias = @PropertyEditorAlias)", new { FileAlias = Constants.Conventions.Media.File, NodeObjectType = NodeObjectTypeId, PropertyEditorAlias = Constants.PropertyEditors.UploadFieldAlias }); - var files = db.Fetch(sql); + var files = Database.Fetch(sql); return files; } } diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs index b6c312e4da..a021aca520 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -17,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents a repository for doing CRUD operations for /// - internal class RelationRepository : PetaPocoRepositoryBase, IRelationRepository + internal class RelationRepository : NPocoRepositoryBase, IRelationRepository { private readonly IRelationTypeRepository _relationTypeRepository; @@ -89,13 +90,19 @@ namespace Umbraco.Core.Persistence.Repositories #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); + return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs index b3ce9fa14d..db3bf84620 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -17,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents a repository for doing CRUD operations for /// - internal class RelationTypeRepository : PetaPocoRepositoryBase, IRelationTypeRepository + internal class RelationTypeRepository : NPocoRepositoryBase, IRelationTypeRepository { public RelationTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) @@ -81,13 +82,19 @@ namespace Umbraco.Core.Persistence.Repositories #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); + return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs index 2926525f48..dd576ce899 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -14,7 +15,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class ServerRegistrationRepository : PetaPocoRepositoryBase, IServerRegistrationRepository + internal class ServerRegistrationRepository : NPocoRepositoryBase, IServerRegistrationRepository { private readonly ICacheProvider _staticCache; @@ -59,11 +60,17 @@ namespace Umbraco.Core.Persistence.Repositories throw new NotSupportedException("This repository does not support this method"); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); + return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs b/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs index 2f0a2321d6..e5d941ba4b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/SimpleGetRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Persistence.Mappers; @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Simple abstract ReadOnly repository used to simply have PerformGet and PeformGetAll with an underlying cache /// - internal abstract class SimpleGetRepository : PetaPocoRepositoryBase + internal abstract class SimpleGetRepository : NPocoRepositoryBase where TEntity : class, IAggregateRoot where TDto: class { @@ -56,11 +57,11 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable PerformGetAll(params TId[] ids) { - var sql = new Sql().From(SqlSyntax); + var sql = Sql().From(); if (ids.Any()) { - sql.Where(GetWhereInClauseForGetAll(), new { ids = ids }); + sql.Where(GetWhereInClauseForGetAll(), new { /*ids =*/ ids }); } return Database.Fetch(sql).Select(ConvertToEntity); diff --git a/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs index add3f21729..df5cc4883f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TagRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -15,7 +16,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class TagRepository : PetaPocoRepositoryBase, ITagRepository + internal class TagRepository : NPocoRepositoryBase, ITagRepository { public TagRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -92,25 +93,14 @@ namespace Umbraco.Core.Persistence.Repositories } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - if (isCount) - { - sql.Select("COUNT(*)").From(SqlSyntax); - } - else - { - return GetBaseQuery(); - } - return sql; + return isCount ? Sql().SelectCount().From() : GetBaseQuery(); } - private Sql GetBaseQuery() + private Sql GetBaseQuery() { - var sql = new Sql(); - sql.Select("*").From(SqlSyntax); - return sql; + return Sql().SelectAll().From(); } protected override string GetBaseWhereClause() @@ -165,60 +155,60 @@ namespace Umbraco.Core.Persistence.Repositories public TaggedEntity GetTaggedEntityByKey(Guid key) { - var sql = new Sql() + var sql = Sql() .Select("cmsTagRelationship.nodeId, cmsPropertyType.Alias, cmsPropertyType.id as propertyTypeId, cmsTags.tag, cmsTags.id as tagId, cmsTags." + SqlSyntax.GetQuotedColumnName("group")) - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.TagId, right => right.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.UniqueId == key); + .From() + .InnerJoin() + .On(left => left.TagId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.Id, right => right.PropertyTypeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.UniqueId == key); return CreateTaggedEntityCollection(Database.Fetch(sql)).FirstOrDefault(); } public TaggedEntity GetTaggedEntityById(int id) { - var sql = new Sql() + var sql = Sql() .Select("cmsTagRelationship.nodeId, cmsPropertyType.Alias, cmsPropertyType.id as propertyTypeId, cmsTags.tag, cmsTags.id as tagId, cmsTags." + SqlSyntax.GetQuotedColumnName("group")) - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.TagId, right => right.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.NodeId == id); + .From() + .InnerJoin() + .On(left => left.TagId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.Id, right => right.PropertyTypeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeId == id); return CreateTaggedEntityCollection(Database.Fetch(sql)).FirstOrDefault(); } public IEnumerable GetTaggedEntitiesByTagGroup(TaggableObjectTypes objectType, string tagGroup) { - var sql = new Sql() + var sql = Sql() .Select("cmsTagRelationship.nodeId, cmsPropertyType.Alias, cmsPropertyType.id as propertyTypeId, cmsTags.tag, cmsTags.id as tagId, cmsTags." + SqlSyntax.GetQuotedColumnName("group")) - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.TagId, right => right.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.Group == tagGroup); + .From() + .InnerJoin() + .On(left => left.TagId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.Id, right => right.PropertyTypeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.Group == tagGroup); if (objectType != TaggableObjectTypes.All) { var nodeObjectType = GetNodeObjectType(objectType); sql = sql - .Where(SqlSyntax, dto => dto.NodeObjectType == nodeObjectType); + .Where(dto => dto.NodeObjectType == nodeObjectType); } return CreateTaggedEntityCollection( @@ -227,29 +217,29 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetTaggedEntitiesByTag(TaggableObjectTypes objectType, string tag, string tagGroup = null) { - var sql = new Sql() + var sql = Sql() .Select("cmsTagRelationship.nodeId, cmsPropertyType.Alias, cmsPropertyType.id as propertyTypeId, cmsTags.tag, cmsTags.id as tagId, cmsTags." + SqlSyntax.GetQuotedColumnName("group")) - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.TagId, right => right.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, dto => dto.Tag == tag); + .From() + .InnerJoin() + .On(left => left.TagId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.Id, right => right.PropertyTypeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.Tag == tag); if (objectType != TaggableObjectTypes.All) { var nodeObjectType = GetNodeObjectType(objectType); sql = sql - .Where(SqlSyntax, dto => dto.NodeObjectType == nodeObjectType); + .Where(dto => dto.NodeObjectType == nodeObjectType); } if (tagGroup.IsNullOrWhiteSpace() == false) { - sql = sql.Where(SqlSyntax, dto => dto.Group == tagGroup); + sql = sql.Where(dto => dto.Group == tagGroup); } return CreateTaggedEntityCollection( @@ -275,12 +265,12 @@ namespace Umbraco.Core.Persistence.Repositories var sql = GetTagsQuerySelect(true); sql = ApplyRelationshipJoinToTagsQuery(sql); - + if (objectType != TaggableObjectTypes.All) { var nodeObjectType = GetNodeObjectType(objectType); sql = sql - .Where(SqlSyntax, dto => dto.NodeObjectType == nodeObjectType); + .Where(dto => dto.NodeObjectType == nodeObjectType); } sql = ApplyGroupFilterToTagsQuery(sql, group); @@ -297,7 +287,7 @@ namespace Umbraco.Core.Persistence.Repositories sql = ApplyRelationshipJoinToTagsQuery(sql); sql = sql - .Where(SqlSyntax, dto => dto.NodeId == contentId); + .Where(dto => dto.NodeId == contentId); sql = ApplyGroupFilterToTagsQuery(sql, group); @@ -311,7 +301,7 @@ namespace Umbraco.Core.Persistence.Repositories sql = ApplyRelationshipJoinToTagsQuery(sql); sql = sql - .Where(SqlSyntax, dto => dto.UniqueId == contentId); + .Where(dto => dto.UniqueId == contentId); sql = ApplyGroupFilterToTagsQuery(sql, group); @@ -325,10 +315,10 @@ namespace Umbraco.Core.Persistence.Repositories sql = ApplyRelationshipJoinToTagsQuery(sql); sql = sql - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeId) - .Where(SqlSyntax, dto => dto.NodeId == contentId) - .Where(SqlSyntax, dto => dto.Alias == propertyTypeAlias); + .InnerJoin() + .On(left => left.Id, right => right.PropertyTypeId) + .Where(dto => dto.NodeId == contentId) + .Where(dto => dto.Alias == propertyTypeAlias); sql = ApplyGroupFilterToTagsQuery(sql, group); @@ -342,19 +332,19 @@ namespace Umbraco.Core.Persistence.Repositories sql = ApplyRelationshipJoinToTagsQuery(sql); sql = sql - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.PropertyTypeId) - .Where(SqlSyntax, dto => dto.UniqueId == contentId) - .Where(SqlSyntax, dto => dto.Alias == propertyTypeAlias); + .InnerJoin() + .On(left => left.Id, right => right.PropertyTypeId) + .Where(dto => dto.UniqueId == contentId) + .Where(dto => dto.Alias == propertyTypeAlias); sql = ApplyGroupFilterToTagsQuery(sql, group); return ExecuteTagsQuery(sql); } - private Sql GetTagsQuerySelect(bool withGrouping = false) + private Sql GetTagsQuerySelect(bool withGrouping = false) { - var sql = new Sql(); + var sql = Sql(); if (withGrouping) { @@ -368,31 +358,31 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - private Sql ApplyRelationshipJoinToTagsQuery(Sql sql) + private Sql ApplyRelationshipJoinToTagsQuery(Sql sql) { return sql - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.TagId, right => right.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId); + .From() + .InnerJoin() + .On(left => left.TagId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId); } - private Sql ApplyGroupFilterToTagsQuery(Sql sql, string group) + private Sql ApplyGroupFilterToTagsQuery(Sql sql, string group) { - if (@group.IsNullOrWhiteSpace() == false) + if (group.IsNullOrWhiteSpace() == false) { - sql = sql.Where(SqlSyntax, dto => dto.Group == group); + sql = sql.Where(dto => dto.Group == group); } return sql; } - private Sql ApplyGroupByToTagsQuery(Sql sql) + private Sql ApplyGroupByToTagsQuery(Sql sql) { - return sql.GroupBy(new string[] { "cmsTags.id", "cmsTags.tag", "cmsTags." + SqlSyntax.GetQuotedColumnName("group") + @"" }); + return sql.GroupBy("cmsTags.id", "cmsTags.tag", "cmsTags." + SqlSyntax.GetQuotedColumnName("group") + @""); } private IEnumerable ExecuteTagsQuery(Sql sql) @@ -409,7 +399,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// The tags to assign /// - /// If set to true, this will replace all tags with the given tags, + /// If set to true, this will replace all tags with the given tags, /// if false this will append the tags that already exist for the content item /// /// @@ -436,8 +426,8 @@ namespace Umbraco.Core.Persistence.Repositories } //ok so now we're actually assigning tags... - //NOTE: There's some very clever logic in the umbraco.cms.businesslogic.Tags.Tag to insert tags where they don't exist, - // and assign where they don't exist which we've borrowed here. The queries are pretty zany but work, otherwise we'll end up + //NOTE: There's some very clever logic in the umbraco.cms.businesslogic.Tags.Tag to insert tags where they don't exist, + // and assign where they don't exist which we've borrowed here. The queries are pretty zany but work, otherwise we'll end up // with quite a few additional queries. //do all this in one transaction @@ -522,7 +512,7 @@ namespace Umbraco.Core.Persistence.Repositories public void ClearTagsFromProperty(int contentId, int propertyTypeId) { - Database.Execute("DELETE FROM cmsTagRelationship WHERE nodeId = @nodeId AND propertyTypeId = @propertyTypeId", + Database.Execute("DELETE FROM cmsTagRelationship WHERE nodeId = @nodeId AND propertyTypeId = @propertyTypeId", new { nodeId = contentId, propertyTypeId = propertyTypeId }); } @@ -549,18 +539,19 @@ namespace Umbraco.Core.Persistence.Repositories /// /// This is a clever way to produce an SQL statement like this: - /// - /// (select 'Spacesdd' as Tag, 'default' as [Group] - /// union + /// + /// (select 'Spacesdd' as Tag, 'default' as [Group] + /// union /// select 'Cool' as Tag, 'default' as [Group] /// ) as TagSet - /// - /// This allows us to use the tags to be inserted as a temporary in memory table. + /// + /// This allows us to use the tags to be inserted as a temporary in memory table. /// /// /// private string GetTagSet(IEnumerable tagsToInsert) { + // fixme.npoco //TODO: Fix this query, since this is going to be basically a unique query each time, this will cause some mem usage in peta poco, // and surely there's a nicer way! //TODO: When we fix, be sure to remove the @ symbol escape @@ -568,7 +559,7 @@ namespace Umbraco.Core.Persistence.Repositories var array = tagsToInsert .Select(tag => string.Format("select '{0}' as Tag, '{1}' as " + SqlSyntax.GetQuotedColumnName("group") + @"", - PetaPocoExtensions.EscapeAtSymbols(tag.Text.Replace("'", "''")), tag.Group)) + NPocoDatabaseExtensions.EscapeAtSymbols(tag.Text.Replace("'", "''")), tag.Group)) .ToArray(); return "(" + string.Join(" union ", array).Replace(" ", " ") + ") as TagSet"; } diff --git a/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs index c2793dcc1b..f87dacc911 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TaskRepository.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using AutoMapper; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -14,7 +15,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class TaskRepository : PetaPocoRepositoryBase, ITaskRepository + internal class TaskRepository : NPocoRepositoryBase, ITaskRepository { public TaskRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -26,7 +27,7 @@ namespace Umbraco.Core.Persistence.Repositories var sql = GetBaseQuery(false); sql.Where(GetBaseWhereClause(), new { Id = id }); - var taskDto = Database.Fetch(sql).FirstOrDefault(); + var taskDto = Database.Fetch(sql).FirstOrDefault(); if (taskDto == null) return null; @@ -45,7 +46,7 @@ namespace Umbraco.Core.Persistence.Repositories } var factory = new TaskFactory(); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); return dtos.Select(factory.BuildEntity); } @@ -56,34 +57,24 @@ namespace Umbraco.Core.Persistence.Repositories var sql = translator.Translate(); var factory = new TaskFactory(); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); return dtos.Select(factory.BuildEntity); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - if (isCount) - { - sql.Select("COUNT(*)").From(SqlSyntax); - } - else - { - return GetBaseQuery(); - } - return sql; + return isCount ? Sql().SelectCount().From() : GetBaseQuery(); } - private Sql GetBaseQuery() + private Sql GetBaseQuery() { - var sql = new Sql(); - sql.Select("cmsTask.closed,cmsTask.id,cmsTask.taskTypeId,cmsTask.nodeId,cmsTask.parentUserId,cmsTask.userId,cmsTask." + SqlSyntax.GetQuotedColumnName("DateTime") + ",cmsTask.Comment,cmsTaskType.id, cmsTaskType.alias") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.TaskTypeId, right => right.Id) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId); - return sql; + return Sql() + .Select("cmsTask.closed,cmsTask.id,cmsTask.taskTypeId,cmsTask.nodeId,cmsTask.parentUserId,cmsTask.userId,cmsTask." + SqlSyntax.GetQuotedColumnName("DateTime") + ",cmsTask.Comment,cmsTaskType.id, cmsTaskType.alias") + .From() + .InnerJoin() + .On(left => left.TaskTypeId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId); } protected override string GetBaseWhereClause() @@ -95,7 +86,7 @@ namespace Umbraco.Core.Persistence.Repositories { var list = new List { - "DELETE FROM cmsTask WHERE id = @Id" + "DELETE FROM cmsTask WHERE id = @Id" }; return list; } @@ -147,21 +138,21 @@ namespace Umbraco.Core.Persistence.Repositories var sql = GetGetTasksQuery(assignedUser, ownerUser, taskTypeAlias, includeClosed); if (itemId.HasValue) { - sql.Where(SqlSyntax, dto => dto.NodeId == itemId.Value); + sql.Where(dto => dto.NodeId == itemId.Value); } - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); var factory = new TaskFactory(); return dtos.Select(factory.BuildEntity); } - private Sql GetGetTasksQuery(int? assignedUser = null, int? ownerUser = null, string taskTypeAlias = null, bool includeClosed = false) + private Sql GetGetTasksQuery(int? assignedUser = null, int? ownerUser = null, string taskTypeAlias = null, bool includeClosed = false) { var sql = GetBaseQuery(false); if (includeClosed == false) { - sql.Where(SqlSyntax, dto => dto.Closed == false); + sql.Where(dto => dto.Closed == false); } if (taskTypeAlias.IsNullOrWhiteSpace() == false) { @@ -169,11 +160,11 @@ namespace Umbraco.Core.Persistence.Repositories } if (ownerUser.HasValue) { - sql.Where(SqlSyntax, dto => dto.ParentUserId == ownerUser.Value); + sql.Where(dto => dto.ParentUserId == ownerUser.Value); } if (assignedUser.HasValue) { - sql.Where(SqlSyntax, dto => dto.UserId == assignedUser.Value); + sql.Where(dto => dto.UserId == assignedUser.Value); } return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs index aef8debd1f..cc26450962 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TaskTypeRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; @@ -12,7 +13,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal class TaskTypeRepository : PetaPocoRepositoryBase, ITaskTypeRepository + internal class TaskTypeRepository : NPocoRepositoryBase, ITaskTypeRepository { public TaskTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -58,11 +59,9 @@ namespace Umbraco.Core.Persistence.Repositories return dtos.Select(factory.BuildEntity); } - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select("*").From(SqlSyntax); - return sql; + return Sql().SelectAll().From(); } protected override string GetBaseWhereClause() diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs index 32f5f63d98..e4379119c2 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; @@ -27,7 +28,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents the Template Repository /// - internal class TemplateRepository : PetaPocoRepositoryBase, ITemplateRepository + internal class TemplateRepository : NPocoRepositoryBase, ITemplateRepository { private readonly IFileSystem _masterpagesFileSystem; private readonly IFileSystem _viewsFileSystem; @@ -75,14 +76,14 @@ namespace Umbraco.Core.Persistence.Repositories } else { - sql.Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + sql.Where(x => x.NodeObjectType == NodeObjectTypeId); } - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); if (dtos.Count == 0) return Enumerable.Empty(); - //look up the simple template definitions that have a master template assigned, this is used + //look up the simple template definitions that have a master template assigned, this is used // later to populate the template item's properties var childIds = (ids.Any() ? GetAxisDefinitions(dtos.ToArray()) @@ -92,7 +93,7 @@ namespace Umbraco.Core.Persistence.Repositories ParentId = x.NodeDto.ParentId, Name = x.Alias })).ToArray(); - + return dtos.Select(d => MapFromDto(d, childIds)); } @@ -102,11 +103,11 @@ namespace Umbraco.Core.Persistence.Repositories var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - var dtos = Database.Fetch(sql); + var dtos = Database.Fetch(sql); if (dtos.Count == 0) return Enumerable.Empty(); - //look up the simple template definitions that have a master template assigned, this is used + //look up the simple template definitions that have a master template assigned, this is used // later to populate the template item's properties var childIds = GetAxisDefinitions(dtos.ToArray()).ToArray(); @@ -115,16 +116,23 @@ namespace Umbraco.Core.Persistence.Repositories #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(r => + r.Select()); + + sql + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); + return sql; } @@ -166,7 +174,7 @@ namespace Umbraco.Core.Persistence.Repositories //Create the (base) node data - umbracoNode var nodeDto = dto.NodeDto; nodeDto.Path = "-1," + dto.NodeDto.NodeId; - var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); + var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto); //Update with new correct path var parent = Get(template.MasterTemplateId.Value); @@ -325,23 +333,23 @@ namespace Umbraco.Core.Persistence.Repositories { var masterpageName = string.Concat(entity.Alias, ".master"); _masterpagesFileSystem.DeleteFile(masterpageName); - } + } } #endregion private IEnumerable GetAxisDefinitions(params TemplateDto[] templates) { - //look up the simple template definitions that have a master template assigned, this is used + //look up the simple template definitions that have a master template assigned, this is used // later to populate the template item's properties - var childIdsSql = new Sql() + var childIdsSql = Sql() .Select("nodeId,alias,parentID") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId) + .From() + .InnerJoin() + .On(dto => dto.NodeId, dto => dto.NodeId) //lookup axis's .Where("umbracoNode." + SqlSyntax.GetQuotedColumnName("id") + " IN (@parentIds) OR umbracoNode.parentID IN (@childIds)", - new {parentIds = templates.Select(x => x.NodeDto.ParentId), childIds = templates.Select(x => x.NodeId)}); + new {parentIds = templates.Select(x => x.NodeDto.ParentId), childIds = templates.Select(x => x.NodeId)}); var childIds = Database.Fetch(childIdsSql) .Select(x => new UmbracoEntity @@ -571,7 +579,7 @@ namespace Umbraco.Core.Persistence.Repositories /// [Obsolete("Use GetDescendants instead")] public TemplateNode GetTemplateNode(string alias) - { + { //first get all template objects var allTemplates = base.GetAll().ToArray(); @@ -580,7 +588,7 @@ namespace Umbraco.Core.Persistence.Repositories { return null; } - + var top = selfTemplate; while (top.MasterTemplateAlias.IsNullOrWhiteSpace() == false) { @@ -631,16 +639,16 @@ namespace Umbraco.Core.Persistence.Repositories } /// - /// This checks what the default rendering engine is set in config but then also ensures that there isn't already - /// a template that exists in the opposite rendering engine's template folder, then returns the appropriate + /// This checks what the default rendering engine is set in config but then also ensures that there isn't already + /// a template that exists in the opposite rendering engine's template folder, then returns the appropriate /// rendering engine to use. - /// + /// /// /// /// The reason this is required is because for example, if you have a master page file already existing under ~/masterpages/Blah.aspx - /// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml - /// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page. - /// This is mostly related to installing packages since packages install file templates to the file system and then create the + /// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml + /// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page. + /// This is mostly related to installing packages since packages install file templates to the file system and then create the /// templates in business logic. Without this, it could cause the wrong rendering engine to be used for a package. /// public RenderingEngine DetermineTemplateRenderingEngine(ITemplate template) @@ -748,7 +756,7 @@ namespace Umbraco.Core.Persistence.Repositories /// private void EnsureValidAlias(ITemplate template) { - //ensure unique alias + //ensure unique alias template.Alias = template.Alias.ToCleanString(CleanStringType.UnderscoreAlias); if (template.Alias.Length > 100) @@ -762,7 +770,7 @@ namespace Umbraco.Core.Persistence.Repositories private bool AliasAlreadExists(ITemplate template) { - var sql = GetBaseQuery(true).Where(SqlSyntax, x => x.Alias.InvariantEquals(template.Alias) && x.NodeId != template.Id); + var sql = GetBaseQuery(true).Where(x => x.Alias.InvariantEquals(template.Alias) && x.NodeId != template.Id); var count = Database.ExecuteScalar(sql); return count > 0; } diff --git a/src/Umbraco.Core/Persistence/Repositories/TupleExtensions.cs b/src/Umbraco.Core/Persistence/Repositories/TupleExtensions.cs new file mode 100644 index 0000000000..a944e9e497 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/TupleExtensions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Umbraco.Core.Persistence.Repositories +{ + static class TupleExtensions + { + public static IEnumerable Map(this Tuple, List> t, Func relator) + { + return t.Item1.Zip(t.Item2, relator); + } + + public static IEnumerable Map(this Tuple, List, List> t, Func relator) + { + return t.Item1.Zip(t.Item2, t.Item3, relator); + } + } +} diff --git a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs index e7d310e550..72333289c7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using NPoco; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -12,7 +13,6 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; @@ -21,7 +21,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents the UserRepository for doing CRUD operations for /// - internal class UserRepository : PetaPocoRepositoryBase, IUserRepository + internal class UserRepository : NPocoRepositoryBase, IUserRepository { private readonly IUserTypeRepository _userTypeRepository; private readonly CacheHelper _cacheHelper; @@ -40,8 +40,10 @@ namespace Umbraco.Core.Persistence.Repositories var sql = GetBaseQuery(false); sql.Where(GetBaseWhereClause(), new { Id = id }); - var dto = Database.Fetch(new UserSectionRelator().Map, sql).FirstOrDefault(); - + var dto = Database + .FetchOneToMany(x => x.User2AppDtos, sql) + .FirstOrDefault(); + if (dto == null) return null; @@ -60,50 +62,49 @@ namespace Umbraco.Core.Persistence.Repositories { sql.Where("umbracoUser.id in (@ids)", new {ids = ids}); } - - return ConvertFromDtos(Database.Fetch(new UserSectionRelator().Map, sql)) - .ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching. + + var dtos = Database + .FetchOneToMany(x => x.User2AppDtos, sql); + + return ConvertFromDtos(dtos).ToArray(); // do it now and do it once, else can end up with nulls in cache } - + protected override IEnumerable PerformGetByQuery(IQuery query) { var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - var dtos = Database.Fetch(new UserSectionRelator().Map, sql) + var dtos = Database + .FetchOneToMany(x => x.User2AppDtos, sql) .DistinctBy(x => x.Id); - return ConvertFromDtos(dtos) - .ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching. + return ConvertFromDtos(dtos).ToArray(); // do it now and do it once, else can end up with nulls in cache } - + #endregion - #region Overrides of PetaPocoRepositoryBase - - protected override Sql GetBaseQuery(bool isCount) + #region Overrides of NPocoRepositoryBase + + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); if (isCount) - { - sql.Select("COUNT(*)").From(SqlSyntax); - } - else - { - return GetBaseQuery("*"); - } - return sql; + return Sql().SelectCount().From(); + + return Sql() + .Select(r => r.Select(referenceName: "User2AppDtos")) + .From() + .LeftJoin() + .On(left => left.Id, right => right.UserId); } - private Sql GetBaseQuery(string columns) + private Sql GetBaseQuery(string columns) { - var sql = new Sql(); - sql.Select(columns) - .From(SqlSyntax) - .LeftJoin(SqlSyntax) - .On(SqlSyntax, left => left.Id, right => right.UserId); - return sql; + return Sql() + .Select(columns) + .From() + .LeftJoin() + .On(left => left.Id, right => right.UserId); } @@ -113,7 +114,7 @@ namespace Umbraco.Core.Persistence.Repositories } protected override IEnumerable GetDeleteClauses() - { + { var list = new List { "DELETE FROM cmsTask WHERE userId = @Id", @@ -131,7 +132,7 @@ namespace Umbraco.Core.Persistence.Repositories { get { throw new NotImplementedException(); } } - + protected override void PersistNewItem(IUser entity) { var userFactory = new UserFactory(entity.UserType); @@ -141,7 +142,7 @@ namespace Umbraco.Core.Persistence.Repositories { entity.SecurityStamp = Guid.NewGuid().ToString(); } - + var userDto = userFactory.BuildDto(entity); var id = Convert.ToInt32(Database.Insert(userDto)); @@ -181,8 +182,8 @@ namespace Umbraco.Core.Persistence.Repositories {"startStructureID", "StartContentId"}, {"startMediaID", "StartMediaId"}, {"userName", "Name"}, - {"userLogin", "Username"}, - {"userEmail", "Email"}, + {"userLogin", "Username"}, + {"userEmail", "Email"}, {"userLanguage", "Language"}, {"securityStampToken", "SecurityStamp"}, {"lastLockoutDate", "LastLockoutDate"}, @@ -217,7 +218,7 @@ namespace Umbraco.Core.Persistence.Repositories { Database.Update(userDto, changedCols); } - + //update the sections if they've changed var user = (User)entity; if (user.IsPropertyDirty("AllowedSections")) @@ -237,7 +238,7 @@ namespace Umbraco.Core.Persistence.Repositories //if something has been added then insert it if (user.AddedSections.Contains(sectionDto.AppAlias)) { - //we need to insert since this was added + //we need to insert since this was added Database.Insert(sectionDto); } else @@ -248,7 +249,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - + } entity.ResetDirtyProperties(); @@ -272,11 +273,10 @@ namespace Umbraco.Core.Persistence.Repositories public bool Exists(string username) { - var sql = new Sql(); - - sql.Select("COUNT(*)") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.UserName == username); + var sql = Sql() + .SelectCount() + .From() + .Where(x => x.UserName == username); return Database.ExecuteScalar(sql) > 0; } @@ -301,7 +301,10 @@ namespace Umbraco.Core.Persistence.Repositories innerSql.Where("umbracoUser2app.app = " + SqlSyntax.GetQuotedValue(sectionAlias)); sql.Where(string.Format("umbracoUser.id IN ({0})", innerSql.SQL)); - return ConvertFromDtos(Database.Fetch(new UserSectionRelator().Map, sql)); + var dtos = Database + .FetchOneToMany(x => x.User2AppDtos, sql); + + return ConvertFromDtos(dtos); } /// @@ -316,14 +319,15 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - /// The query supplied will ONLY work with data specifically on the umbracoUser table because we are using PetaPoco paging (SQL paging) + /// The query supplied will ONLY work with data specifically on the umbracoUser table because we are using NPoco paging (SQL paging) /// public IEnumerable GetPagedResultsByQuery(IQuery query, int pageIndex, int pageSize, out int totalRecords, Expression> orderBy) { - if (orderBy == null) throw new ArgumentNullException("orderBy"); + if (orderBy == null) throw new ArgumentNullException(nameof(orderBy)); - var sql = new Sql(); - sql.Select("*").From(SqlSyntax); + var sql = Sql() + .SelectAll() + .From(); Sql resultQuery; if (query != null) @@ -364,13 +368,13 @@ namespace Umbraco.Core.Persistence.Repositories //now we need to ensure this result is also ordered by the same order by clause return result.OrderBy(orderBy.Compile()); } - + /// /// Returns permissions for a given user for any number of nodes /// /// /// - /// + /// public IEnumerable GetUserPermissionsForEntities(int userId, params int[] entityIds) { var repo = new PermissionRepository(UnitOfWork, _cacheHelper, SqlSyntax); @@ -410,7 +414,7 @@ namespace Umbraco.Core.Persistence.Repositories var allUserTypes = userTypeIds.Length == 0 ? Enumerable.Empty() : _userTypeRepository.GetAll(userTypeIds); return dtos.Select(dto => - { + { var userType = allUserTypes.Single(x => x.Id == dto.Type); var userFactory = new UserFactory(userType); diff --git a/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs index df3ab9f669..497eef779b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserTypeRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; @@ -16,7 +17,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents the UserTypeRepository for doing CRUD operations for /// - internal class UserTypeRepository : PetaPocoRepositoryBase, IUserTypeRepository + internal class UserTypeRepository : NPocoRepositoryBase, IUserTypeRepository { public UserTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMappingResolver mappingResolver) : base(work, cache, logger, sqlSyntax, mappingResolver) @@ -35,14 +36,14 @@ namespace Umbraco.Core.Persistence.Repositories var userTypeFactory = new UserTypeFactory(); var sql = GetBaseQuery(false); - + if (ids.Any()) { sql.Where("umbracoUserType.id in (@ids)", new { ids = ids }); } else { - sql.Where(SqlSyntax, x => x.Id >= 0); + sql.Where(x => x.Id >= 0); } var dtos = Database.Fetch(sql); @@ -63,13 +64,19 @@ namespace Umbraco.Core.Persistence.Repositories #endregion - #region Overrides of PetaPocoRepositoryBase + #region Overrides of NPocoRepositoryBase - protected override Sql GetBaseQuery(bool isCount) + protected override Sql GetBaseQuery(bool isCount) { - var sql = new Sql(); - sql.Select(isCount ? "COUNT(*)" : "*") - .From(SqlSyntax); + var sql = Sql(); + + sql = isCount + ? sql.SelectCount() + : sql.Select(); + + sql + .From(); + return sql; } diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs index 86de4d7052..53a3884431 100644 --- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using NPoco; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; @@ -26,7 +27,27 @@ using Umbraco.Core.Persistence.Mappers; namespace Umbraco.Core.Persistence.Repositories { - internal abstract class VersionableRepositoryBase : PetaPocoRepositoryBase + // this cannot be inside VersionableRepositoryBase because that class is static + internal static class VersionableRepositoryBaseAliasRegex + { + private readonly static Dictionary Regexes = new Dictionary(); + + public static Regex For(ISqlSyntaxProvider sqlSyntax) + { + var type = sqlSyntax.GetType(); + Regex aliasRegex; + if (Regexes.TryGetValue(type, out aliasRegex)) + return aliasRegex; + + var col = Regex.Escape(sqlSyntax.GetQuotedColumnName("column")).Replace("column", @"\w+"); + var fld = Regex.Escape(sqlSyntax.GetQuotedTableName("table") + ".").Replace("table", @"\w+") + col; + aliasRegex = new Regex("(" + fld + @")\s+AS\s+(" + col + ")", RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + Regexes[type] = aliasRegex; + return aliasRegex; + } + } + + internal abstract class VersionableRepositoryBase : NPocoRepositoryBase where TEntity : class, IAggregateRoot { private readonly IContentSection _contentSection; @@ -41,22 +62,19 @@ namespace Umbraco.Core.Persistence.Repositories public virtual IEnumerable GetAllVersions(int id) { - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.NodeId == id) - .OrderByDescending(SqlSyntax, x => x.VersionDate); + var sql = Sql() + .SelectAll() + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.NodeId == id) + .OrderByDescending(x => x.VersionDate); - var dtos = Database.Fetch(sql); - foreach (var dto in dtos) - { - yield return GetByVersion(dto.VersionId); - } + var dtos = Database.Fetch(sql); + return dtos.Select(x => GetByVersion(x.VersionId)); } public virtual void DeleteVersion(Guid versionId) @@ -114,25 +132,27 @@ namespace Umbraco.Core.Persistence.Repositories var pathMatch = parentId == -1 ? "-1," : "," + parentId + ","; - var sql = new Sql(); + + var sql = Sql() + .SelectCount() + .From(); + if (contentTypeAlias.IsNullOrWhiteSpace()) { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.Path.Contains(pathMatch)); + sql + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.Path.Contains(pathMatch)); } else { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.Path.Contains(pathMatch)) - .Where(SqlSyntax, x => x.Alias == contentTypeAlias); + sql + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.ContentTypeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.Path.Contains(pathMatch)) + .Where(x => x.Alias == contentTypeAlias); } return Database.ExecuteScalar(sql); @@ -140,25 +160,26 @@ namespace Umbraco.Core.Persistence.Repositories public int CountChildren(int parentId, string contentTypeAlias = null) { - var sql = new Sql(); + var sql = Sql() + .SelectCount() + .From(); + if (contentTypeAlias.IsNullOrWhiteSpace()) { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.ParentId == parentId); + sql + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.ParentId == parentId); } else { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.ParentId == parentId) - .Where(SqlSyntax, x => x.Alias == contentTypeAlias); + sql + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.ContentTypeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.ParentId == parentId) + .Where(x => x.Alias == contentTypeAlias); } return Database.ExecuteScalar(sql); @@ -171,23 +192,24 @@ namespace Umbraco.Core.Persistence.Repositories /// public int Count(string contentTypeAlias = null) { - var sql = new Sql(); + var sql = Sql() + .SelectCount() + .From(); + if (contentTypeAlias.IsNullOrWhiteSpace()) { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + sql + .Where(x => x.NodeObjectType == NodeObjectTypeId); } else { - sql.Select("COUNT(*)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId) - .Where(SqlSyntax, x => x.Alias == contentTypeAlias); + sql + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.ContentTypeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId) + .Where(x => x.Alias == contentTypeAlias); } return Database.ExecuteScalar(sql); @@ -232,197 +254,120 @@ namespace Umbraco.Core.Persistence.Repositories } } - private Sql GetFilteredSqlForPagedResults(Sql sql, Func> defaultFilter = null) - { - //copy to var so that the original isn't changed - var filteredSql = new Sql(sql.SQL, sql.Arguments); - // Apply filter - if (defaultFilter != null) - { - var filterResult = defaultFilter(); - filteredSql.Append(filterResult.Item1, filterResult.Item2); - } - return filteredSql; - } - private Sql GetSortedSqlForPagedResults(Sql sql, Direction orderDirection, string orderBy) + private Sql PrepareSqlForPagedResults(Sql sql, Sql filterSql, string orderBy, Direction orderDirection) { - //copy to var so that the original isn't changed - var sortedSql = new Sql(sql.SQL, sql.Arguments); - // Apply order according to parameters + if (filterSql == null && string.IsNullOrEmpty(orderBy)) return sql; + + // preserve original + var psql = new Sql(sql.SqlContext, sql.SQL, sql.Arguments); + + // apply filter + if (filterSql != null) + { + psql.Append(filterSql); + } + + // apply sort if (string.IsNullOrEmpty(orderBy) == false) { - var orderByParams = new[] { GetDatabaseFieldNameForOrderBy(orderBy) }; + // get the database field eg "[table].[column]" + var dbfield = GetDatabaseFieldNameForOrderBy(orderBy); + + // for SqlServer pagination to work, the "order by" field needs to be the alias eg if + // the select statement has "umbracoNode.text AS NodeDto__Text" then the order field needs + // to be "NodeDto__Text" and NOT "umbracoNode.text". + // not sure about SqlCE nor MySql, so better do it too. initially thought about patching + // NPoco but that would be expensive and not 100% possible, so better give NPoco proper + // queries to begin with. + // thought about maintaining a map of columns-to-aliases in the sql context but that would + // be expensive and most of the time, useless. so instead we parse the SQL looking for the + // alias. somewhat expensive too but nothing's free. + + var matches = VersionableRepositoryBaseAliasRegex.For(SqlSyntax).Matches(sql.SQL); + var match = matches.Cast().FirstOrDefault(m => m.Groups[1].Value == dbfield); + if (match != null) + dbfield = match.Groups[2].Value; + + var orderByParams = new object[] { dbfield }; if (orderDirection == Direction.Ascending) - { - sortedSql.OrderBy(orderByParams); - } + psql.OrderBy(orderByParams); else - { - sortedSql.OrderByDescending(orderByParams); - } - return sortedSql; + psql.OrderByDescending(orderByParams); } - return sortedSql; + + return psql; } - /// - /// A helper method for inheritors to get the paged results by query in a way that minimizes queries - /// - /// The type of the d. - /// The 'true' entity type (i.e. Content, Member, etc...) - /// The query. - /// Index of the page. - /// Size of the page. - /// The total records. - /// The tablename + column name for the SELECT statement fragment to return the node id from the query - /// A callback to create the default filter to be applied if there is one - /// A callback to process the query result - /// The order by column - /// The order direction. - /// - /// orderBy - protected IEnumerable GetPagedResultsByQuery(IQuery query, long pageIndex, int pageSize, out long totalRecords, - Tuple nodeIdSelect, - Func> processQuery, - string orderBy, - Direction orderDirection, - Func> defaultFilter = null) - where TContentBase : class, IAggregateRoot, TEntity + protected IEnumerable GetPagedResultsByQuery(IQuery query, long pageIndex, int pageSize, out long totalRecords, + Func, IEnumerable> mapper, + string orderBy, Direction orderDirection, + Sql filterSql = null) { - if (orderBy == null) throw new ArgumentNullException("orderBy"); + if (orderBy == null) throw new ArgumentNullException(nameof(orderBy)); - // Get base query + // start with base query, and apply the supplied IQuery var sqlBase = GetBaseQuery(false); - if (query == null) query = Query; var translator = new SqlTranslator(sqlBase, query); - var sqlQuery = translator.Translate(); - - // Note we can't do multi-page for several DTOs like we can multi-fetch and are doing in PerformGetByQuery, - // but actually given we are doing a Get on each one (again as in PerformGetByQuery), we only need the node Id. - // So we'll modify the SQL. - var sqlNodeIds = new Sql( - sqlQuery.SQL.Replace("SELECT *", string.Format("SELECT {0}.{1}",nodeIdSelect.Item1, nodeIdSelect.Item2)), - sqlQuery.Arguments); - - //get sorted and filtered sql - var sqlNodeIdsWithSort = GetSortedSqlForPagedResults( - GetFilteredSqlForPagedResults(sqlNodeIds, defaultFilter), - orderDirection, orderBy); + var sqlNodeIds = translator.Translate(); - // Get page of results and total count - IEnumerable result; - var pagedResult = Database.Page(pageIndex + 1, pageSize, sqlNodeIdsWithSort); + // sort and filter + sqlNodeIds = PrepareSqlForPagedResults(sqlNodeIds, filterSql, orderBy, orderDirection); + + // get a page of DTOs and the total count + var pagedResult = Database.Page(pageIndex + 1, pageSize, sqlNodeIds); totalRecords = Convert.ToInt32(pagedResult.TotalItems); - //NOTE: We need to check the actual items returned, not the 'totalRecords', that is because if you request a page number - // that doesn't actually have any data on it, the totalRecords will still indicate there are records but there are none in - // the pageResult, then the GetAll will actually return ALL records in the db. - if (pagedResult.Items.Any()) - { - //Crete the inner paged query that was used above to get the paged result, we'll use that as the inner sub query - var args = sqlNodeIdsWithSort.Arguments; - string sqlStringCount, sqlStringPage; - Database.BuildPageQueries(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage); - - //if this is for sql server, the sqlPage will start with a SELECT * but we don't want that, we only want to return the nodeId - sqlStringPage = sqlStringPage - .Replace("SELECT *", - //This ensures we only take the field name of the node id select and not the table name - since the resulting select - // will ony work with the field name. - "SELECT " + nodeIdSelect.Item2); - - //We need to make this an inner join on the paged query - var splitQuery = sqlQuery.SQL.Split(new[] {"WHERE "}, StringSplitOptions.None); - var withInnerJoinSql = new Sql(splitQuery[0]) - .Append("INNER JOIN (") - //join the paged query with the paged query arguments - .Append(sqlStringPage, args) - .Append(") temp ") - .Append(string.Format("ON {0}.{1} = temp.{1}", nodeIdSelect.Item1, nodeIdSelect.Item2)) - //add the original where clause back with the original arguments - .Where(splitQuery[1], sqlQuery.Arguments); - - //get sorted and filtered sql - var fullQuery = GetSortedSqlForPagedResults( - GetFilteredSqlForPagedResults(withInnerJoinSql, defaultFilter), - orderDirection, orderBy); - - var content = processQuery(fullQuery) - .Cast() - .AsQueryable(); - - // Now we need to ensure this result is also ordered by the same order by clause - var orderByProperty = GetEntityPropertyNameForOrderBy(orderBy); - if (orderDirection == Direction.Ascending) - { - result = content.OrderBy(orderByProperty); - } - else - { - result = content.OrderByDescending(orderByProperty); - } - } - else - { - result = Enumerable.Empty(); - } - - return result; + // map the DTOs and return + return mapper(pagedResult.Items); } - protected IDictionary GetPropertyCollection( - Sql docSql, - IEnumerable documentDefs) + protected IDictionary GetPropertyCollection(DocumentDefinition[] ddefs) { - if (documentDefs.Any() == false) return new Dictionary(); + var versions = ddefs.Select(x => x.Version).ToArray(); + if (versions.Length == 0) return new Dictionary(); - //we need to parse the original SQL statement and reduce the columns to just cmsContent.nodeId, cmsContentVersion.VersionId so that we can use - // the statement to go get the property data for all of the items by using an inner join - var parsedOriginalSql = "SELECT {0} " + docSql.SQL.Substring(docSql.SQL.IndexOf("FROM", StringComparison.Ordinal)); - //now remove everything from an Orderby clause and beyond - if (parsedOriginalSql.InvariantContains("ORDER BY ")) + // fetch by version only, that should be enough, versions are guids and the same guid + // should not be reused for two different nodes -- then validate with a Where() just + // to be sure -- but we probably can get rid of the validation + var allPropertyData = Database.FetchByGroups(versions, 2000, batch => + Sql() + .Select(r => r.Select()) + .From() + .LeftJoin() + .On(left => left.PropertyTypeId, right => right.Id) + .WhereIn(x => x.VersionId, batch)) + .Where(x => ddefs.Any(y => y.Version == x.VersionId && y.Id == x.NodeId)) // so... probably redundant, but safe + .ToList(); + + // lazy access to prevalue for data types if any property requires tag support + var pre = new Lazy>(() => { - parsedOriginalSql = parsedOriginalSql.Substring(0, parsedOriginalSql.LastIndexOf("ORDER BY ", StringComparison.Ordinal)); - } + var allPropertyTypes = allPropertyData + .Select(x => x.PropertyTypeDto.Id) + .Distinct(); - var propSql = new Sql(@"SELECT cmsPropertyData.* -FROM cmsPropertyData -INNER JOIN cmsPropertyType -ON cmsPropertyData.propertytypeid = cmsPropertyType.id -INNER JOIN - (" + string.Format(parsedOriginalSql, "cmsContent.nodeId, cmsContentVersion.VersionId") + @") as docData -ON cmsPropertyData.versionId = docData.VersionId AND cmsPropertyData.contentNodeId = docData.nodeId -LEFT OUTER JOIN cmsDataTypePreValues -ON cmsPropertyType.dataTypeId = cmsDataTypePreValues.datatypeNodeId", docSql.Arguments); + var allDataTypePreValue = Database.FetchByGroups(allPropertyTypes, 2000, batch => + Sql() + .Select() + .From() + .LeftJoin().On(left => left.DataTypeNodeId, right => right.DataTypeId) + .WhereIn(x => x.Id, batch)); - var allPropertyData = Database.Fetch(propSql); - - //This is a lazy access call to get all prevalue data for the data types that make up all of these properties which we use - // below if any property requires tag support - var allPreValues = new Lazy>(() => - { - var preValsSql = new Sql(@"SELECT a.id, a.value, a.sortorder, a.alias, a.datatypeNodeId -FROM cmsDataTypePreValues a -WHERE EXISTS( - SELECT DISTINCT b.id as preValIdInner - FROM cmsDataTypePreValues b - INNER JOIN cmsPropertyType - ON b.datatypeNodeId = cmsPropertyType.dataTypeId - INNER JOIN - (" + string.Format(parsedOriginalSql, "DISTINCT cmsContent.contentType") + @") as docData - ON cmsPropertyType.contentTypeId = docData.contentType - WHERE a.id = b.id)", docSql.Arguments); - - return Database.Fetch(preValsSql); + return allDataTypePreValue; }); + return GetPropertyCollection(ddefs, allPropertyData, pre); + } + + protected IDictionary GetPropertyCollection(DocumentDefinition[] documentDefs, List allPropertyData, Lazy> allPreValues) + { var result = new Dictionary(); var propertiesWithTagSupport = new Dictionary(); - //iterate each definition grouped by it's content type - this will mean less property type iterations while building + //iterate each definition grouped by it's content type - this will mean less property type iterations while building // up the property collections foreach (var compositionGroup in documentDefs.GroupBy(x => x.Composition)) { @@ -433,8 +378,8 @@ WHERE EXISTS( var propertyDataDtos = allPropertyData.Where(x => x.NodeId == def.Id).Distinct(); var propertyFactory = new PropertyFactory(compositionProperties, def.Version, def.Id, def.CreateDate, def.VersionDate); - var properties = propertyFactory.BuildEntity(propertyDataDtos.ToArray()).ToArray(); - + var properties = propertyFactory.BuildEntity(propertyDataDtos.ToArray()).ToArray(); + var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity); foreach (var property in newProperties) @@ -482,7 +427,7 @@ WHERE EXISTS( Logger.Warn>("The query returned multiple property sets for document definition " + def.Id + ", " + def.Composition.Name); } result[def.Id] = new PropertyCollection(properties); - } + } } return result; @@ -511,37 +456,20 @@ WHERE EXISTS( protected virtual string GetDatabaseFieldNameForOrderBy(string orderBy) { - // Translate the passed order by field (which were originally defined for in-memory object sorting - // of ContentItemBasic instances) to the database field names. + // translate the supplied "order by" field, which were originally defined for in-memory + // object sorting of ContentItemBasic instance, to the actual database field names. + switch (orderBy.ToUpperInvariant()) { case "UPDATEDATE": - return "cmsContentVersion.VersionDate"; + return SqlSyntax.GetQuotedTableName("cmsContentVersion") + "." + SqlSyntax.GetQuotedColumnName("VersionDate"); case "NAME": - return "umbracoNode.text"; + return SqlSyntax.GetQuotedTableName("umbracoNode") + "." + SqlSyntax.GetQuotedColumnName("text"); case "OWNER": //TODO: This isn't going to work very nicely because it's going to order by ID, not by letter - return "umbracoNode.nodeUser"; - default: - //ensure invalid SQL cannot be submitted - return Regex.Replace(orderBy, @"[^\w\.,`\[\]@-]", ""); - } - } - - protected virtual string GetEntityPropertyNameForOrderBy(string orderBy) - { - // Translate the passed order by field (which were originally defined for in-memory object sorting - // of ContentItemBasic instances) to the IMedia property names. - switch (orderBy.ToUpperInvariant()) - { - case "OWNER": - //TODO: This isn't going to work very nicely because it's going to order by ID, not by letter - return "CreatorId"; - case "UPDATER": - //TODO: This isn't going to work very nicely because it's going to order by ID, not by letter - return "WriterId"; - case "VERSIONDATE": - return "UpdateDate"; + return SqlSyntax.GetQuotedTableName("umbracoNode") + "." + SqlSyntax.GetQuotedColumnName("nodeUser"); + case "PATH": + return SqlSyntax.GetQuotedTableName("umbracoNode") + "." + SqlSyntax.GetQuotedColumnName("path"); default: //ensure invalid SQL cannot be submitted return Regex.Replace(orderBy, @"[^\w\.,`\[\]@-]", ""); diff --git a/src/Umbraco.Core/Persistence/SqlContext.cs b/src/Umbraco.Core/Persistence/SqlContext.cs new file mode 100644 index 0000000000..927d6b469e --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlContext.cs @@ -0,0 +1,36 @@ +using System; +using NPoco; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence +{ + public class SqlContext + { + public SqlContext(ISqlSyntaxProvider sqlSyntax, IPocoDataFactory pocoDataFactory, DatabaseType databaseType) + { + if (sqlSyntax == null) throw new ArgumentNullException(nameof(sqlSyntax)); + if (pocoDataFactory == null) throw new ArgumentNullException(nameof(pocoDataFactory)); + if (databaseType == null) throw new ArgumentNullException(nameof(databaseType)); + + SqlSyntax = sqlSyntax; + PocoDataFactory = pocoDataFactory; + DatabaseType = databaseType; + } + + public SqlContext(ISqlSyntaxProvider sqlSyntax, IDatabaseConfig database) + { + if (sqlSyntax == null) throw new ArgumentNullException(nameof(sqlSyntax)); + if (database == null) throw new ArgumentNullException(nameof(database)); + + SqlSyntax = sqlSyntax; + PocoDataFactory = database.PocoDataFactory; + DatabaseType = database.DatabaseType; + } + + public ISqlSyntaxProvider SqlSyntax { get; } + + public IPocoDataFactory PocoDataFactory { get; } + + public DatabaseType DatabaseType { get; } + } +} diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index 056d9c1d9a..5778b4e618 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Querying; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index c18a5f8477..6e21881f0c 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -390,7 +391,7 @@ ORDER BY TABLE_NAME, INDEX_NAME", public override string EscapeString(string val) { - return PetaPocoExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val)); + return NPocoDatabaseExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index 1c6e1bba52..41b88abec9 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Querying; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 9cb0ce327d..8ea169e997 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.SqlSyntax diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index eb8a56faca..bc1b12a22d 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -4,6 +4,7 @@ using System.Data; using System.Globalization; using System.Linq; using System.Text; +using NPoco; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Querying; @@ -121,7 +122,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax public virtual string EscapeString(string val) { - return PetaPocoExtensions.EscapeAtSymbols(val.Replace("'", "''")); + return NPocoDatabaseExtensions.EscapeAtSymbols(val.Replace("'", "''")); } public virtual string GetStringColumnEqualComparison(string column, int paramIndex, TextColumnType columnType) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs index af18d9c3d9..90f0a56696 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs @@ -1,4 +1,6 @@ -namespace Umbraco.Core.Persistence.SqlSyntax +using NPoco; + +namespace Umbraco.Core.Persistence.SqlSyntax { internal static class SqlSyntaxProviderExtensions { diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs index 8125c183ff..eaf637df4b 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs @@ -3,23 +3,31 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; +using NPoco; using StackExchange.Profiling; using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.FaultHandling; +using Umbraco.Core.Persistence.Mappers; namespace Umbraco.Core.Persistence { /// - /// Represents the Umbraco implementation of the PetaPoco Database object + /// Extends NPoco Database for Umbraco. /// /// - /// Currently this object exists for 'future proofing' our implementation. By having our own inheritied implementation we - /// can then override any additional execution (such as additional loggging, functionality, etc...) that we need to without breaking compatibility since we'll always be exposing - /// this object instead of the base PetaPoco database object. + /// Is used everywhere in place of the original NPoco Database object, and provides additional features + /// such as profiling, retry policies, logging, etc. + /// Is never created directly but obtained from the . /// public class UmbracoDatabase : Database, IDisposeOnRequestEnd { + // Umbraco's default isolation level is RepeatableRead + private const IsolationLevel DefaultIsolationLevel = IsolationLevel.RepeatableRead; + private readonly ILogger _logger; private readonly Guid _instanceId = Guid.NewGuid(); + private readonly RetryPolicy _connectionRetryPolicy; + private readonly RetryPolicy _commandRetryPolicy; private bool _enableCount; /// @@ -57,49 +65,52 @@ namespace Umbraco.Core.Persistence /// internal int SqlCount { get; private set; } - public UmbracoDatabase(IDbConnection connection, ILogger logger) - : base(connection) + // used by DefaultDatabaseFactory + // creates one instance per request + // also used by DatabaseContext for creating DBs and upgrading + public UmbracoDatabase(string connectionString, string providerName, ILogger logger, RetryPolicy connectionRetryPolicy = null, RetryPolicy commandRetryPolicy = null) + : base(connectionString, providerName, DefaultIsolationLevel) { _logger = logger; + _connectionRetryPolicy = connectionRetryPolicy; + _commandRetryPolicy = commandRetryPolicy; EnableSqlTrace = false; } - public UmbracoDatabase(string connectionString, string providerName, ILogger logger) - : base(connectionString, providerName) + // used by DefaultDatabaseFactory + // creates one instance per request + public UmbracoDatabase(string connectionStringName, ILogger logger, RetryPolicy connectionRetryPolicy = null, RetryPolicy commandRetryPolicy = null) + : base(connectionStringName, DefaultIsolationLevel) { _logger = logger; + _connectionRetryPolicy = connectionRetryPolicy; + _commandRetryPolicy = commandRetryPolicy; EnableSqlTrace = false; } - public UmbracoDatabase(string connectionString, DbProviderFactory provider, ILogger logger) - : base(connectionString, provider) + protected override DbConnection OnConnectionOpened(DbConnection connection) { - _logger = logger; - EnableSqlTrace = false; - } - - public UmbracoDatabase(string connectionStringName, ILogger logger) - : base(connectionStringName) - { - _logger = logger; - EnableSqlTrace = false; - } - - public override IDbConnection OnConnectionOpened(IDbConnection connection) - { - // propagate timeout if none yet + if (connection == null) throw new ArgumentNullException("connection"); // wrap the connection with a profiling connection that tracks timings - return new StackExchange.Profiling.Data.ProfiledDbConnection(connection as DbConnection, MiniProfiler.Current); + connection = new StackExchange.Profiling.Data.ProfiledDbConnection(connection, MiniProfiler.Current); + + // wrap the connection with a retrying connection + if (_connectionRetryPolicy != null || _commandRetryPolicy != null) + connection = new RetryDbConnection(connection, _connectionRetryPolicy, _commandRetryPolicy); + + return connection; } - public override void OnException(Exception x) + protected override void OnException(Exception x) { _logger.Error("Database exception occurred", x); base.OnException(x); } - public override void OnExecutingCommand(IDbCommand cmd) + // fixme.poco - has new interceptors? + + protected override void OnExecutingCommand(DbCommand cmd) { // if no timeout is specified, and the connection has a longer timeout, use it if (OneTimeCommandTimeout == 0 && CommandTimeout == 0 && cmd.Connection.ConnectionTimeout > 30) @@ -107,7 +118,7 @@ namespace Umbraco.Core.Persistence base.OnExecutingCommand(cmd); } - public override void OnExecutedCommand(IDbCommand cmd) + protected override void OnExecutedCommand(DbCommand cmd) { if (EnableSqlTrace) { @@ -119,5 +130,10 @@ namespace Umbraco.Core.Persistence } base.OnExecutedCommand(cmd); } + + public IEnumerable FetchByGroups(IEnumerable source, int groupSize, Func, Sql> sqlFactory) + { + return source.SelectByGroups(x => Fetch(sqlFactory(x)), groupSize); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/UmbracoSqlExtensions.cs b/src/Umbraco.Core/Persistence/UmbracoSqlExtensions.cs new file mode 100644 index 0000000000..6bb571fe6e --- /dev/null +++ b/src/Umbraco.Core/Persistence/UmbracoSqlExtensions.cs @@ -0,0 +1,250 @@ +using System; +using System.Collections; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using NPoco; +using Umbraco.Core.Persistence.Querying; + +namespace Umbraco.Core.Persistence +{ + public static class UmbracoSqlExtensions + { + // note: here we take benefit from the fact that NPoco methods that return a Sql, such as + // when doing "sql = sql.Where(...)" actually append to, and return, the original Sql, not + // a new one. + + #region Where + + public static Sql Where(this Sql sql, Expression> predicate) + { + var expresionist = new PocoToSqlExpressionHelper(sql.SqlContext); + var whereExpression = expresionist.Visit(predicate); + sql.Where(whereExpression, expresionist.GetSqlParameters()); + return sql; + } + + public static Sql WhereIn(this Sql sql, Expression> fieldSelector, IEnumerable values) + { + var expresionist = new PocoToSqlExpressionHelper(sql.SqlContext); + var fieldExpression = expresionist.Visit(fieldSelector); + sql.Where(fieldExpression + " IN (@values)", new { /*@values =*/ values }); + return sql; + } + + #endregion + + #region From + + public static Sql From(this Sql sql) + { + var type = typeof (T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + sql.From(sql.SqlContext.SqlSyntax.GetQuotedTableName(tableName)); + return sql; + } + + #endregion + + #region OrderBy, GroupBy + + public static Sql OrderBy(this Sql sql, Expression> columnMember) + { + var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; + var columnName = column.FirstAttribute().Name; + + var type = typeof (T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + // need to ensure the order by is in brackets, see: https://github.com/toptensoftware/PetaPoco/issues/177 + var sqlSyntax = sql.SqlContext.SqlSyntax; + var syntax = $"({sqlSyntax.GetQuotedTableName(tableName)}.{sqlSyntax.GetQuotedColumnName(columnName)})"; + + sql.OrderBy(syntax); + return sql; + } + + public static Sql OrderByDescending(this Sql sql, Expression> columnMember) + { + var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; + var columnName = column.FirstAttribute().Name; + + var type = typeof(T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + var sqlSyntax = sql.SqlContext.SqlSyntax; + var syntax = $"{sqlSyntax.GetQuotedTableName(tableName)}.{sqlSyntax.GetQuotedColumnName(columnName)} DESC"; + + sql.OrderBy(syntax); + return sql; + } + + public static Sql OrderByDescending(this Sql sql, params object[] columns) + { + sql.Append("ORDER BY " + string.Join(", ", columns.Select(x => x + " DESC"))); + return sql; + } + + public static Sql GroupBy(this Sql sql, Expression> columnMember) + { + var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; + var columnName = column.FirstAttribute().Name; + + sql.GroupBy(sql.SqlContext.SqlSyntax.GetQuotedColumnName(columnName)); + return sql; + } + + #endregion + + #region Joins + + public static Sql.SqlJoinClause InnerJoin(this Sql sql) + { + var type = typeof(T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + return sql.InnerJoin(sql.SqlContext.SqlSyntax.GetQuotedTableName(tableName)); + } + + public static Sql.SqlJoinClause LeftJoin(this Sql sql) + { + var type = typeof(T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + return sql.LeftJoin(sql.SqlContext.SqlSyntax.GetQuotedTableName(tableName)); + } + + public static Sql.SqlJoinClause LeftOuterJoin(this Sql sql) + { + var type = typeof(T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + return sql.LeftOuterJoin(sql.SqlContext.SqlSyntax.GetQuotedTableName(tableName)); + } + + public static Sql.SqlJoinClause RightJoin(this Sql sql) + { + var type = typeof(T); + var tableNameAttribute = type.FirstAttribute(); + var tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; + + return sql.RightJoin(sql.SqlContext.SqlSyntax.GetQuotedTableName(tableName)); + } + + public static Sql On(this Sql.SqlJoinClause clause, + Expression> leftMember, Expression> rightMember, + params object[] args) + { + var sqlSyntax = clause.SqlContext.SqlSyntax; + + var leftType = typeof (TLeft); + var rightType = typeof (TRight); + var leftTableName = sqlSyntax.GetQuotedTableName(leftType.FirstAttribute().Value); + var rightTableName = sqlSyntax.GetQuotedTableName(rightType.FirstAttribute().Value); + + var left = ExpressionHelper.FindProperty(leftMember) as PropertyInfo; + var right = ExpressionHelper.FindProperty(rightMember) as PropertyInfo; + var leftColumnName = sqlSyntax.GetQuotedColumnName(left.FirstAttribute().Name); + var rightColumnName = sqlSyntax.GetQuotedColumnName(right.FirstAttribute().Name); + + var onClause = $"{leftTableName}.{leftColumnName} = {rightTableName}.{rightColumnName}"; + return clause.On(onClause); + } + + #endregion + + #region Select + + public static Sql SelectCount(this Sql sql) + { + sql.Select("COUNT(*)"); + return sql; + } + + public static Sql SelectAll(this Sql sql) + { + sql.Select("*"); + return sql; + } + + public static Sql Select(this Sql sql, Func refexpr = null) + { + var pd = sql.SqlContext.PocoDataFactory.ForType(typeof (T)); + + var tableName = pd.TableInfo.TableName; + var columns = pd.QueryColumns.Select(x => GetColumn(sql.SqlContext.DatabaseType, + tableName, + x.Value.ColumnName, + string.IsNullOrEmpty(x.Value.ColumnAlias) ? x.Value.MemberInfoKey : x.Value.ColumnAlias)); + + sql.Select(string.Join(", ", columns)); + + if (refexpr == null) return sql; + refexpr(new RefSql(sql, null)); + return sql; + } + + /// + /// + /// + /// + /// + /// + /// The name of the DTO reference. + /// The name of the table alias. + /// + /// + /// Select<Foo>() produces: [foo].[value] AS [Foo_Value] + /// With tableAlias: [tableAlias].[value] AS [Foo_Value] + /// With referenceName: [foo].[value] AS [referenceName_Value] + /// + public static RefSql Select(this RefSql refSql, Func refexpr = null, string referenceName = null, string tableAlias = null) + { + if (referenceName == null) referenceName = typeof (T).Name; + if (refSql.Prefix != null) referenceName = refSql.Prefix + PocoData.Separator + referenceName; + var pd = refSql.Sql.SqlContext.PocoDataFactory.ForType(typeof (T)); + + var tableName = tableAlias ?? pd.TableInfo.TableName; + var columns = pd.QueryColumns.Select(x => GetColumn(refSql.Sql.SqlContext.DatabaseType, + tableName, + x.Value.ColumnName, + string.IsNullOrEmpty(x.Value.ColumnAlias) ? x.Value.MemberInfoKey : x.Value.ColumnAlias, + referenceName)); + + refSql.Sql.Append(", " + string.Join(", ", columns)); + + if (refexpr == null) return refSql; + refexpr(new RefSql(refSql.Sql, referenceName)); + return refSql; + } + + public class RefSql + { + public RefSql(Sql sql, string prefix) + { + Sql = sql; + Prefix = prefix; + } + + public Sql Sql { get; } + public string Prefix { get; } + } + + private static string GetColumn(DatabaseType dbType, string tableName, string columnName, string columnAlias, string referenceName = null) + { + tableName = dbType.EscapeTableName(tableName); + columnName = dbType.EscapeSqlIdentifier(columnName); + columnAlias = dbType.EscapeSqlIdentifier((referenceName == null ? "" : (referenceName + "__")) + columnAlias); + return tableName + "." + columnName + " AS " + columnAlias; + } + + #endregion + } +} diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs b/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWork.cs similarity index 88% rename from src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs rename to src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWork.cs index a5337e854c..5b6af0b4c0 100644 --- a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs +++ b/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWork.cs @@ -1,183 +1,183 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models.EntityBase; - -namespace Umbraco.Core.Persistence.UnitOfWork -{ - /// - /// Represents the Unit of Work implementation for PetaPoco - /// - internal class PetaPocoUnitOfWork : DisposableObject, IDatabaseUnitOfWork - { - - /// - /// Used for testing - /// - internal Guid InstanceId { get; private set; } - - private Guid _key; - private readonly Queue _operations = new Queue(); - - /// - /// Creates a new unit of work instance - /// - /// - /// - /// This should normally not be used directly and should be created with the UnitOfWorkProvider - /// - internal PetaPocoUnitOfWork(UmbracoDatabase database) - { - Database = database; - _key = Guid.NewGuid(); - InstanceId = Guid.NewGuid(); - } - - /// - /// Registers an instance to be added through this - /// - /// The - /// The participating in the transaction - public void RegisterAdded(IEntity entity, IUnitOfWorkRepository repository) - { - _operations.Enqueue(new Operation - { - Entity = entity, - Repository = repository, - Type = TransactionType.Insert - }); - } - - /// - /// Registers an instance to be changed through this - /// - /// The - /// The participating in the transaction - public void RegisterChanged(IEntity entity, IUnitOfWorkRepository repository) - { - _operations.Enqueue( - new Operation - { - Entity = entity, - Repository = repository, - Type = TransactionType.Update - }); - } - - /// - /// Registers an instance to be removed through this - /// - /// The - /// The participating in the transaction - public void RegisterRemoved(IEntity entity, IUnitOfWorkRepository repository) - { - _operations.Enqueue( - new Operation - { - Entity = entity, - Repository = repository, - Type = TransactionType.Delete - }); - } - - /// - /// Commits all batched changes within the scope of a PetaPoco transaction - /// - /// - /// Unlike a typical unit of work, this UOW will let you commit more than once since a new transaction is creaed per - /// Commit() call instead of having one Transaction per UOW. - /// - public void Commit() - { - Commit(null); - } - - /// - /// Commits all batched changes within the scope of a PetaPoco transaction - /// - /// - /// Allows you to set a callback which is executed before the transaction is committed, allow you to add additional SQL - /// operations to the overall commit process after the queue has been processed. - /// - internal void Commit(Action transactionCompleting) - { - using (var transaction = Database.GetTransaction()) - { - while (_operations.Count > 0) - { - var operation = _operations.Dequeue(); - switch (operation.Type) - { - case TransactionType.Insert: - operation.Repository.PersistNewItem(operation.Entity); - break; - case TransactionType.Delete: - operation.Repository.PersistDeletedItem(operation.Entity); - break; - case TransactionType.Update: - operation.Repository.PersistUpdatedItem(operation.Entity); - break; - } - } - - //Execute the callback if there is one - if (transactionCompleting != null) - { - transactionCompleting(Database); - } - - transaction.Complete(); - } - - // Clear everything - _operations.Clear(); - _key = Guid.NewGuid(); - } - - public object Key - { - get { return _key; } - } - - public UmbracoDatabase Database { get; private set; } - - #region Operation - - /// - /// Provides a snapshot of an entity and the repository reference it belongs to. - /// - private sealed class Operation - { - /// - /// Gets or sets the entity. - /// - /// The entity. - public IEntity Entity { get; set; } - - /// - /// Gets or sets the repository. - /// - /// The repository. - public IUnitOfWorkRepository Repository { get; set; } - - /// - /// Gets or sets the type of operation. - /// - /// The type of operation. - public TransactionType Type { get; set; } - } - - #endregion - - /// - /// Ensures disposable objects are disposed - /// - /// - /// Ensures that the Transaction instance is disposed of - /// - protected override void DisposeResources() - { - _operations.Clear(); - } - } +using System; +using System.Collections.Generic; +using NPoco; +using Umbraco.Core.Models.EntityBase; + +namespace Umbraco.Core.Persistence.UnitOfWork +{ + /// + /// Represents the Unit of Work implementation for NPoco + /// + internal class NPocoUnitOfWork : DisposableObject, IDatabaseUnitOfWork + { + + /// + /// Used for testing + /// + internal Guid InstanceId { get; private set; } + + private Guid _key; + private readonly Queue _operations = new Queue(); + + /// + /// Creates a new unit of work instance + /// + /// + /// + /// This should normally not be used directly and should be created with the UnitOfWorkProvider + /// + internal NPocoUnitOfWork(UmbracoDatabase database) + { + Database = database; + _key = Guid.NewGuid(); + InstanceId = Guid.NewGuid(); + } + + /// + /// Registers an instance to be added through this + /// + /// The + /// The participating in the transaction + public void RegisterAdded(IEntity entity, IUnitOfWorkRepository repository) + { + _operations.Enqueue(new Operation + { + Entity = entity, + Repository = repository, + Type = TransactionType.Insert + }); + } + + /// + /// Registers an instance to be changed through this + /// + /// The + /// The participating in the transaction + public void RegisterChanged(IEntity entity, IUnitOfWorkRepository repository) + { + _operations.Enqueue( + new Operation + { + Entity = entity, + Repository = repository, + Type = TransactionType.Update + }); + } + + /// + /// Registers an instance to be removed through this + /// + /// The + /// The participating in the transaction + public void RegisterRemoved(IEntity entity, IUnitOfWorkRepository repository) + { + _operations.Enqueue( + new Operation + { + Entity = entity, + Repository = repository, + Type = TransactionType.Delete + }); + } + + /// + /// Commits all batched changes within the scope of a NPoco . + /// + /// + /// Unlike a typical unit of work, this UOW will let you commit more than once since a new transaction is creaed per + /// Commit() call instead of having one transaction per UOW. + /// + public void Commit() + { + Commit(null); + } + + /// + /// Commits all batched changes within the scope of a NPoco . + /// + /// + /// Allows you to set a callback which is executed before the transaction is committed, allow you to add additional SQL + /// operations to the overall commit process after the queue has been processed. + /// + internal void Commit(Action transactionCompleting) + { + using (var transaction = Database.GetTransaction()) + { + while (_operations.Count > 0) + { + var operation = _operations.Dequeue(); + switch (operation.Type) + { + case TransactionType.Insert: + operation.Repository.PersistNewItem(operation.Entity); + break; + case TransactionType.Delete: + operation.Repository.PersistDeletedItem(operation.Entity); + break; + case TransactionType.Update: + operation.Repository.PersistUpdatedItem(operation.Entity); + break; + } + } + + //Execute the callback if there is one + if (transactionCompleting != null) + { + transactionCompleting(Database); + } + + transaction.Complete(); + } + + // Clear everything + _operations.Clear(); + _key = Guid.NewGuid(); + } + + public object Key + { + get { return _key; } + } + + public UmbracoDatabase Database { get; private set; } + + #region Operation + + /// + /// Provides a snapshot of an entity and the repository reference it belongs to. + /// + private sealed class Operation + { + /// + /// Gets or sets the entity. + /// + /// The entity. + public IEntity Entity { get; set; } + + /// + /// Gets or sets the repository. + /// + /// The repository. + public IUnitOfWorkRepository Repository { get; set; } + + /// + /// Gets or sets the type of operation. + /// + /// The type of operation. + public TransactionType Type { get; set; } + } + + #endregion + + /// + /// Ensures disposable objects are disposed + /// + /// + /// Ensures that the Transaction instance is disposed of + /// + protected override void DisposeResources() + { + _operations.Clear(); + } + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs b/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs new file mode 100644 index 0000000000..c8407eb08d --- /dev/null +++ b/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs @@ -0,0 +1,47 @@ +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; + +namespace Umbraco.Core.Persistence.UnitOfWork +{ + /// + /// Represents a Unit of Work Provider for creating a . + /// + public class NPocoUnitOfWorkProvider : IDatabaseUnitOfWorkProvider + { + private readonly IDatabaseFactory _dbFactory; + + /// + /// Initializes a new instance of the class with an . + /// + /// + public NPocoUnitOfWorkProvider(IDatabaseFactory dbFactory) + { + Mandate.ParameterNotNull(dbFactory, "dbFactory"); + _dbFactory = dbFactory; + } + + // for unit tests only + // will re-create a new DefaultDatabaseFactory each time it is called + internal NPocoUnitOfWorkProvider(ILogger logger) + : this(new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, logger)) + { } + + #region Implementation of IUnitOfWorkProvider + + /// + /// Creates a unit of work around a database obtained from the database factory. + /// + /// A unit of work. + /// The unit of work will execute on the current database returned by the database factory. + public IDatabaseUnitOfWork GetUnitOfWork() + { + // get a database from the factory - might be the "ambient" database eg + // the one that's enlisted with the HttpContext - so it's not always a + // "new" database. + var database = _dbFactory.CreateDatabase(); + return new NPocoUnitOfWork(database); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs deleted file mode 100644 index 65dc09b418..0000000000 --- a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; - -namespace Umbraco.Core.Persistence.UnitOfWork -{ - /// - /// Represents a Unit of Work Provider for creating a - /// - public class PetaPocoUnitOfWorkProvider : IDatabaseUnitOfWorkProvider - { - private readonly IDatabaseFactory _dbFactory; - - /// - /// Parameterless constructor uses defaults - /// - public PetaPocoUnitOfWorkProvider(ILogger logger) - : this(new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, logger)) - { - - } - - /// - /// Constructor accepting custom connectino string and provider name - /// - /// - /// Connection String to use with Database - /// Database Provider for the Connection String - public PetaPocoUnitOfWorkProvider(ILogger logger, string connectionString, string providerName) - : this(new DefaultDatabaseFactory(connectionString, providerName, logger)) - { } - - /// - /// Constructor accepting an IDatabaseFactory instance - /// - /// - public PetaPocoUnitOfWorkProvider(IDatabaseFactory dbFactory) - { - Mandate.ParameterNotNull(dbFactory, "dbFactory"); - _dbFactory = dbFactory; - } - - #region Implementation of IUnitOfWorkProvider - - /// - /// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction. - /// - /// - /// - /// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from - /// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database - /// and we Dispose of this Database object when the UOW is disposed. - /// - public IDatabaseUnitOfWork GetUnitOfWork() - { - return new PetaPocoUnitOfWork(_dbFactory.CreateDatabase()); - } - - #endregion - - /// - /// Static helper method to return a new unit of work - /// - /// - internal static IDatabaseUnitOfWork CreateUnitOfWork(ILogger logger) - { - var provider = new PetaPocoUnitOfWorkProvider(logger); - return provider.GetUnitOfWork(); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Services/EntityService.cs b/src/Umbraco.Core/Services/EntityService.cs index 4314308f41..5f24eac64b 100644 --- a/src/Umbraco.Core/Services/EntityService.cs +++ b/src/Umbraco.Core/Services/EntityService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.CodeAnnotations; using Umbraco.Core.Events; @@ -86,9 +87,10 @@ namespace Umbraco.Core.Services case UmbracoObjectTypes.DataType: case UmbracoObjectTypes.DocumentTypeContainer: return uow.Database.ExecuteScalar( - new Sql().Select("id") - .From(RepositoryFactory.SqlSyntax) - .Where(RepositoryFactory.SqlSyntax, dto => dto.UniqueId == key)); + NPoco.Sql.BuilderFor(new SqlContext(RepositoryFactory.SqlSyntax, uow.Database)) + .Select("id") + .From() + .Where(dto => dto.UniqueId == key)); case UmbracoObjectTypes.RecycleBin: case UmbracoObjectTypes.Stylesheet: case UmbracoObjectTypes.MemberGroup: @@ -127,9 +129,10 @@ namespace Umbraco.Core.Services case UmbracoObjectTypes.Member: case UmbracoObjectTypes.DataType: return uow.Database.ExecuteScalar( - new Sql().Select("uniqueID") - .From(RepositoryFactory.SqlSyntax) - .Where(RepositoryFactory.SqlSyntax, dto => dto.NodeId == id)); + NPoco.Sql.BuilderFor(new SqlContext(RepositoryFactory.SqlSyntax, uow.Database)) + .Select("uniqueID") + .From() + .Where(dto => dto.NodeId == id)); case UmbracoObjectTypes.RecycleBin: case UmbracoObjectTypes.Stylesheet: case UmbracoObjectTypes.MemberGroup: @@ -342,7 +345,7 @@ namespace Umbraco.Core.Services using (var repository = RepositoryFactory.CreateEntityRepository(UowProvider.GetUnitOfWork())) { var query = repository.Query.Where(x => x.ParentId == parentId); - var contents = repository.GetByQuery(query, objectTypeId); + var contents = repository.GetByQuery(query, objectTypeId).ToList(); // run within using! return contents; } @@ -492,7 +495,10 @@ namespace Umbraco.Core.Services { using (var uow = UowProvider.GetUnitOfWork()) { - var sql = new Sql().Select("nodeObjectType").From(RepositoryFactory.SqlSyntax).Where(RepositoryFactory.SqlSyntax, x => x.NodeId == id); + var sql = NPoco.Sql.BuilderFor(new SqlContext(RepositoryFactory.SqlSyntax, uow.Database)) + .Select("nodeObjectType") + .From() + .Where(x => x.NodeId == id); var nodeObjectTypeId = uow.Database.ExecuteScalar(sql); var objectTypeId = nodeObjectTypeId; return UmbracoObjectTypesExtensions.GetUmbracoObjectType(objectTypeId); @@ -508,7 +514,10 @@ namespace Umbraco.Core.Services { using (var uow = UowProvider.GetUnitOfWork()) { - var sql = new Sql().Select("nodeObjectType").From(RepositoryFactory.SqlSyntax).Where(RepositoryFactory.SqlSyntax, x => x.UniqueId == key); + var sql = NPoco.Sql.BuilderFor(new SqlContext(RepositoryFactory.SqlSyntax, uow.Database)) + .Select("nodeObjectType") + .From() + .Where(x => x.UniqueId == key); var nodeObjectTypeId = uow.Database.ExecuteScalar(sql); var objectTypeId = nodeObjectTypeId; return UmbracoObjectTypesExtensions.GetUmbracoObjectType(objectTypeId); diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs index fffa158a46..c16ce5a1a8 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -244,10 +245,10 @@ namespace Umbraco.Core.Sync // // FIXME not true if we're running on a background thread, assuming we can? - var sql = new Sql().Select("*") - .From(_appContext.DatabaseContext.SqlSyntax) - .Where(_appContext.DatabaseContext.SqlSyntax, dto => dto.Id > _lastId) - .OrderBy(_appContext.DatabaseContext.SqlSyntax, dto => dto.Id); + var sql = _appContext.DatabaseContext.Sql().SelectAll() + .From() + .Where(dto => dto.Id > _lastId) + .OrderBy(dto => dto.Id); var dtos = _appContext.DatabaseContext.Database.Fetch(sql); if (dtos.Count <= 0) return; @@ -348,9 +349,9 @@ namespace Umbraco.Core.Sync /// and it should instead cold-boot. private void EnsureInstructions() { - var sql = new Sql().Select("*") - .From(_appContext.DatabaseContext.SqlSyntax) - .Where(_appContext.DatabaseContext.SqlSyntax, dto => dto.Id == _lastId); + var sql = _appContext.DatabaseContext.Sql().SelectAll() + .From() + .Where(dto => dto.Id == _lastId); var dtos = _appContext.DatabaseContext.Database.Fetch(sql); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ac36147368..26137a72bc 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -92,6 +92,10 @@ ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll True + + ..\packages\NPoco.3.1.0-u005\lib\net45\NPoco.dll + True + ..\packages\Owin.1.0\lib\net40\Owin.dll @@ -333,6 +337,7 @@ + @@ -368,6 +373,9 @@ + + Component + @@ -445,7 +453,6 @@ - @@ -465,6 +472,9 @@ + + + @@ -755,7 +765,6 @@ - @@ -766,7 +775,7 @@ - + @@ -964,19 +973,13 @@ - - - - + - - - @@ -997,7 +1000,6 @@ - @@ -1012,7 +1014,7 @@ - + @@ -1045,8 +1047,8 @@ - - + + @@ -1150,7 +1152,6 @@ - diff --git a/src/Umbraco.Core/Umbraco.Core.csproj.DotSettings b/src/Umbraco.Core/Umbraco.Core.csproj.DotSettings index 662f95686e..73e96563f9 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj.DotSettings +++ b/src/Umbraco.Core/Umbraco.Core.csproj.DotSettings @@ -1,2 +1,2 @@  - CSharp50 \ No newline at end of file + CSharp60 \ No newline at end of file diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index d3aa7b8ba5..1cbbee0585 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -13,6 +13,7 @@ + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 916277329e..2a3bfdc290 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -2,12 +2,12 @@ - +
- + - + @@ -52,7 +52,7 @@ - + @@ -64,9 +64,9 @@ - + - + @@ -121,13 +121,13 @@ - + - + - + - + diff --git a/src/Umbraco.Tests/EnumerableExtensionsTests.cs b/src/Umbraco.Tests/EnumerableExtensionsTests.cs index 8edba760a1..da69ab9d40 100644 --- a/src/Umbraco.Tests/EnumerableExtensionsTests.cs +++ b/src/Umbraco.Tests/EnumerableExtensionsTests.cs @@ -156,6 +156,15 @@ namespace Umbraco.Tests CollectionAssert.AreEquivalent(integers, flattened); } + [Test] + public void InGroupsOf_CanRepeat() + { + var integers = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + var inGroupsOf = integers.InGroupsOf(2); + Assert.AreEqual(5, inGroupsOf.Count()); + Assert.AreEqual(5, inGroupsOf.Count()); // again + } + [TestCase] public void DistinctBy_ReturnsDistinctElements_AndResetsIteratorCorrectly() { diff --git a/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs b/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs index 49c0e1e8ac..9168ee6ace 100644 --- a/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs +++ b/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Moq; +using NPoco; using NUnit.Framework; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; @@ -19,6 +20,7 @@ namespace Umbraco.Tests.Migrations { // Arrange var sqlSyntax = new SqlCeSyntaxProvider(); + // fixme Database vs UmbracoDatabase var context = new MigrationContext(DatabaseProviders.SqlServerCE, new Database("test", "System.Data.SqlClient"), Mock.Of(), sqlSyntax); var stub = new DropForeignKeyMigrationStub(sqlSyntax, Mock.Of()); diff --git a/src/Umbraco.Tests/Migrations/MigrationRunnerTests.cs b/src/Umbraco.Tests/Migrations/MigrationRunnerTests.cs index ee1639d41a..5be8f9bda9 100644 --- a/src/Umbraco.Tests/Migrations/MigrationRunnerTests.cs +++ b/src/Umbraco.Tests/Migrations/MigrationRunnerTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Moq; +using NPoco; using NUnit.Framework; using Semver; using Umbraco.Core.Logging; @@ -29,6 +30,7 @@ namespace Umbraco.Tests.Migrations var ctx = runner.InitializeMigrations( //new List {new DoRunMigration(), new DoNotRunMigration()}, migrations.ToList(), + // fixme Database vs UmbracoDatabase new Database("umbracoDbDSN") , DatabaseProviders.SqlServerCE, Mock.Of(), true); @@ -48,6 +50,7 @@ namespace Umbraco.Tests.Migrations var ctx = runner.InitializeMigrations( //new List {new DoRunMigration(), new DoNotRunMigration()}, migrations.ToList(), + // fixme Database vs UmbracoDatabase new Database("umbracoDbDSN") , DatabaseProviders.SqlServerCE, Mock.Of(), true); @@ -67,6 +70,7 @@ namespace Umbraco.Tests.Migrations var ctx = runner.InitializeMigrations( //new List {new DoRunMigration(), new DoNotRunMigration()}, migrations.ToList(), + // fixme Database vs UmbracoDatabase new Database("umbracoDbDSN") , DatabaseProviders.SqlServerCE, Mock.Of(), true); diff --git a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs index 8faa4f8717..e21ee81e2b 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text.RegularExpressions; using Moq; +using NPoco; using NUnit.Framework; using Semver; using Umbraco.Core; @@ -58,7 +59,6 @@ namespace Umbraco.Tests.Migrations.Upgrades } var logger = Mock.Of(); - var sqlHelper = Mock.Of(); var sql = GetSyntaxProvider(); //Setup the MigrationRunner @@ -83,11 +83,11 @@ namespace Umbraco.Tests.Migrations.Upgrades new UpdateCmsContentVersionTable(sql, logger), new UpdateCmsPropertyTypeGroupTable(sql, logger)); - bool upgraded = migrationRunner.Execute(db, provider, sqlHelper, true); + bool upgraded = migrationRunner.Execute(db, provider, sql, true); Assert.That(upgraded, Is.True); - var schemaHelper = new DatabaseSchemaHelper(db, Mock.Of(), sqlHelper); + var schemaHelper = new DatabaseSchemaHelper(db, Mock.Of(), sql); bool hasTabTable = schemaHelper.TableExist("cmsTab"); bool hasPropertyTypeGroupTable = schemaHelper.TableExist("cmsPropertyTypeGroup"); diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs index 5ef07ef569..d8d4bd5fe2 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs @@ -68,7 +68,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Mock.Of()); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoNPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Mock.Of()); } public override DatabaseProviders GetDatabaseProvider() @@ -79,6 +79,6 @@ namespace Umbraco.Tests.Migrations.Upgrades public override string GetDatabaseSpecificSqlScript() { return SqlScripts.SqlResources.SqlCe_SchemaAndData_4110; - } + } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs index 856a8fcf4e..6e889313f8 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs @@ -17,13 +17,13 @@ namespace Umbraco.Tests.Migrations.Upgrades { public override void DatabaseSpecificSetUp() { - string filePath = string.Concat(Path, "\\UmbracoPetaPocoTests.sdf"); + string filePath = string.Concat(Path, "\\UmbracoNPocoTests.sdf"); if (!File.Exists(filePath)) { try { - //Delete database file before continueing + //Delete database file before continueing if (File.Exists(filePath)) { File.Delete(filePath); @@ -47,7 +47,7 @@ namespace Umbraco.Tests.Migrations.Upgrades { TestHelper.ClearDatabase(); } - + } public override void DatabaseSpecificTearDown() @@ -65,7 +65,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Mock.Of()); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoNPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Mock.Of()); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index f64b7041ea..0b761d0a67 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs @@ -4,6 +4,7 @@ using System.Data.SqlServerCe; using System.IO; using System.Text.RegularExpressions; using Moq; +using NPoco; using NUnit.Framework; using SQLCE4Umbraco; using Umbraco.Core.Configuration; @@ -58,7 +59,7 @@ namespace Umbraco.Tests.Migrations.Upgrades AppDomain.CurrentDomain.SetData("DataDirectory", Path); //Delete database file before continueing - string filePath = string.Concat(Path, "\\UmbracoPetaPocoTests.sdf"); + string filePath = string.Concat(Path, "\\UmbracoNPocoTests.sdf"); if (File.Exists(filePath)) { File.Delete(filePath); @@ -88,18 +89,18 @@ namespace Umbraco.Tests.Migrations.Upgrades //legacy API database connection close SqlCeContextGuardian.CloseBackgroundConnection(); - string filePath = string.Concat(Path, "\\UmbracoPetaPocoTests.sdf"); + string filePath = string.Concat(Path, "\\UmbracoNPocoTests.sdf"); if (File.Exists(filePath)) { File.Delete(filePath); } } - + public string Path { get; set; } public UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Mock.Of()); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoNPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Mock.Of()); } public string GetDatabaseSpecificSqlScript() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs index 3e49663546..6822728ad4 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs @@ -1,5 +1,6 @@ using System.Linq; using Moq; +using NPoco; using NUnit.Framework; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; @@ -19,6 +20,7 @@ namespace Umbraco.Tests.Migrations.Upgrades { var sqlSyntax = new SqlCeSyntaxProvider(); var migration = new AddIndexToCmsMacroTable(true, sqlSyntax, Mock.Of()); + // fixme Database vs UmbracoDatabase var migrationContext = new MigrationContext(DatabaseProviders.SqlServerCE, new Database("test", "System.Data.SqlClient"), Mock.Of(), sqlSyntax); migration.GetUpExpressions(migrationContext); @@ -35,6 +37,7 @@ namespace Umbraco.Tests.Migrations.Upgrades { var sqlSyntax = new SqlCeSyntaxProvider(); var migration = new AddIndexToCmsMacroPropertyTable(true, sqlSyntax, Mock.Of()); + // fixme Database vs UmbracoDatabase var migrationContext = new MigrationContext(DatabaseProviders.SqlServerCE, new Database("test", "System.Data.SqlClient"), Mock.Of(), sqlSyntax); migration.GetUpExpressions(migrationContext); diff --git a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs index 86b321c9e3..6fa7499553 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs @@ -1,13 +1,17 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using AutoMapper; +using LightInject; using Moq; using NUnit.Framework; using umbraco; using umbraco.cms.presentation; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Logging; +using Umbraco.Core.Manifest; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; @@ -37,10 +41,11 @@ namespace Umbraco.Tests.Models.Mapping public void Setup() { var nullCacheHelper = CacheHelper.CreateDisabledCacheHelper(); + var logger = Mock.Of(); //Create an app context using mocks var appContext = new ApplicationContext( - new DatabaseContext(Mock.Of(), Mock.Of(), Mock.Of(), "test"), + new DatabaseContext(Mock.Of(), logger, Mock.Of(), "test"), //Create service context using mocks new ServiceContext( @@ -52,13 +57,14 @@ namespace Umbraco.Tests.Models.Mapping fileService: _fileService.Object), nullCacheHelper, - new ProfilingLogger(Mock.Of(), Mock.Of())); + new ProfilingLogger(logger, Mock.Of())); //create a fake property editor resolver to return fake property editors Func> typeListProducerList = Enumerable.Empty; _propertyEditorResolver = new Mock( //ctor args - Mock.Of(), Mock.Of(), typeListProducerList, nullCacheHelper.RuntimeCache); + Mock.Of(), logger, typeListProducerList, + new ManifestBuilder(nullCacheHelper.RuntimeCache, new ManifestParser(logger, new DirectoryInfo(TestHelper.CurrentAssemblyDirectory), Mock.Of()))); Mapper.Initialize(configuration => { diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 5883562f3b..db6bab1160 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -27,14 +27,14 @@ namespace Umbraco.Tests.Persistence new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, Mock.Of()), Mock.Of(), new SqlCeSyntaxProvider(), "System.Data.SqlServerCe.4.0"); - //unfortunately we have to set this up because the PetaPocoExtensions require singleton access + //unfortunately we have to set this up because the NPocoExtensions require singleton access ApplicationContext.Current = new ApplicationContext( CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of())) { DatabaseContext = _dbContext, IsReady = true - }; + }; } [TearDown] @@ -78,10 +78,10 @@ namespace Umbraco.Tests.Persistence //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1; + //by default the conn string is: Datasource=|DataDirectory|UmbracoNPocoTests.sdf;Flush Interval=1; //we'll just replace the sdf file with our custom one: //Create the Sql CE database - var engine = new SqlCeEngine(settings.ConnectionString.Replace("UmbracoPetaPocoTests", "DatabaseContextTests")); + var engine = new SqlCeEngine(settings.ConnectionString.Replace("UmbracoNPocoTests", "DatabaseContextTests")); engine.CreateDatabase(); var dbFactory = new DefaultDatabaseFactory(engine.LocalConnectionString, "System.Data.SqlServerCe.4.0", Mock.Of()); @@ -96,7 +96,7 @@ namespace Umbraco.Tests.Persistence var appCtx = new ApplicationContext( new DatabaseContext(Mock.Of(), Mock.Of(), Mock.Of(), "test"), - new ServiceContext(migrationEntryService: Mock.Of()), + new ServiceContext(migrationEntryService: Mock.Of()), CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of())); diff --git a/src/Umbraco.Tests/Persistence/FaultHandling/ConnectionRetryTest.cs b/src/Umbraco.Tests/Persistence/FaultHandling/ConnectionRetryTest.cs index 841db8198c..f97b030dda 100644 --- a/src/Umbraco.Tests/Persistence/FaultHandling/ConnectionRetryTest.cs +++ b/src/Umbraco.Tests/Persistence/FaultHandling/ConnectionRetryTest.cs @@ -10,7 +10,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling public class ConnectionRetryTest { [Test] - public void PetaPocoConnection_Cant_Connect_To_SqlDatabase_With_Invalid_User() + public void Cant_Connect_To_SqlDatabase_With_Invalid_User() { // Arrange const string providerName = "System.Data.SqlClient"; @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling } [Test] - public void PetaPocoConnection_Cant_Connect_To_SqlDatabase_Because_Of_Network() + public void Cant_Connect_To_SqlDatabase_Because_Of_Network() { // Arrange const string providerName = "System.Data.SqlClient"; diff --git a/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs b/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs index 70daccc74c..3ebd40577b 100644 --- a/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs +++ b/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; using Moq; +using NPoco; using NUnit.Framework; using Semver; using Umbraco.Core; @@ -22,6 +24,43 @@ namespace Umbraco.Tests.Persistence.Migrations [TestFixture] public class MigrationStartupHandlerTests { + // NPoco wants a DbConnection and NOT an IDbConnection + // and DbConnection is hard to mock... + private class MockConnection : DbConnection + { + protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) + { + return Mock.Of(); // enough here + } + + public override void Close() + { + throw new NotImplementedException(); + } + + public override void ChangeDatabase(string databaseName) + { + throw new NotImplementedException(); + } + + public override void Open() + { + throw new NotImplementedException(); + } + + public override string ConnectionString { get; set; } + + protected override DbCommand CreateDbCommand() + { + throw new NotImplementedException(); + } + + public override string Database { get; } + public override string DataSource { get; } + public override string ServerVersion { get; } + public override ConnectionState State => ConnectionState.Open; // else NPoco reopens + } + [Test] public void Executes_For_Any_Product_Name_When_Not_Specified() { @@ -29,9 +68,8 @@ namespace Umbraco.Tests.Persistence.Migrations var testHandler1 = new TestMigrationHandler(changed1); testHandler1.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of()))); - var conn = new Mock(); - conn.Setup(x => x.BeginTransaction(It.IsAny())).Returns(Mock.Of()); - var db = new Mock(conn.Object); + var conn = new MockConnection(); + var db = new Mock(conn); var runner1 = new MigrationRunner(Mock.Of(), Mock.Of(), Mock.Of(), new SemVersion(1), new SemVersion(2), "Test1", new IMigration[] { Mock.Of() }); @@ -49,9 +87,8 @@ namespace Umbraco.Tests.Persistence.Migrations var testHandler2 = new TestMigrationHandler("Test2", changed2); testHandler2.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of()))); - var conn = new Mock(); - conn.Setup(x => x.BeginTransaction(It.IsAny())).Returns(Mock.Of()); - var db = new Mock(conn.Object); + var conn = new MockConnection(); + var db = new Mock(conn); var runner1 = new MigrationRunner(Mock.Of(), Mock.Of(), Mock.Of(), new SemVersion(1), new SemVersion(2), "Test1", new IMigration[] { Mock.Of()}); diff --git a/src/Umbraco.Tests/Persistence/NPocoExtensionsTest.cs b/src/Umbraco.Tests/Persistence/NPocoExtensionsTest.cs new file mode 100644 index 0000000000..eb4bdfc23e --- /dev/null +++ b/src/Umbraco.Tests/Persistence/NPocoExtensionsTest.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using NUnit.Framework; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence; +using Umbraco.Tests.TestHelpers; + +namespace Umbraco.Tests.Persistence +{ + // fixme.npoco - is this still appropriate? + // + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] + [TestFixture] + public class NPocoExtensionsTest : BaseDatabaseFactoryTest + { + [SetUp] + public override void Initialize() + { + base.Initialize(); + } + + [TearDown] + public override void TearDown() + { + base.TearDown(); + } + + [Test] + public void Can_Bulk_Insert() + { + // Arrange + var db = DatabaseContext.Database; + + var servers = new List(); + for (var i = 0; i < 1000; i++) + { + servers.Add(new ServerRegistrationDto + { + ServerAddress = "address" + i, + ServerIdentity = "computer" + i, + DateRegistered = DateTime.Now, + IsActive = true, + DateAccessed = DateTime.Now + }); + } + + // Act + using (ProfilingLogger.TraceDuration("starting insert", "finished insert")) + { + db.BulkInsertRecords(SqlSyntax, servers); + } + + // Assert + Assert.That(db.ExecuteScalar("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000)); + } + + [Test] + public void Generate_Bulk_Import_Sql() + { + // Arrange + var db = DatabaseContext.Database; + + var servers = new List(); + for (var i = 0; i < 2; i++) + { + servers.Add(new ServerRegistrationDto + { + ServerAddress = "address" + i, + ServerIdentity = "computer" + i, + DateRegistered = DateTime.Now, + IsActive = true, + DateAccessed = DateTime.Now + }); + } + db.OpenSharedConnection(); + + // Act + string[] sql; + db.GenerateBulkInsertCommand(servers, db.Connection, out sql); + db.CloseSharedConnection(); + + // Assert + Assert.That(sql[0], + Is.EqualTo("INSERT INTO [umbracoServer] ([umbracoServer].[address], [umbracoServer].[computerName], [umbracoServer].[registeredDate], [umbracoServer].[lastNotifiedDate], [umbracoServer].[isActive], [umbracoServer].[isMaster]) VALUES (@0,@1,@2,@3,@4,@5), (@6,@7,@8,@9,@10,@11)")); + } + + + [Test] + public void Generate_Bulk_Import_Sql_Exceeding_Max_Params() + { + // Arrange + var db = DatabaseContext.Database; + + var servers = new List(); + for (var i = 0; i < 1500; i++) + { + servers.Add(new ServerRegistrationDto + { + ServerAddress = "address" + i, + ServerIdentity = "computer" + i, + DateRegistered = DateTime.Now, + IsActive = true, + DateAccessed = DateTime.Now, + IsMaster = true + }); + } + db.OpenSharedConnection(); + + // Act + string[] sql; + db.GenerateBulkInsertCommand(servers, db.Connection, out sql); + db.CloseSharedConnection(); + + // Assert + Assert.That(sql.Length, Is.EqualTo(5)); + foreach (var s in sql) + { + Assert.LessOrEqual(Regex.Matches(s, "@\\d+").Count, 2000); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/PetaPocoCachesTest.cs b/src/Umbraco.Tests/Persistence/PetaPocoCachesTest.cs new file mode 100644 index 0000000000..965341d7ea --- /dev/null +++ b/src/Umbraco.Tests/Persistence/PetaPocoCachesTest.cs @@ -0,0 +1,193 @@ +using System; +using System.Linq; +using NUnit.Framework; +using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Tests.Services; +using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.TestHelpers.Entities; + +namespace Umbraco.Tests.Persistence +{ + // fixme.npoco - what shall we do with those tests? + // + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] + [TestFixture, Ignore] + public class PetaPocoCachesTest : BaseServiceTest + { + /// + /// This tests the peta poco caches + /// + /// + /// This test WILL fail. This is because we cannot stop PetaPoco from creating more cached items for queries such as + /// ContentTypeRepository.GetAll(1,2,3,4); + /// when combined with other GetAll queries that pass in an array of Ids, each query generated for different length + /// arrays will produce a unique query which then gets added to the cache. + /// + /// This test confirms this, if you analyze the DIFFERENCE output below you can see why the cached queries grow. + /// + //[Test] + //public void Check_Peta_Poco_Caches() + //{ + // var result = new List>>(); + + // Database.PocoData.UseLongKeys = true; + + // for (int i = 0; i < 2; i++) + // { + // int id1, id2, id3; + // string alias; + // CreateStuff(out id1, out id2, out id3, out alias); + // QueryStuff(id1, id2, id3, alias); + + // double totalBytes1; + // IEnumerable keys; + // Console.Write(PocoData.PrintDebugCacheReport(out totalBytes1, out keys)); + + // result.Add(new Tuple>(totalBytes1, keys.Count(), keys)); + // } + + // for (int index = 0; index < result.Count; index++) + // { + // var tuple = result[index]; + // Console.WriteLine("Bytes: {0}, Delegates: {1}", tuple.Item1, tuple.Item2); + // if (index != 0) + // { + // Console.WriteLine("----------------DIFFERENCE---------------------"); + // var diff = tuple.Item3.Except(result[index - 1].Item3); + // foreach (var d in diff) + // { + // Console.WriteLine(d); + // } + // } + + // } + + // var allByteResults = result.Select(x => x.Item1).Distinct(); + // var totalKeys = result.Select(x => x.Item2).Distinct(); + + // Assert.AreEqual(1, allByteResults.Count()); + // Assert.AreEqual(1, totalKeys.Count()); + //} + + //[Test] + //public void Verify_Memory_Expires() + //{ + // Database.PocoData.SlidingExpirationSeconds = 2; + + // var managedCache = new Database.ManagedCache(); + + // int id1, id2, id3; + // string alias; + // CreateStuff(out id1, out id2, out id3, out alias); + // QueryStuff(id1, id2, id3, alias); + + // var count1 = managedCache.GetCache().GetCount(); + // Console.WriteLine("Keys = " + count1); + // Assert.Greater(count1, 0); + + // Thread.Sleep(10000); + + // var count2 = managedCache.GetCache().GetCount(); + // Console.WriteLine("Keys = " + count2); + // Assert.Less(count2, count1); + //} + + private void QueryStuff(int id1, int id2, int id3, string alias1) + { + var contentService = ServiceContext.ContentService; + + ServiceContext.TagService.GetTagsForEntity(id1); + + ServiceContext.TagService.GetAllContentTags(); + + ServiceContext.TagService.GetTagsForEntity(id2); + + ServiceContext.TagService.GetTagsForEntity(id3); + + contentService.CountDescendants(id3); + + contentService.CountChildren(id3); + + contentService.Count(contentTypeAlias: alias1); + + contentService.Count(); + + contentService.GetById(Guid.NewGuid()); + + contentService.GetByLevel(2); + + contentService.GetChildren(id1); + + contentService.GetDescendants(id2); + + contentService.GetVersions(id3); + + contentService.GetRootContent(); + + contentService.GetContentForExpiration(); + + contentService.GetContentForRelease(); + + contentService.GetContentInRecycleBin(); + + ((ContentService)contentService).GetPublishedDescendants(new Content("Test", -1, new ContentType(-1)) + { + Id = id1, + Path = "-1," + id1 + }); + + contentService.GetByVersion(Guid.NewGuid()); + } + + private void CreateStuff(out int id1, out int id2, out int id3, out string alias) + { + var contentService = ServiceContext.ContentService; + + var ctAlias = "umbTextpage" + Guid.NewGuid().ToString("N"); + alias = ctAlias; + + for (int i = 0; i < 20; i++) + { + contentService.CreateContentWithIdentity("Test", -1, "umbTextpage", 0); + } + var contentTypeService = ServiceContext.ContentTypeService; + var contentType = MockedContentTypes.CreateSimpleContentType(ctAlias, "test Doc Type"); + contentTypeService.Save(contentType); + for (int i = 0; i < 20; i++) + { + contentService.CreateContentWithIdentity("Test", -1, ctAlias, 0); + } + var parent = contentService.CreateContentWithIdentity("Test", -1, ctAlias, 0); + id1 = parent.Id; + + for (int i = 0; i < 20; i++) + { + contentService.CreateContentWithIdentity("Test", parent, ctAlias); + } + IContent current = parent; + for (int i = 0; i < 20; i++) + { + current = contentService.CreateContentWithIdentity("Test", current, ctAlias); + } + contentType = MockedContentTypes.CreateSimpleContentType("umbMandatory" + Guid.NewGuid().ToString("N"), "Mandatory Doc Type", true); + contentType.PropertyGroups.First().PropertyTypes.Add( + new PropertyType("test", DataTypeDatabaseType.Ntext, "tags") + { + DataTypeDefinitionId = 1041 + }); + contentTypeService.Save(contentType); + var content1 = MockedContent.CreateSimpleContent(contentType, "Tagged content 1", -1); + content1.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true); + contentService.Publish(content1); + id2 = content1.Id; + + var content2 = MockedContent.CreateSimpleContent(contentType, "Tagged content 2", -1); + content2.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true); + contentService.Publish(content2); + id3 = content2.Id; + + contentService.MoveToRecycleBin(content1); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/PetaPocoExtensionsTest.cs b/src/Umbraco.Tests/Persistence/PetaPocoExtensionsTest.cs deleted file mode 100644 index 96aae1bcc2..0000000000 --- a/src/Umbraco.Tests/Persistence/PetaPocoExtensionsTest.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Rdbms; -using Umbraco.Core.Persistence; -using Umbraco.Core.Services; -using Umbraco.Tests.Services; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; - -namespace Umbraco.Tests.Persistence -{ - [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] - [TestFixture, NUnit.Framework.Ignore] - public class PetaPocoCachesTest : BaseServiceTest - { - /// - /// This tests the peta poco caches - /// - /// - /// This test WILL fail. This is because we cannot stop PetaPoco from creating more cached items for queries such as - /// ContentTypeRepository.GetAll(1,2,3,4); - /// when combined with other GetAll queries that pass in an array of Ids, each query generated for different length - /// arrays will produce a unique query which then gets added to the cache. - /// - /// This test confirms this, if you analyze the DIFFERENCE output below you can see why the cached queries grow. - /// - [Test] - public void Check_Peta_Poco_Caches() - { - var result = new List>>(); - - Database.PocoData.UseLongKeys = true; - - for (int i = 0; i < 2; i++) - { - int id1, id2, id3; - string alias; - CreateStuff(out id1, out id2, out id3, out alias); - QueryStuff(id1, id2, id3, alias); - - double totalBytes1; - IEnumerable keys; - Console.Write(Database.PocoData.PrintDebugCacheReport(out totalBytes1, out keys)); - - result.Add(new Tuple>(totalBytes1, keys.Count(), keys)); - } - - for (int index = 0; index < result.Count; index++) - { - var tuple = result[index]; - Console.WriteLine("Bytes: {0}, Delegates: {1}", tuple.Item1, tuple.Item2); - if (index != 0) - { - Console.WriteLine("----------------DIFFERENCE---------------------"); - var diff = tuple.Item3.Except(result[index - 1].Item3); - foreach (var d in diff) - { - Console.WriteLine(d); - } - } - - } - - var allByteResults = result.Select(x => x.Item1).Distinct(); - var totalKeys = result.Select(x => x.Item2).Distinct(); - - Assert.AreEqual(1, allByteResults.Count()); - Assert.AreEqual(1, totalKeys.Count()); - } - - [Test] - public void Verify_Memory_Expires() - { - Database.PocoData.SlidingExpirationSeconds = 2; - - var managedCache = new Database.ManagedCache(); - - int id1, id2, id3; - string alias; - CreateStuff(out id1, out id2, out id3, out alias); - QueryStuff(id1, id2, id3, alias); - - var count1 = managedCache.GetCache().GetCount(); - Console.WriteLine("Keys = " + count1); - Assert.Greater(count1, 0); - - Thread.Sleep(10000); - - var count2 = managedCache.GetCache().GetCount(); - Console.WriteLine("Keys = " + count2); - Assert.Less(count2, count1); - } - - private void QueryStuff(int id1, int id2, int id3, string alias1) - { - var contentService = ServiceContext.ContentService; - - ServiceContext.TagService.GetTagsForEntity(id1); - - ServiceContext.TagService.GetAllContentTags(); - - ServiceContext.TagService.GetTagsForEntity(id2); - - ServiceContext.TagService.GetTagsForEntity(id3); - - contentService.CountDescendants(id3); - - contentService.CountChildren(id3); - - contentService.Count(contentTypeAlias: alias1); - - contentService.Count(); - - contentService.GetById(Guid.NewGuid()); - - contentService.GetByLevel(2); - - contentService.GetChildren(id1); - - contentService.GetDescendants(id2); - - contentService.GetVersions(id3); - - contentService.GetRootContent(); - - contentService.GetContentForExpiration(); - - contentService.GetContentForRelease(); - - contentService.GetContentInRecycleBin(); - - ((ContentService)contentService).GetPublishedDescendants(new Content("Test", -1, new ContentType(-1)) - { - Id = id1, - Path = "-1," + id1 - }); - - contentService.GetByVersion(Guid.NewGuid()); - } - - private void CreateStuff(out int id1, out int id2, out int id3, out string alias) - { - var contentService = ServiceContext.ContentService; - - var ctAlias = "umbTextpage" + Guid.NewGuid().ToString("N"); - alias = ctAlias; - - for (int i = 0; i < 20; i++) - { - contentService.CreateContentWithIdentity("Test", -1, "umbTextpage", 0); - } - var contentTypeService = ServiceContext.ContentTypeService; - var contentType = MockedContentTypes.CreateSimpleContentType(ctAlias, "test Doc Type"); - contentTypeService.Save(contentType); - for (int i = 0; i < 20; i++) - { - contentService.CreateContentWithIdentity("Test", -1, ctAlias, 0); - } - var parent = contentService.CreateContentWithIdentity("Test", -1, ctAlias, 0); - id1 = parent.Id; - - for (int i = 0; i < 20; i++) - { - contentService.CreateContentWithIdentity("Test", parent, ctAlias); - } - IContent current = parent; - for (int i = 0; i < 20; i++) - { - current = contentService.CreateContentWithIdentity("Test", current, ctAlias); - } - contentType = MockedContentTypes.CreateSimpleContentType("umbMandatory" + Guid.NewGuid().ToString("N"), "Mandatory Doc Type", true); - contentType.PropertyGroups.First().PropertyTypes.Add( - new PropertyType("test", DataTypeDatabaseType.Ntext, "tags") - { - DataTypeDefinitionId = 1041 - }); - contentTypeService.Save(contentType); - var content1 = MockedContent.CreateSimpleContent(contentType, "Tagged content 1", -1); - content1.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true); - contentService.Publish(content1); - id2 = content1.Id; - - var content2 = MockedContent.CreateSimpleContent(contentType, "Tagged content 2", -1); - content2.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true); - contentService.Publish(content2); - id3 = content2.Id; - - contentService.MoveToRecycleBin(content1); - } - } - - [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] - [TestFixture] - public class PetaPocoExtensionsTest : BaseDatabaseFactoryTest - { - [SetUp] - public override void Initialize() - { - base.Initialize(); - } - - [TearDown] - public override void TearDown() - { - base.TearDown(); - } - - [Test] - public void Can_Bulk_Insert() - { - // Arrange - var db = DatabaseContext.Database; - - var servers = new List(); - for (var i = 0; i < 1000; i++) - { - servers.Add(new ServerRegistrationDto - { - ServerAddress = "address" + i, - ServerIdentity = "computer" + i, - DateRegistered = DateTime.Now, - IsActive = true, - DateAccessed = DateTime.Now - }); - } - - // Act - using (ProfilingLogger.TraceDuration("starting insert", "finished insert")) - { - db.BulkInsertRecords(SqlSyntax, servers); - } - - // Assert - Assert.That(db.ExecuteScalar("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000)); - } - - [Test] - public void Generate_Bulk_Import_Sql() - { - // Arrange - var db = DatabaseContext.Database; - - var servers = new List(); - for (var i = 0; i < 2; i++) - { - servers.Add(new ServerRegistrationDto - { - ServerAddress = "address" + i, - ServerIdentity = "computer" + i, - DateRegistered = DateTime.Now, - IsActive = true, - DateAccessed = DateTime.Now - }); - } - db.OpenSharedConnection(); - - // Act - string[] sql; - db.GenerateBulkInsertCommand(servers, db.Connection, out sql); - db.CloseSharedConnection(); - - // Assert - Assert.That(sql[0], - Is.EqualTo("INSERT INTO [umbracoServer] ([umbracoServer].[address], [umbracoServer].[computerName], [umbracoServer].[registeredDate], [umbracoServer].[lastNotifiedDate], [umbracoServer].[isActive], [umbracoServer].[isMaster]) VALUES (@0,@1,@2,@3,@4,@5), (@6,@7,@8,@9,@10,@11)")); - } - - - [Test] - public void Generate_Bulk_Import_Sql_Exceeding_Max_Params() - { - // Arrange - var db = DatabaseContext.Database; - - var servers = new List(); - for (var i = 0; i < 1500; i++) - { - servers.Add(new ServerRegistrationDto - { - ServerAddress = "address" + i, - ServerIdentity = "computer" + i, - DateRegistered = DateTime.Now, - IsActive = true, - DateAccessed = DateTime.Now, - IsMaster = true - }); - } - db.OpenSharedConnection(); - - // Act - string[] sql; - db.GenerateBulkInsertCommand(servers, db.Connection, out sql); - db.CloseSharedConnection(); - - // Assert - Assert.That(sql.Length, Is.EqualTo(5)); - foreach (var s in sql) - { - Assert.LessOrEqual(Regex.Matches(s, "@\\d+").Count, 2000); - } - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs index 99b3a3cdce..d926d3ce43 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; @@ -23,21 +24,21 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[umbracoNode]").On("[cmsContent].[nodeId] = [umbracoNode].[id]") .Where("([umbracoNode].[nodeObjectType] = @0)", new Guid("c66ba18e-eaf3-4cff-8a22-41b16d66a972")); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectType); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectType); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); Assert.AreEqual(expected.Arguments.Length, sql.Arguments.Length); - for (int i = 0; i < expected.Arguments.Length; i++) + for (var i = 0; i < expected.Arguments.Length; i++) { Assert.AreEqual(expected.Arguments[i], sql.Arguments[i]); } @@ -50,8 +51,8 @@ namespace Umbraco.Tests.Persistence.Querying { var NodeObjectType = new Guid(Constants.ObjectTypes.Document); - var expected = new Sql(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsDocument]") .InnerJoin("[cmsContentVersion]").On("[cmsDocument].[versionId] = [cmsContentVersion].[VersionId]") .InnerJoin("[cmsContent]").On("[cmsContentVersion].[ContentId] = [cmsContent].[nodeId]") @@ -59,17 +60,17 @@ namespace Umbraco.Tests.Persistence.Querying .Where("([umbracoNode].[nodeObjectType] = @0)", new Guid("c66ba18e-eaf3-4cff-8a22-41b16d66a972")) .Where("([umbracoNode].[id] = @0)", 1050); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectType) - .Where(SqlSyntax, x => x.NodeId == 1050); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectType) + .Where(x => x.NodeId == 1050); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -99,19 +100,19 @@ namespace Umbraco.Tests.Persistence.Querying .Where("([cmsContentVersion].[VersionId] = @0)", new Guid("2b543516-a944-4ee6-88c6-8813da7aaa07")) .OrderBy("[cmsContentVersion].[VersionDate] DESC"); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectType) - .Where(SqlSyntax, x => x.NodeId == 1050) - .Where(SqlSyntax, x => x.VersionId == versionId) - .OrderByDescending(SqlSyntax, x => x.VersionDate); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectType) + .Where(x => x.NodeId == 1050) + .Where(x => x.VersionId == versionId) + .OrderByDescending(x => x.VersionDate); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); Assert.AreEqual(expected.Arguments.Length, sql.Arguments.Length); @@ -136,13 +137,13 @@ namespace Umbraco.Tests.Persistence.Querying expected.Where("([cmsPropertyData].[contentNodeId] = @0)", 1050); expected.Where("([cmsPropertyData].[versionId] = @0)", new Guid("2b543516-a944-4ee6-88c6-8813da7aaa07")); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) - .Where(SqlSyntax, x => x.NodeId == id) - .Where(SqlSyntax, x => x.VersionId == versionId); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.PropertyTypeId, right => right.Id) + .Where(x => x.NodeId == id) + .Where(x => x.VersionId == versionId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); Assert.AreEqual(expected.Arguments.Length, sql.Arguments.Length); diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs index bf2d0693ae..6c16ce927a 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; @@ -15,9 +16,8 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Verify_Base_Clause() { var nodeObjectType = new Guid(Constants.ObjectTypes.DocumentType); - var sqlSyntaxProvider = new SqlCeSyntaxProvider(); - var expected = new Sql(); + var expected = Sql(); expected.Select("*") .From("[cmsDocumentType]") .RightJoin("[cmsContentType]") @@ -27,15 +27,15 @@ namespace Umbraco.Tests.Persistence.Querying .Where("([umbracoNode].[nodeObjectType] = @0)", new Guid("a2cb7800-f571-4787-9638-bc48539a0efb")) .Where("([cmsDocumentType].[IsDefault] = @0)", true); - var sql = new Sql(); - sql.Select("*") - .From(sqlSyntaxProvider) - .RightJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.NodeId, right => right.ContentTypeNodeId) - .InnerJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.NodeId, right => right.NodeId) - .Where(sqlSyntaxProvider, x => x.NodeObjectType == nodeObjectType) - .Where(sqlSyntaxProvider, x => x.IsDefault == true); + var sql = Sql(); + sql.SelectAll() + .From() + .RightJoin() + .On(left => left.NodeId, right => right.ContentTypeNodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == nodeObjectType) + .Where(x => x.IsDefault == true); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -52,10 +52,9 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Verify_Base_Where_Clause() { var nodeObjectType = new Guid(Constants.ObjectTypes.DocumentType); - var sqlSyntaxProvider = new SqlCeSyntaxProvider(); - var expected = new Sql(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsDocumentType]") .RightJoin("[cmsContentType]") .On("[cmsContentType].[nodeId] = [cmsDocumentType].[contentTypeNodeId]") @@ -65,16 +64,16 @@ namespace Umbraco.Tests.Persistence.Querying .Where("[cmsDocumentType].[IsDefault] = @0", true) .Where("([umbracoNode].[id] = @0)", 1050); - var sql = new Sql(); - sql.Select("*") - .From(sqlSyntaxProvider) - .RightJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.NodeId, right => right.ContentTypeNodeId) - .InnerJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.NodeId, right => right.NodeId) - .Where(sqlSyntaxProvider, x => x.NodeObjectType == nodeObjectType) - .Where(sqlSyntaxProvider, x => x.IsDefault) - .Where(sqlSyntaxProvider, x => x.NodeId == 1050); + var sql = Sql(); + sql.SelectAll() + .From() + .RightJoin() + .On(left => left.NodeId, right => right.ContentTypeNodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == nodeObjectType) + .Where(x => x.IsDefault) + .Where(x => x.NodeId == 1050); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -90,20 +89,19 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_Verify_PerformQuery_Clause() { - var sqlSyntaxProvider = new SqlCeSyntaxProvider(); - var expected = new Sql(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsPropertyTypeGroup]") .RightJoin("[cmsPropertyType]").On("[cmsPropertyTypeGroup].[id] = [cmsPropertyType].[propertyTypeGroupId]") .InnerJoin("[cmsDataType]").On("[cmsPropertyType].[dataTypeId] = [cmsDataType].[nodeId]"); - var sql = new Sql(); - sql.Select("*") - .From(sqlSyntaxProvider) - .RightJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.Id, right => right.PropertyTypeGroupId) - .InnerJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.DataTypeId, right => right.DataTypeId); + var sql = Sql(); + sql.SelectAll() + .From() + .RightJoin() + .On(left => left.Id, right => right.PropertyTypeGroupId) + .InnerJoin() + .On(left => left.DataTypeId, right => right.DataTypeId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -113,16 +111,15 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_Verify_AllowedContentTypeIds_Clause() { - var expected = new Sql(); - var sqlSyntaxProvider = new SqlCeSyntaxProvider(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsContentTypeAllowedContentType]") .Where("([cmsContentTypeAllowedContentType].[Id] = @0)", 1050); - var sql = new Sql(); - sql.Select("*") - .From(sqlSyntaxProvider) - .Where(sqlSyntaxProvider, x => x.Id == 1050); + var sql = Sql(); + sql.SelectAll() + .From() + .Where(x => x.Id == 1050); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -138,22 +135,21 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_Verify_PropertyGroupCollection_Clause() { - var expected = new Sql(); - var sqlSyntaxProvider = new SqlCeSyntaxProvider(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsPropertyTypeGroup]") .RightJoin("[cmsPropertyType]").On("[cmsPropertyTypeGroup].[id] = [cmsPropertyType].[propertyTypeGroupId]") .InnerJoin("[cmsDataType]").On("[cmsPropertyType].[dataTypeId] = [cmsDataType].[nodeId]") .Where("([cmsPropertyType].[contentTypeId] = @0)", 1050); - var sql = new Sql(); - sql.Select("*") - .From(sqlSyntaxProvider) - .RightJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.Id, right => right.PropertyTypeGroupId) - .InnerJoin(sqlSyntaxProvider) - .On(sqlSyntaxProvider, left => left.DataTypeId, right => right.DataTypeId) - .Where(sqlSyntaxProvider, x => x.ContentTypeId == 1050); + var sql = Sql(); + sql.SelectAll() + .From() + .RightJoin() + .On(left => left.Id, right => right.PropertyTypeGroupId) + .InnerJoin() + .On(left => left.DataTypeId, right => right.DataTypeId) + .Where(x => x.ContentTypeId == 1050); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs b/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs index 8c299d414b..006d2dc659 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs @@ -3,12 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Relators; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Tests.TestHelpers; diff --git a/src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs index 55805282a4..5ba86af69d 100644 --- a/src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; @@ -21,12 +22,12 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[umbracoNode]").On("[cmsDataType].[nodeId] = [umbracoNode].[id]") .Where("([umbracoNode].[nodeObjectType] = @0)", new Guid("30a2a501-1978-4ddb-a57b-f7efed43ba3c")); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.DataTypeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.DataTypeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); diff --git a/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs b/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs index 9100a77eb0..ce8fa1068a 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs @@ -1,11 +1,13 @@ using System; using System.Linq.Expressions; using Moq; +using NPoco; using NUnit.Framework; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.SqlSyntax; @@ -14,7 +16,7 @@ using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Persistence.Querying { [TestFixture] - public class ExpressionTests + public class ExpressionTests : BaseUsingSqlCeSyntax { // [Test] // public void Can_Query_With_Content_Type_Alias() @@ -34,9 +36,8 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Verify_Path_StartsWith_Predicate_In_Same_Result() { //Arrange - var sqlSyntax = new SqlCeSyntaxProvider(); Expression> predicate = content => content.Path.StartsWith("-1"); - var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(sqlSyntax, new ContentMapper(sqlSyntax)); + var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(SqlContext.SqlSyntax, new ContentMapper(SqlContext.SqlSyntax)); var result = modelToSqlExpressionHelper.Visit(predicate); Console.WriteLine("Model to Sql ExpressionHelper: \n" + result); @@ -49,9 +50,8 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Verify_ParentId_StartsWith_Predicate_In_Same_Result() { //Arrange - var sqlSyntax = new SqlCeSyntaxProvider(); Expression> predicate = content => content.ParentId == -1; - var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(sqlSyntax, new ContentMapper(sqlSyntax)); + var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(SqlContext.SqlSyntax, new ContentMapper(SqlContext.SqlSyntax)); var result = modelToSqlExpressionHelper.Visit(predicate); Console.WriteLine("Model to Sql ExpressionHelper: \n" + result); @@ -63,9 +63,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Equals_Operator_For_Value_Gets_Escaped() { - var sqlSyntax = new SqlCeSyntaxProvider(); Expression> predicate = user => user.Username == "hello@world.com"; - var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(sqlSyntax, new UserMapper(sqlSyntax)); + var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(SqlContext.SqlSyntax, new UserMapper(SqlContext.SqlSyntax)); var result = modelToSqlExpressionHelper.Visit(predicate); Console.WriteLine("Model to Sql ExpressionHelper: \n" + result); @@ -79,7 +78,7 @@ namespace Umbraco.Tests.Persistence.Querying { var sqlSyntax = new SqlCeSyntaxProvider(); Expression> predicate = user => user.Username.Equals("hello@world.com"); - var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(sqlSyntax, new UserMapper(sqlSyntax)); + var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(SqlContext.SqlSyntax, new UserMapper(SqlContext.SqlSyntax)); var result = modelToSqlExpressionHelper.Visit(predicate); Console.WriteLine("Model to Sql ExpressionHelper: \n" + result); @@ -93,8 +92,10 @@ namespace Umbraco.Tests.Persistence.Querying { //mysql escapes backslashes, so we'll test with that var sqlSyntax = new MySqlSyntaxProvider(Mock.Of()); + var sqlContext = new SqlContext(sqlSyntax, SqlContext.PocoDataFactory, DatabaseType.MySQL); + Expression> predicate = user => user.Username.Equals("mydomain\\myuser"); - var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(sqlSyntax, new UserMapper(sqlSyntax)); + var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper(sqlContext.SqlSyntax, new UserMapper(sqlContext.SqlSyntax)); var result = modelToSqlExpressionHelper.Visit(predicate); Console.WriteLine("Model to Sql ExpressionHelper: \n" + result); @@ -109,8 +110,10 @@ namespace Umbraco.Tests.Persistence.Querying { //mysql escapes backslashes, so we'll test with that var sqlSyntax = new MySqlSyntaxProvider(Mock.Of()); + var sqlContext = new SqlContext(sqlSyntax, SqlContext.PocoDataFactory, DatabaseType.MySQL); + Expression> predicate = user => user.Login.StartsWith("mydomain\\myuser"); - var modelToSqlExpressionHelper = new PocoToSqlExpressionHelper(sqlSyntax); + var modelToSqlExpressionHelper = new PocoToSqlExpressionHelper(sqlContext); var result = modelToSqlExpressionHelper.Visit(predicate); Console.WriteLine("Poco to Sql ExpressionHelper: \n" + result); diff --git a/src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs index 5d4501eb15..6fcbd6643e 100644 --- a/src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; @@ -22,14 +23,14 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[umbracoNode]").On("[cmsContent].[nodeId] = [umbracoNode].[id]") .Where("([umbracoNode].[nodeObjectType] = @0)", new Guid("b796f64c-1f99-4ffb-b886-4bf4bc011a9c")); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); diff --git a/src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs index 6d6ec4ed2c..f1893f6ee5 100644 --- a/src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; @@ -21,12 +22,12 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[umbracoNode]").On("[cmsContentType].[nodeId] = [umbracoNode].[id]") .Where("([umbracoNode].[nodeObjectType] = @0)", new Guid("4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e")); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); diff --git a/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs b/src/Umbraco.Tests/Persistence/Querying/NPocoSqlTests.cs similarity index 63% rename from src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs rename to src/Umbraco.Tests/Persistence/Querying/NPocoSqlTests.cs index 705e625d47..de0081be23 100644 --- a/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/NPocoSqlTests.cs @@ -1,18 +1,15 @@ using System; -using System.Linq; +using NPoco; using NUnit.Framework; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Tests.TestHelpers; using Umbraco.Core.Persistence.Querying; namespace Umbraco.Tests.Persistence.Querying { [TestFixture] - public class PetaPocoSqlTests : BaseUsingSqlCeSyntax + public class NPocoSqlTests : BaseUsingSqlCeSyntax { //x => @@ -20,8 +17,8 @@ namespace Umbraco.Tests.Persistence.Querying public void Where_Clause_With_Starts_With_Additional_Parameters() { var content = new NodeDto() { NodeId = 123, Path = "-1,123" }; - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Path.SqlStartsWith(content.Path, TextColumnType.NVarchar)); + var sql = Sql().SelectAll().From() + .Where(x => x.Path.SqlStartsWith(content.Path, TextColumnType.NVarchar)); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (upper([umbracoNode].[path]) LIKE upper(@0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -32,8 +29,8 @@ namespace Umbraco.Tests.Persistence.Querying public void Where_Clause_With_Starts_With_By_Variable() { var content = new NodeDto() {NodeId = 123, Path = "-1,123"}; - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Path.StartsWith(content.Path) && x.NodeId != content.NodeId); + var sql = Sql().SelectAll().From() + .Where(x => x.Path.StartsWith(content.Path) && x.NodeId != content.NodeId); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((upper([umbracoNode].[path]) LIKE upper(@0) AND ([umbracoNode].[id] <> @1)))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(2, sql.Arguments.Length); @@ -44,9 +41,9 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_Not_Starts_With() { - var level = 1; - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Level == level && !x.Path.StartsWith("-20")); + const int level = 1; + var sql = Sql().SelectAll().From() + .Where(x => x.Level == level && !x.Path.StartsWith("-20")); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[level] = @0) AND NOT (upper([umbracoNode].[path]) LIKE upper(@1))))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(2, sql.Arguments.Length); @@ -57,8 +54,9 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_EqualsFalse_Starts_With() { - var level = 1; - var sql = new Sql("SELECT *").From(SqlSyntax).Where(SqlSyntax, x => x.Level == level && x.Path.StartsWith("-20") == false); + const int level = 1; + var sql = Sql().SelectAll().From() + .Where(x => x.Level == level && x.Path.StartsWith("-20") == false); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[level] = @0) AND NOT (upper([umbracoNode].[path]) LIKE upper(@1))))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(2, sql.Arguments.Length); @@ -69,8 +67,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_Equals_Clause() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Text.Equals("Hello@world.com")); + var sql = Sql().SelectAll().From() + .Where(x => x.Text.Equals("Hello@world.com")); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (upper([umbracoNode].[text]) = upper(@0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -80,8 +78,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_False_Boolean() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => !x.Trashed); + var sql = Sql().SelectAll().From() + .Where(x => x.Trashed == false); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (NOT ([umbracoNode].[trashed] = @0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -91,7 +89,7 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_EqualsFalse_Boolean() { - var sql = new Sql("SELECT *").From(SqlSyntax).Where(SqlSyntax, x => x.Trashed == false); + var sql = Sql().SelectAll().From().Where(x => x.Trashed == false); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (NOT ([umbracoNode].[trashed] = @0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -101,8 +99,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_Boolean() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Trashed); + var sql = Sql().SelectAll().From() + .Where(x => x.Trashed); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ([umbracoNode].[trashed] = @0)", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -112,8 +110,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_ToUpper() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Text.ToUpper() == "hello".ToUpper()); + var sql = Sql().SelectAll().From() + .Where(x => x.Text.ToUpper() == "hello".ToUpper()); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((upper([umbracoNode].[text]) = upper(@0)))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -123,8 +121,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_ToString() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Text == 1.ToString()); + var sql = Sql().SelectAll().From() + .Where(x => x.Text == 1.ToString()); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (([umbracoNode].[text] = @0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -134,8 +132,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_With_Wildcard() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Text.StartsWith("D")); + var sql = Sql().SelectAll().From() + .Where(x => x.Text.StartsWith("D")); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (upper([umbracoNode].[text]) LIKE upper(@0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -145,8 +143,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_Single_Constant() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeId == 2); + var sql = Sql().SelectAll().From() + .Where(x => x.NodeId == 2); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (([umbracoNode].[id] = @0))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(1, sql.Arguments.Length); @@ -156,8 +154,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_And_Constant() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeId != 2 && x.NodeId != 3); + var sql = Sql().SelectAll().From() + .Where(x => x.NodeId != 2 && x.NodeId != 3); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[id] <> @0) AND ([umbracoNode].[id] <> @1)))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(2, sql.Arguments.Length); @@ -168,8 +166,8 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Where_Clause_Or_Constant() { - var sql = new Sql("SELECT *").From(SqlSyntax) - .Where(SqlSyntax, x => x.Text == "hello" || x.NodeId == 3); + var sql = Sql().SelectAll().From() + .Where(x => x.Text == "hello" || x.NodeId == 3); Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[text] = @0) OR ([umbracoNode].[id] = @1)))", sql.SQL.Replace("\n", " ")); Assert.AreEqual(2, sql.Arguments.Length); @@ -180,11 +178,11 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_Select_From_With_Type() { - var expected = new Sql(); - expected.Select("*").From("[cmsContent]"); + var expected = Sql(); + expected.SelectAll().From("[cmsContent]"); - var sql = new Sql(); - sql.Select("*").From(SqlSyntax); + var sql = Sql(); + sql.SelectAll().From(); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -194,16 +192,16 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_InnerJoin_With_Types() { - var expected = new Sql(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsDocument]") .InnerJoin("[cmsContentVersion]") .On("[cmsDocument].[versionId] = [cmsContentVersion].[VersionId]"); - var sql = new Sql(); - sql.Select("*").From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.VersionId, right => right.VersionId); + var sql = Sql(); + sql.SelectAll().From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -213,11 +211,11 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_OrderBy_With_Type() { - var expected = new Sql(); - expected.Select("*").From("[cmsContent]").OrderBy("([cmsContent].[contentType])"); + var expected = Sql(); + expected.SelectAll().From("[cmsContent]").OrderBy("([cmsContent].[contentType])"); - var sql = new Sql(); - sql.Select("*").From(SqlSyntax).OrderBy(SqlSyntax, x => x.ContentTypeId); + var sql = Sql(); + sql.SelectAll().From().OrderBy(x => x.ContentTypeId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -227,11 +225,11 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_GroupBy_With_Type() { - var expected = new Sql(); - expected.Select("*").From("[cmsContent]").GroupBy("[contentType]"); + var expected = Sql(); + expected.SelectAll().From("[cmsContent]").GroupBy("[contentType]"); - var sql = new Sql(); - sql.Select("*").From(SqlSyntax).GroupBy(SqlSyntax, x => x.ContentTypeId); + var sql = Sql(); + sql.SelectAll().From().GroupBy(x => x.ContentTypeId); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -241,11 +239,11 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_Use_Where_Predicate() { - var expected = new Sql(); - expected.Select("*").From("[cmsContent]").Where("([cmsContent].[nodeId] = @0)", 1045); + var expected = Sql(); + expected.SelectAll().From("[cmsContent]").Where("([cmsContent].[nodeId] = @0)", 1045); - var sql = new Sql(); - sql.Select("*").From(SqlSyntax).Where(SqlSyntax, x => x.NodeId == 1045); + var sql = Sql(); + sql.SelectAll().From().Where(x => x.NodeId == 1045); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); @@ -255,17 +253,17 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Can_Use_Where_And_Predicate() { - var expected = new Sql(); - expected.Select("*") + var expected = Sql(); + expected.SelectAll() .From("[cmsContent]") .Where("([cmsContent].[nodeId] = @0)", 1045) .Where("([cmsContent].[contentType] = @0)", 1050); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .Where(SqlSyntax, x => x.NodeId == 1045) - .Where(SqlSyntax, x => x.ContentTypeId == 1050); + var sql = Sql(); + sql.SelectAll() + .From() + .Where(x => x.NodeId == 1045) + .Where(x => x.ContentTypeId == 1050); Assert.That(sql.SQL, Is.EqualTo(expected.SQL)); diff --git a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs b/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs index 62582ace64..9844e6fb26 100644 --- a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs @@ -1,4 +1,5 @@ using System; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; @@ -18,11 +19,11 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Build_StartsWith_Query_For_IContent() { // Arrange - var sql = new Sql(); - sql.Select("*"); + var sql = Sql(); + sql.SelectAll(); sql.From("umbracoNode"); - var query = new Query(SqlSyntax, MappingResolver).Where(x => x.Path.StartsWith("-1")); + var query = new Query(SqlContext.SqlSyntax, MappingResolver).Where(x => x.Path.StartsWith("-1")); // Act var translator = new SqlTranslator(sql, query); @@ -45,11 +46,11 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Build_ParentId_Query_For_IContent() { // Arrange - var sql = new Sql(); - sql.Select("*"); + var sql = Sql(); + sql.SelectAll(); sql.From("umbracoNode"); - var query = new Query(SqlSyntax, MappingResolver).Where(x => x.ParentId == -1); + var query = new Query(SqlContext.SqlSyntax, MappingResolver).Where(x => x.ParentId == -1); // Act var translator = new SqlTranslator(sql, query); @@ -72,11 +73,11 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Build_ContentTypeAlias_Query_For_IContentType() { // Arrange - var sql = new Sql(); - sql.Select("*"); + var sql = Sql(); + sql.SelectAll(); sql.From("umbracoNode"); - var query = new Query(SqlSyntax, MappingResolver).Where(x => x.Alias == "umbTextpage"); + var query = new Query(SqlContext.SqlSyntax, MappingResolver).Where(x => x.Alias == "umbTextpage"); // Act var translator = new SqlTranslator(sql, query); @@ -102,18 +103,18 @@ namespace Umbraco.Tests.Persistence.Querying var id = 1046; var nodeObjectTypeId = new Guid(Constants.ObjectTypes.Document); - var sql = new Sql(); - sql.Select("*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.VersionId, right => right.VersionId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == nodeObjectTypeId); + var sql = Sql(); + sql.SelectAll() + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == nodeObjectTypeId); - var query = new Query(SqlSyntax, MappingResolver).Where(x => x.Path.StartsWith(path) && x.Id != id && x.Published == true && x.Trashed == false); + var query = new Query(SqlContext.SqlSyntax, MappingResolver).Where(x => x.Path.StartsWith(path) && x.Id != id && x.Published == true && x.Trashed == false); // Act var translator = new SqlTranslator(sql, query); diff --git a/src/Umbraco.Tests/Persistence/Repositories/AuditRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/AuditRepositoryTest.cs index 29c2960cf8..6be6bd5f6e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/AuditRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/AuditRepositoryTest.cs @@ -15,7 +15,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Add_Audit_Entry() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new AuditRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index c78abce427..f118bf1b55 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -19,6 +19,7 @@ using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Tests.Persistence.Repositories { @@ -48,17 +49,17 @@ namespace Umbraco.Tests.Persistence.Repositories private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out TemplateRepository templateRepository) { - templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of()); - var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, Mock.Of()); - contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, templateRepository, Mock.Of()); - var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, contentTypeRepository, templateRepository, tagRepository, Mock.Of(), Mock.Of()); + templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), MappingResolver); + var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver); + contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, templateRepository, MappingResolver); + var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, contentTypeRepository, templateRepository, tagRepository, Mock.Of(), MappingResolver); return repository; } [Test] public void Rebuild_Xml_Structures_With_Non_Latest_Version() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -110,7 +111,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Rebuild_All_Xml_Structures() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -157,7 +158,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Rebuild_All_Xml_Structures_For_Content_Type() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -223,7 +224,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Ensures_Permissions_Are_Set_If_Parent_Entity_Permissions_Exist() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; @@ -257,7 +258,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -281,7 +282,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_With_Default_Template() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; TemplateRepository templateRepository; @@ -313,7 +314,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Save_Content_With_AtSign_In_Name_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -347,7 +348,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Multiple_Adds_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -378,7 +379,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Fresh_Entity_Is_Not_Dirty() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -396,7 +397,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -419,7 +420,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_With_Null_Template() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -441,7 +442,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -470,7 +471,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -496,7 +497,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -514,7 +515,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_All_With_Many_Version() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -541,11 +542,25 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void RegexAliasTest() + { + var regex = VersionableRepositoryBaseAliasRegex.For(new SqlServerSyntaxProvider()); + Assert.AreEqual(@"(\[\w+]\.\[\w+])\s+AS\s+(\[\w+])", regex.ToString()); + const string sql = "SELECT [table].[column1] AS [alias1], [table].[column2] AS [alias2] FROM [table];"; + var matches = regex.Matches(sql); + Assert.AreEqual(2, matches.Count); + Assert.AreEqual("[table].[column1]", matches[0].Groups[1].Value); + Assert.AreEqual("[alias1]", matches[0].Groups[2].Value); + Assert.AreEqual("[table].[column2]", matches[1].Groups[1].Value); + Assert.AreEqual("[alias2]", matches[1].Groups[2].Value); + } + [Test] public void Can_Perform_GetPagedResultsByQuery_ForFirstPage_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -566,7 +581,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_ForSecondPage_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -587,7 +602,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithSinglePage_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -608,7 +623,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithDescendingOrder_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -629,7 +644,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithFilterMatchingSome_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -650,7 +665,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithFilterMatchingAll_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -671,7 +686,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Param_Ids_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -690,7 +705,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -711,7 +726,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -730,7 +745,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_ContentRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -749,7 +764,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Keys_Set() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) @@ -770,7 +785,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Get_Content_By_Guid_Key() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs index 2c1404683f..1d27925fc5 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -75,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Maps_Templates_Correctly() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var templateRepo = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), MappingResolver)) using (var repository = CreateRepository(unitOfWork)) @@ -110,7 +110,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Move() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var containerRepository = CreateContainerRepository(unitOfWork, Constants.ObjectTypes.DocumentTypeContainerGuid)) using (var repository = CreateRepository(unitOfWork)) @@ -156,7 +156,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; using (var containerRepository = CreateContainerRepository(unitOfWork, Constants.ObjectTypes.DocumentTypeContainerGuid)) @@ -176,7 +176,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; using (var containerRepository = CreateContainerRepository(unitOfWork, Constants.ObjectTypes.DocumentTypeContainerGuid)) @@ -201,7 +201,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container_Containing_Media_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var containerRepository = CreateContainerRepository(unitOfWork, Constants.ObjectTypes.MediaTypeContainerGuid)) using (var repository = CreateRepository(unitOfWork)) @@ -222,7 +222,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container_Containing_Media_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; IMediaType contentType; @@ -258,7 +258,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -289,7 +289,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_ContentTypeRepository_After_Model_Mapping() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -338,7 +338,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -414,7 +414,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_ContentTypeRepository_After_Model_Mapping() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -477,7 +477,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -501,7 +501,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_With_Heirarchy_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -531,7 +531,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Query_On_ContentTypeRepository_Sort_By_Name() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -560,7 +560,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -578,7 +578,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_By_Guid_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -600,7 +600,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_By_Missing_Guid_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -616,7 +616,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -638,7 +638,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Guid_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -661,7 +661,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_ContentTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -678,7 +678,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_ContentType_With_PropertyType_Removed() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -702,7 +702,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyTypes_On_SimpleTextpage() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -720,7 +720,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyTypes_On_Textpage() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -738,7 +738,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyType_With_No_Group() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -772,7 +772,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_AllowedChildContentTypes_On_ContentType() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -806,7 +806,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Removal_Of_Used_PropertyType_From_ContentType() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository repository; using (var contentRepository = CreateRepository(unitOfWork, out repository)) @@ -833,7 +833,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Addition_Of_PropertyType_After_ContentType_Is_Used() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository repository; using (var contentRepository = CreateRepository(unitOfWork, out repository)) @@ -861,7 +861,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Usage_Of_New_PropertyType_On_Content() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository repository; using (var contentRepository = CreateRepository(unitOfWork, out repository)) @@ -897,7 +897,7 @@ namespace Umbraco.Tests.Persistence.Repositories () { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository repository; using (var contentRepository = CreateRepository(unitOfWork, out repository)) diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index bc5314abb1..075093c92e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -1,12 +1,14 @@ using System; using System.Data; using System.Linq; +using System.Reflection; using System.Text.RegularExpressions; using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.DependencyInjection; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -32,6 +34,23 @@ namespace Umbraco.Tests.Persistence.Repositories base.Initialize(); } + protected override CacheHelper CreateCacheHelper() + { + // hackish, but it works + var testName = TestContext.CurrentContext.Test.Name; + if (testName == "Can_Get_Pre_Value_As_String_With_Cache" + || testName == "Can_Get_Pre_Value_Collection_With_Cache") + { + return new CacheHelper( + new ObjectCacheRuntimeCacheProvider(), + new StaticCacheProvider(), + new StaticCacheProvider(), + new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); // default would be NullCacheProvider + } + + return base.CreateCacheHelper(); + } + private IDataTypeDefinitionRepository CreateRepository(IDatabaseUnitOfWork unitOfWork) { return Container.GetInstance(unitOfWork); @@ -39,7 +58,7 @@ namespace Umbraco.Tests.Persistence.Repositories private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork) { - return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, Mock.Of(), Constants.ObjectTypes.DataTypeContainerGuid); + return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, MappingResolver, Constants.ObjectTypes.DataTypeContainerGuid); } [TestCase("UmbracoPreVal87-21,3,48", 3, true)] @@ -62,7 +81,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Move() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) @@ -82,7 +101,7 @@ namespace Umbraco.Tests.Persistence.Repositories repository.AddOrUpdate(dataType); unitOfWork.Commit(); - //create a + //create a var dataType2 = (IDataTypeDefinition)new DataTypeDefinition(dataType.Id, Constants.PropertyEditors.RadioButtonListAlias) { Name = "dt2" @@ -109,14 +128,14 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; using (var containerRepository = CreateContainerRepository(unitOfWork)) { container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; containerRepository.AddOrUpdate(container); - unitOfWork.Commit(); + unitOfWork.Commit(); Assert.That(container.Id, Is.GreaterThan(0)); } using (var containerRepository = CreateContainerRepository(unitOfWork)) @@ -129,7 +148,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; using (var containerRepository = CreateContainerRepository(unitOfWork)) @@ -154,7 +173,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container_Containing_Data_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) @@ -174,7 +193,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container_Containing_Data_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; IDataTypeDefinition dataType; @@ -187,7 +206,7 @@ namespace Umbraco.Tests.Persistence.Repositories dataType = new DataTypeDefinition(container.Id, Constants.PropertyEditors.RadioButtonListAlias) { Name = "test" }; repository.AddOrUpdate(dataType); - unitOfWork.Commit(); + unitOfWork.Commit(); } using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) @@ -208,7 +227,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); int id; using (var repository = CreateRepository(unitOfWork)) @@ -237,7 +256,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -247,16 +266,16 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(dataTypeDefinition, Is.Not.Null); Assert.That(dataTypeDefinition.HasIdentity, Is.True); - Assert.That(dataTypeDefinition.Name, Is.EqualTo("Dropdown")); + Assert.That(dataTypeDefinition.Name, Is.EqualTo("Dropdown")); } - + } [Test] public void Can_Perform_GetAll_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -276,7 +295,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_With_Params_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -296,7 +315,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -316,7 +335,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -334,7 +353,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -361,7 +380,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -395,7 +414,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -427,7 +446,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_DataTypeDefinitionRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -445,7 +464,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Pre_Value_Collection() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); int dtid; @@ -470,7 +489,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Pre_Value_As_String() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); int dtid; @@ -495,21 +514,15 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Pre_Value_Collection_With_Cache() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - var cache = new CacheHelper( - new ObjectCacheRuntimeCacheProvider(), - new StaticCacheProvider(), - new StaticCacheProvider(), - new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); - DataTypeDefinition dtd; using (var repository = Container.GetInstance(unitOfWork)) { dtd = new DataTypeDefinition(-1, Constants.PropertyEditors.RadioButtonListAlias) { Name = "test" }; repository.AddOrUpdate(dtd); - unitOfWork.Commit(); + unitOfWork.Commit(); } DatabaseContext.Database.Insert(new DataTypePreValueDto() { DataTypeNodeId = dtd.Id, SortOrder = 0, Value = "test1" }); @@ -521,7 +534,10 @@ namespace Umbraco.Tests.Persistence.Repositories var collection = repository.GetPreValuesCollectionByDataTypeId(dtd.Id); } - var cached = cache.IsolatedRuntimeCache.GetCache().Result + // note: see CreateCacheHelper, this test uses a special cache + var cache = CacheHelper.IsolatedRuntimeCache.GetCache(); + Assert.IsTrue(cache); + var cached = cache.Result .GetCacheItemsByKeySearch(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-"); Assert.IsNotNull(cached); @@ -532,15 +548,9 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Pre_Value_As_String_With_Cache() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - var cache = new CacheHelper( - new ObjectCacheRuntimeCacheProvider(), - new StaticCacheProvider(), - new StaticCacheProvider(), - new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); - DataTypeDefinition dtd; using (var repository = Container.GetInstance(unitOfWork)) { @@ -558,7 +568,10 @@ namespace Umbraco.Tests.Persistence.Repositories var val = repository.GetPreValueAsString(Convert.ToInt32(id)); } - var cached = cache.IsolatedRuntimeCache.GetCache().Result + // note: see CreateCacheHelper, this test uses a special cache + var cache = CacheHelper.IsolatedRuntimeCache.GetCache(); + Assert.IsTrue(cache); + var cached = cache.Result .GetCacheItemsByKeySearch(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-"); Assert.IsNotNull(cached); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DictionaryRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DictionaryRepositoryTest.cs index f0c428473f..9febecaef4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DictionaryRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DictionaryRepositoryTest.cs @@ -36,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_By_Key_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_By_UniqueId_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) @@ -102,7 +102,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) @@ -136,7 +136,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_DictionaryRepository_When_No_Language_Assigned() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) @@ -163,7 +163,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -184,7 +184,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_With_Params_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -204,7 +204,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -224,7 +224,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -242,7 +242,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var languageRepository = Container.GetInstance(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) @@ -273,7 +273,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -300,7 +300,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_WithNewTranslation_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repository = CreateRepository(unitOfWork); @@ -328,7 +328,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -349,7 +349,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_DictionaryRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs index 1b00f0089c..c68a1fb76a 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs @@ -30,7 +30,7 @@ namespace Umbraco.Tests.Persistence.Repositories private int CreateTestData(string isoName, out ContentType ct) { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentRepository contentRepo; @@ -54,7 +54,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_And_Get_By_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -89,7 +89,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_And_Get_By_Id_Empty_lang() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -122,7 +122,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Cant_Create_Duplicate_Domain_Name() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -155,7 +155,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -190,7 +190,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Update() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -242,7 +242,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Exists() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -273,7 +273,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_By_Name() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -304,7 +304,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_All() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -335,7 +335,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_All_Ids() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -368,7 +368,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_All_Without_Wildcards() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -403,7 +403,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_All_For_Content() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; @@ -454,7 +454,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_All_For_Content_Without_Wildcards() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentType ct; diff --git a/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs index bcad6e0720..9e30c9e71a 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs @@ -37,8 +37,9 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); + unitOfWork.Database.EnableSqlTrace = true; using (var repository = CreateRepository(unitOfWork)) { // Act @@ -55,7 +56,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Perform_Get_By_Iso_Code_On_LanguageRepository() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -81,7 +82,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Perform_Get_By_Culture_Name_On_LanguageRepository() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -108,7 +109,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Get_WhenIdDoesntExist_ReturnsNull() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -124,7 +125,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -144,7 +145,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_With_Params_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -164,7 +165,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -184,7 +185,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -202,7 +203,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -222,7 +223,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -248,7 +249,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -269,7 +270,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_LanguageRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs index 6ea233aa1a..9e4655baa3 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs @@ -30,7 +30,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Cannot_Add_Duplicate_Macros() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Cannot_Update_To_Duplicate_Macro_Alias() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act @@ -66,7 +66,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Instantiate_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act @@ -81,7 +81,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -111,7 +111,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -128,7 +128,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -145,7 +145,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -162,7 +162,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -183,7 +183,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -224,7 +224,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -245,7 +245,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -263,7 +263,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Add_Property_For_Macro() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -290,7 +290,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Add_New_Macro_With_Property() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -315,7 +315,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Remove_Macro_Property() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -340,7 +340,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Add_Remove_Macro_Properties() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -371,7 +371,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_Property_For_Macro() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -399,7 +399,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_Macro_Property_Alias() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { @@ -428,7 +428,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void CreateTestData() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var unitOfWork = provider.GetUnitOfWork()) using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index 0a53bbae7d..3cbed428f2 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -44,7 +44,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Rebuild_All_Xml_Structures() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -72,7 +72,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Rebuild_All_Xml_Structures_For_Content_Type() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -113,7 +113,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -137,7 +137,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Multiple_Adds_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -168,7 +168,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Multiple_Adds_On_MediaRepository_With_RepositoryResolver() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -199,7 +199,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Fresh_Entity_Is_Not_Dirty() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -218,7 +218,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -242,7 +242,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -266,7 +266,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -293,7 +293,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -311,7 +311,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_ForFirstPage_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -332,7 +332,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_ForSecondPage_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -353,7 +353,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithSinglePage_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -374,7 +374,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithDescendingOrder_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -395,7 +395,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WitAlternateOrder_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -416,7 +416,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithFilterMatchingSome_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -437,7 +437,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetPagedResultsByQuery_WithFilterMatchingAll_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -458,7 +458,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Param_Ids_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -478,7 +478,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -498,7 +498,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) @@ -520,7 +520,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_MediaRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs index fd7c440527..d85ff5a72e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs @@ -40,7 +40,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Move() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) @@ -86,7 +86,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; using (var containerRepository = CreateContainerRepository(unitOfWork)) @@ -106,7 +106,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; using (var containerRepository = CreateContainerRepository(unitOfWork)) @@ -132,7 +132,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container_Containing_Media_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) @@ -153,7 +153,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container_Containing_Media_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; IMediaType contentType; @@ -189,7 +189,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -212,7 +212,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -249,7 +249,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -274,7 +274,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -293,7 +293,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_By_Guid_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -313,7 +313,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -334,7 +334,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Guid_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -359,7 +359,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_MediaTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -376,7 +376,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_MediaType_With_PropertyType_Removed() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -403,7 +403,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyTypes_On_Video_MediaType() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -424,7 +424,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyTypes_On_File_MediaType() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index c47c46b1be..23796ca3ca 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Xml.Linq; using Moq; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; @@ -46,14 +47,14 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Rebuild_All_Xml_Structures() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; using (var repository = CreateRepository(unitOfWork, out memberTypeRepository, out memberGroupRepository)) { var memberType1 = CreateTestMemberType(); - + for (var i = 0; i < 100; i++) { var member = MockedMember.CreateSimpleMember(memberType1, "blah" + i, "blah" + i + "@example.com", "blah", "blah" + i); @@ -74,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Rebuild_All_Xml_Structures_For_Content_Type() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -102,7 +103,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); @@ -117,7 +118,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void MemberRepository_Can_Get_Member_By_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -135,7 +136,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Members_By_Ids() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -157,7 +158,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void MemberRepository_Can_Get_All_Members() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -182,7 +183,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void MemberRepository_Can_Perform_GetByQuery_With_Key() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -204,7 +205,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Persist_Member() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -215,19 +216,19 @@ namespace Umbraco.Tests.Persistence.Repositories var sut = repository.Get(member.Id); Assert.That(sut, Is.Not.Null); - Assert.That(sut.HasIdentity, Is.True); + Assert.That(sut.HasIdentity, Is.True); Assert.That(sut.Properties.Any(x => x.HasIdentity == false || x.Id == 0), Is.False); Assert.That(sut.Name, Is.EqualTo("Johnny Hefty")); Assert.That(sut.Email, Is.EqualTo("johnny@example.com")); Assert.That(sut.RawPasswordValue, Is.EqualTo("123")); - Assert.That(sut.Username, Is.EqualTo("hefty")); + Assert.That(sut.Username, Is.EqualTo("hefty")); } } [Test] public void New_Member_Has_Built_In_Properties_By_Default() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -261,7 +262,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void MemberRepository_Does_Not_Replace_Password_When_Null() { IMember sut; - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -290,7 +291,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void MemberRepository_Can_Update_Email_And_Login_When_Changed() { IMember sut; - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -327,9 +328,9 @@ namespace Umbraco.Tests.Persistence.Repositories var translator = new SqlTranslator(sqlSubquery, query); var subquery = translator.Translate(); var sql = GetBaseQuery(false) - .Append(new Sql("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments)) - .OrderByDescending(SqlSyntax, x => x.VersionDate) - .OrderBy(SqlSyntax, x => x.SortOrder); + .Append("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments) + .OrderByDescending(x => x.VersionDate) + .OrderBy(x => x.SortOrder); Console.WriteLine(sql.SQL); Assert.That(sql.SQL, Is.Not.Empty); @@ -337,7 +338,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IMember CreateTestMember(IMemberType memberType = null, string name = null, string email = null, string password = null, string username = null, Guid? key = null) { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -347,7 +348,7 @@ namespace Umbraco.Tests.Persistence.Repositories { memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.AddOrUpdate(memberType); - unitOfWork.Commit(); + unitOfWork.Commit(); } var member = MockedMember.CreateSimpleMember(memberType, name ?? "Johnny Hefty", email ?? "johnny@example.com", password ?? "123", username ?? "hefty", key); @@ -360,7 +361,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IMemberType CreateTestMemberType(string alias = null) { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MemberTypeRepository memberTypeRepository; MemberGroupRepository memberGroupRepository; @@ -373,22 +374,22 @@ namespace Umbraco.Tests.Persistence.Repositories } } - private Sql GetBaseQuery(bool isCount) + private Sql GetBaseQuery(bool isCount) { if (isCount) { - var sqlCount = new Sql() - .Select("COUNT(*)") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + var sqlCount = NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, DatabaseContext.Database)) + .SelectCount() + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sqlCount; } - var sql = new Sql(); + var sql = NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, DatabaseContext.Database)); sql.Select("umbracoNode.*", "cmsContent.contentType", "cmsContentType.alias AS ContentTypeAlias", "cmsContentVersion.VersionId", "cmsContentVersion.VersionDate", "cmsMember.Email", "cmsMember.LoginName", "cmsMember.Password", "cmsPropertyData.id AS PropertyDataId", "cmsPropertyData.propertytypeid", @@ -397,33 +398,33 @@ namespace Umbraco.Tests.Persistence.Repositories "cmsPropertyType.Name", "cmsPropertyType.mandatory", "cmsPropertyType.validationRegExp", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", "cmsPropertyType.propertyTypeGroupId", "cmsPropertyType.dataTypeId", "cmsDataType.propertyEditorAlias", "cmsDataType.dbType") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeId, right => right.ContentTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .LeftJoin().On(left => left.ContentTypeId, right => right.ContentTypeId) + .LeftJoin().On(left => left.DataTypeId, right => right.DataTypeId) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) .Append("AND cmsPropertyData.versionId = cmsContentVersion.VersionId") - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; } - private Sql GetSubquery() + private Sql GetSubquery() { - var sql = new Sql(); + var sql = NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, DatabaseContext.Database)); sql.Select("umbracoNode.id") - .From(SqlSyntax) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.ContentTypeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.ContentTypeId, right => right.ContentTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.DataTypeId, right => right.DataTypeId) - .LeftJoin(SqlSyntax).On(SqlSyntax, left => left.PropertyTypeId, right => right.Id) + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .LeftJoin().On(left => left.ContentTypeId, right => right.ContentTypeId) + .LeftJoin().On(left => left.DataTypeId, right => right.DataTypeId) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) .Append("AND cmsPropertyData.versionId = cmsContentVersion.VersionId") - .Where(SqlSyntax, x => x.NodeObjectType == NodeObjectTypeId); + .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; } diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs index b045aac137..9f9ff91842 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Persist_Member_Type() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -62,7 +62,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Cannot_Persist_Member_Type_Without_Alias() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -77,7 +77,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_Member_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -101,7 +101,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_Member_Types_By_Guid_Ids() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -125,7 +125,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Member_Types_By_Guid_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -152,7 +152,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_Members_When_No_Properties_Assigned() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -179,7 +179,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Member_Type_By_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -194,7 +194,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Member_Type_By_Guid_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -209,7 +209,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Built_In_Member_Type_Properties_Are_Automatically_Added_When_Creating() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -229,7 +229,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Built_In_Member_Type_Properties_Are_Not_Reused_For_Different_Member_Types() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -250,7 +250,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Delete_MemberType() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs index 4d28e909ca..071a419477 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs @@ -20,7 +20,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void CreateNotification() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repo = new NotificationsRepository(unitOfWork, SqlSyntax); @@ -40,7 +40,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void GetUserNotifications() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repo = new NotificationsRepository(unitOfWork, SqlSyntax); @@ -66,7 +66,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void GetEntityNotifications() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repo = new NotificationsRepository(unitOfWork, SqlSyntax); @@ -93,7 +93,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Delete_By_Entity() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repo = new NotificationsRepository(unitOfWork, SqlSyntax); @@ -120,7 +120,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Delete_By_User() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repo = new NotificationsRepository(unitOfWork, SqlSyntax); diff --git a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs index db3dd297ff..1115751688 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs @@ -25,7 +25,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -54,8 +54,9 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); + unitOfWork.Database.EnableSqlTrace = true; using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { var entry = new PublicAccessEntry(content[0], content[1], content[2], new[] @@ -87,12 +88,57 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Can_Add2() + { + var content = CreateTestData(3).ToArray(); + + var provider = new NPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + unitOfWork.Database.EnableSqlTrace = true; + using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) + { + var entry = new PublicAccessEntry(content[0], content[1], content[2], new[] + { + new PublicAccessRule + { + RuleValue = "test", + RuleType = "RoleName" + }, + new PublicAccessRule + { + RuleValue = "test2", + RuleType = "RoleName2" + }, + }); + repo.AddOrUpdate(entry); + unitOfWork.Commit(); + + var found = repo.GetAll().ToArray(); + + Assert.AreEqual(1, found.Length); + Assert.AreEqual(content[0].Id, found[0].ProtectedNodeId); + Assert.AreEqual(content[1].Id, found[0].LoginNodeId); + Assert.AreEqual(content[2].Id, found[0].NoAccessNodeId); + Assert.IsTrue(found[0].HasIdentity); + Assert.AreNotEqual(default(DateTime), found[0].CreateDate); + Assert.AreNotEqual(default(DateTime), found[0].UpdateDate); + Assert.AreEqual(2, found[0].Rules.Count()); + Assert.AreEqual("test", found[0].Rules.First().RuleValue); + Assert.AreEqual("RoleName", found[0].Rules.First().RuleType); + Assert.AreNotEqual(default(DateTime), found[0].Rules.First().CreateDate); + Assert.AreNotEqual(default(DateTime), found[0].Rules.First().UpdateDate); + Assert.IsTrue(found[0].Rules.First().HasIdentity); + Assert.AreEqual("test2", found[0].Rules.Skip(1).First().RuleValue); + } + } + [Test] public void Can_Update() { var content = CreateTestData(3).ToArray(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -129,7 +175,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -156,7 +202,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -193,7 +239,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -236,7 +282,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IEnumerable CreateTestData(int count) { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository ctRepo; using (var repo = CreateRepository(unitOfWork, out ctRepo)) diff --git a/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs index 49f53bef1f..6ed8062a33 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/RelationRepositoryTest.cs @@ -39,7 +39,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -61,7 +61,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -86,7 +86,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -108,7 +108,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -130,7 +130,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -151,7 +151,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_With_Params_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -172,7 +172,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -192,7 +192,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -211,7 +211,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_RelationRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -233,7 +233,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Delete_Content_And_Verify_Relation_Is_Removed() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); RelationTypeRepository repositoryType; using (var repository = CreateRepository(unitOfWork, out repositoryType)) @@ -263,7 +263,7 @@ namespace Umbraco.Tests.Persistence.Repositories var relateContent = new RelationType(new Guid(Constants.ObjectTypes.Document), new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"), "relateContentOnCopy") { IsBidirectional = true, Name = "Relate Content on Copy" }; var relateContentType = new RelationType(new Guid(Constants.ObjectTypes.DocumentType), new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB"), "relateContentTypeOnCopy") { IsBidirectional = true, Name = "Relate ContentType on Copy" }; - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var relationTypeRepository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver); var relationRepository = new RelationRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, relationTypeRepository, MappingResolver); diff --git a/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs index cd4263df03..34817131f1 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -60,7 +60,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -86,7 +86,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -107,7 +107,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -127,7 +127,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -147,7 +147,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_With_Params_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -167,7 +167,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -186,7 +186,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -204,7 +204,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_RelationTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -233,7 +233,7 @@ namespace Umbraco.Tests.Persistence.Repositories var relateContent = new RelationType(new Guid(Constants.ObjectTypes.Document), new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"), "relateContentOnCopy") { IsBidirectional = true, Name = "Relate Content on Copy" }; var relateContentType = new RelationType(new Guid(Constants.ObjectTypes.DocumentType), new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB"), "relateContentTypeOnCopy") { IsBidirectional = true, Name = "Relate ContentType on Copy" }; - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var repository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver); diff --git a/src/Umbraco.Tests/Persistence/Repositories/ServerRegistrationRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ServerRegistrationRepositoryTest.cs index cf5b0e9a3e..8ddb8d45f1 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ServerRegistrationRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ServerRegistrationRepositoryTest.cs @@ -39,7 +39,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Cannot_Add_Duplicate_Server_Identities() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Cannot_Update_To_Duplicate_Server_Identities() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act @@ -75,14 +75,14 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Instantiate_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act using (var repository = CreateRepository(unitOfWork)) { // Assert - Assert.That(repository, Is.Not.Null); + Assert.That(repository, Is.Not.Null); } } @@ -90,7 +90,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -100,17 +100,17 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(server, Is.Not.Null); Assert.That(server.HasIdentity, Is.True); - Assert.That(server.ServerAddress, Is.EqualTo("http://localhost")); + Assert.That(server.ServerAddress, Is.EqualTo("http://localhost")); } - + } [Test] public void Can_Perform_GetAll_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -118,9 +118,9 @@ namespace Umbraco.Tests.Persistence.Repositories var servers = repository.GetAll(); // Assert - Assert.That(servers.Count(), Is.EqualTo(3)); + Assert.That(servers.Count(), Is.EqualTo(3)); } - + } // queries are not supported due to in-memory caching @@ -129,7 +129,7 @@ namespace Umbraco.Tests.Persistence.Repositories //public void Can_Perform_GetByQuery_On_Repository() //{ // // Arrange - // var provider = new PetaPocoUnitOfWorkProvider(Logger); + // var provider = new NPocoUnitOfWorkProvider(Logger); // var unitOfWork = provider.GetUnitOfWork(); // using (var repository = CreateRepository(unitOfWork)) // { @@ -138,7 +138,7 @@ namespace Umbraco.Tests.Persistence.Repositories // var result = repository.GetByQuery(query); // // Assert - // Assert.AreEqual(1, result.Count()); + // Assert.AreEqual(1, result.Count()); // } //} @@ -146,7 +146,7 @@ namespace Umbraco.Tests.Persistence.Repositories //public void Can_Perform_Count_On_Repository() //{ // // Arrange - // var provider = new PetaPocoUnitOfWorkProvider(Logger); + // var provider = new NPocoUnitOfWorkProvider(Logger); // var unitOfWork = provider.GetUnitOfWork(); // using (var repository = CreateRepository(unitOfWork)) // { @@ -155,7 +155,7 @@ namespace Umbraco.Tests.Persistence.Repositories // int count = repository.Count(query); // // Assert - // Assert.That(count, Is.EqualTo(2)); + // Assert.That(count, Is.EqualTo(2)); // } //} @@ -163,7 +163,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -174,15 +174,15 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(server.HasIdentity, Is.True); - Assert.That(server.Id, Is.EqualTo(4));//With 3 existing entries the Id should be 4 - } + Assert.That(server.Id, Is.EqualTo(4));//With 3 existing entries the Id should be 4 + } } [Test] public void Can_Perform_Update_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -199,15 +199,15 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(serverUpdated, Is.Not.Null); Assert.That(serverUpdated.ServerAddress, Is.EqualTo("https://umbraco.com")); - Assert.That(serverUpdated.IsActive, Is.EqualTo(true)); - } + Assert.That(serverUpdated.IsActive, Is.EqualTo(true)); + } } [Test] public void Can_Perform_Delete_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -220,15 +220,15 @@ namespace Umbraco.Tests.Persistence.Repositories var exists = repository.Exists(3); // Assert - Assert.That(exists, Is.False); - } + Assert.That(exists, Is.False); + } } [Test] public void Can_Perform_Exists_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -238,7 +238,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(exists, Is.True); - Assert.That(doesntExist, Is.False); + Assert.That(doesntExist, Is.False); } } @@ -250,7 +250,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void CreateTestData() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var unitOfWork = provider.GetUnitOfWork()) using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs index a71191236b..011bf49a21 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -66,7 +66,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Multiple_Adds_On_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -99,7 +99,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Tag_Relations() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -131,7 +131,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Append_Tag_Relations() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -172,7 +172,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Replace_Tag_Relations() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -216,7 +216,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Merge_Tag_Relations() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -258,7 +258,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Clear_Tag_Relations() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -296,7 +296,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Remove_Specific_Tags_From_Property() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -342,7 +342,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Content_By_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -389,7 +389,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Content_By_Key() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -436,7 +436,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -473,7 +473,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_With_Ids() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -515,7 +515,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Content_For_Group() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -561,7 +561,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Property_By_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -608,7 +608,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Property_By_Key() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -655,7 +655,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Property_For_Group() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -704,7 +704,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Entity_Type() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; ContentTypeRepository contentTypeRepository; @@ -766,7 +766,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Entity_Type_For_Group() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; ContentTypeRepository contentTypeRepository; @@ -823,7 +823,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Cascade_Deletes_Tag_Relations() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); ContentTypeRepository contentTypeRepository; using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) @@ -864,7 +864,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tagged_Entities_For_Tag_Group() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; ContentTypeRepository contentTypeRepository; @@ -951,7 +951,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tagged_Entities_For_Tag() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); MediaTypeRepository mediaTypeRepository; ContentTypeRepository contentTypeRepository; diff --git a/src/Umbraco.Tests/Persistence/Repositories/TaskRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TaskRepositoryTest.cs index 87138d15bf..33c961fcab 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TaskRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TaskRepositoryTest.cs @@ -16,7 +16,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Add() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -75,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Update() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -111,7 +111,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Get_By_Id() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -139,7 +139,7 @@ namespace Umbraco.Tests.Persistence.Repositories { CreateTestData(false, 20); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -154,7 +154,7 @@ namespace Umbraco.Tests.Persistence.Repositories CreateTestData(false, 10); CreateTestData(true, 5); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -169,7 +169,7 @@ namespace Umbraco.Tests.Persistence.Repositories CreateTestData(false, 10, -20); CreateTestData(false, 5, -21); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -184,7 +184,7 @@ namespace Umbraco.Tests.Persistence.Repositories CreateTestData(false, 10); CreateTestData(true, 5); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { @@ -195,7 +195,7 @@ namespace Umbraco.Tests.Persistence.Repositories private void CreateTestData(bool closed, int count, int entityId = -1) { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/TaskTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TaskTypeRepositoryTest.cs index bceb8d54d7..23f2957f16 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TaskTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TaskTypeRepositoryTest.cs @@ -15,7 +15,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); var taskType = new TaskType("asdfasdf"); using (var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, MappingResolver)) diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index 931425ae7f..9b726e2184 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -47,7 +47,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Instantiate_Repository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); // Act @@ -64,7 +64,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_MasterPage_Detect_Content() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -87,7 +87,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_MasterPage_With_Default_Content() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork, Mock.Of(x => x.DefaultRenderingEngine == RenderingEngine.WebForms))) { @@ -113,7 +113,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_MasterPage_With_Default_Content_With_Parent() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork, Mock.Of(x => x.DefaultRenderingEngine == RenderingEngine.WebForms))) { @@ -142,7 +142,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_View() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -162,7 +162,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_View_With_Default_Content() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -188,7 +188,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_View_With_Default_Content_With_Parent() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -216,7 +216,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_Unique_Alias() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -245,7 +245,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_Unique_Alias() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -280,7 +280,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_MasterPage() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -310,7 +310,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_View() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -340,7 +340,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_MasterPage() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -369,7 +369,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_View() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -398,7 +398,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_When_Assigned_To_Doc() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var templateRepository = CreateRepository(unitOfWork)) @@ -443,7 +443,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_Nested_Templates() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -484,7 +484,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Get_Template_Tree() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -510,7 +510,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Get_All() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -537,7 +537,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Get_Children() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -561,7 +561,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Get_Children_At_Root() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -582,7 +582,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Get_Descendants() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -606,7 +606,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Path_Is_Set_Correctly_On_Creation() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -670,7 +670,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Path_Is_Set_Correctly_On_Update() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs index 4569e63959..8d0bbdff77 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs @@ -44,7 +44,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -65,7 +65,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Multiple_Adds_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -90,7 +90,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Fresh_Entity_Is_Not_Dirty() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -112,7 +112,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -162,7 +162,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -193,7 +193,7 @@ namespace Umbraco.Tests.Persistence.Repositories //public void Can_Perform_Delete_On_UserRepository_With_Permissions_Assigned() //{ // // Arrange - // var provider = new PetaPocoUnitOfWorkProvider(Logger); + // var provider = new NPocoUnitOfWorkProvider(Logger); // var unitOfWork = provider.GetUnitOfWork(); // UserTypeRepository userTypeRepository; //using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -223,7 +223,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -244,7 +244,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -264,7 +264,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Param_Ids_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -285,7 +285,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -306,7 +306,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -325,7 +325,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_UserRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -345,7 +345,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Remove_Section_For_User() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -380,7 +380,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Add_Section_For_User() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -424,7 +424,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_Section_For_User() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -452,7 +452,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Get_Users_Assigned_To_Section() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); UserTypeRepository userTypeRepository; using (var repository = CreateRepository(unitOfWork, out userTypeRepository)) @@ -469,7 +469,7 @@ namespace Umbraco.Tests.Persistence.Repositories var users = repository.GetUsersAssignedToSection("test"); - // Assert + // Assert Assert.AreEqual(2, users.Count()); var names = users.Select(x => x.Username).ToArray(); Assert.IsTrue(names.Contains("TestUser1")); @@ -481,11 +481,11 @@ namespace Umbraco.Tests.Persistence.Repositories public void Default_User_Permissions_Based_On_User_Type() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, MappingResolver)) using (var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, utRepo, MappingResolver)) - { + { // Act var user1 = MockedUser.CreateUser(CreateAndCommitUserType(), "1", "test", "media"); @@ -532,7 +532,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IUserType CreateAndCommitUserType() { - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, MappingResolver)) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserTypeRepositoryTest.cs index d3bc64ba4f..012d5c4f0b 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserTypeRepositoryTest.cs @@ -39,7 +39,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -59,7 +59,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Multiple_Adds_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -83,7 +83,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_Fresh_Entity_Is_Not_Dirty() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -104,7 +104,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -131,7 +131,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -161,7 +161,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -186,7 +186,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetByQuery_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -205,7 +205,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Param_Ids_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -225,7 +225,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -245,7 +245,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { @@ -263,7 +263,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Count_On_UserTypeRepository() { // Arrange - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { diff --git a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs index e637e98183..7b9a67a607 100644 --- a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs @@ -1,6 +1,7 @@ using System; using System.IO; using Moq; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; @@ -49,7 +50,7 @@ namespace Umbraco.Tests.Persistence [Test] public void Can_Create_umbracoNode_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -60,7 +61,7 @@ namespace Umbraco.Tests.Persistence [Test] public void Can_Create_umbracoAccess_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -72,7 +73,7 @@ namespace Umbraco.Tests.Persistence [Test] public void Can_Create_umbracoAccessRule_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -86,7 +87,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsContentType2ContentType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -99,7 +100,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsContentTypeAllowedContentType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -113,7 +114,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsContentType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -126,7 +127,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsContentVersion_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -141,7 +142,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsContentXml_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -156,7 +157,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsDataType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -169,7 +170,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsDataTypePreValues_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -183,7 +184,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsDictionary_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -195,7 +196,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsLanguageText_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -209,7 +210,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsTemplate_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -222,7 +223,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsDocument_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -238,7 +239,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsDocumentType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -253,7 +254,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoDomains_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -266,7 +267,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoLanguage_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -278,7 +279,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoLog_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -290,7 +291,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsMacro_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -302,7 +303,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsMember_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -317,7 +318,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsMember2MemberGroup_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -333,7 +334,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsMemberType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -347,7 +348,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsPreviewXml_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -363,7 +364,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsPropertyData_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -380,7 +381,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsPropertyType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -396,7 +397,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsPropertyTypeGroup_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -410,7 +411,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoRelation_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -424,7 +425,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoRelationType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -436,7 +437,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsStylesheet_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -449,7 +450,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsStylesheetProperty_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -462,7 +463,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsTags_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -474,7 +475,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsTagRelationship_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -494,7 +495,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsTask_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -510,7 +511,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_cmsTaskType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -522,7 +523,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoDeployDependency_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -535,7 +536,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoDeployChecksum_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -547,7 +548,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoUser_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -560,7 +561,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoUserType_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); @@ -572,7 +573,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoUser2app_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -586,7 +587,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoUser2NodeNotify_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); @@ -601,7 +602,7 @@ namespace Umbraco.Tests.Persistence public void Can_Create_umbracoUser2NodePermission_Table() { - using (Transaction transaction = DatabaseContext.Database.GetTransaction()) + using (var transaction = DatabaseContext.Database.GetTransaction()) { DatabaseSchemaHelper.CreateTable(); DatabaseSchemaHelper.CreateTable(); diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs index b5ae4a5ed5..7951df2dc6 100644 --- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; @@ -20,17 +21,15 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider [Test] public void Can_Generate_Delete_SubQuery_Statement() { - var sqlSyntax = new SqlCeSyntaxProvider(); - var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); - var subQuery = new Sql() + var subQuery = Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(sqlSyntax) - .InnerJoin(sqlSyntax) - .On(sqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(sqlSyntax, dto => dto.NodeObjectType == mediaObjectType); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == mediaObjectType); - var sqlOutput = sqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); + var sqlOutput = SqlContext.SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); Assert.AreEqual(@"DELETE FROM [cmsContentXml] WHERE [nodeId] IN (SELECT [nodeId] FROM (SELECT DISTINCT cmsContentXml.nodeId FROM [cmsContentXml] @@ -47,15 +46,13 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine, [Test] public void Can_Generate_Create_Table_Statement() { - var sqlSyntax = new SqlCeSyntaxProvider(); - var type = typeof (NodeDto); - var definition = DefinitionFactory.GetTableDefinition(type, sqlSyntax); + var definition = DefinitionFactory.GetTableDefinition(type, SqlContext.SqlSyntax); - string create = sqlSyntax.Format(definition); - string primaryKey = sqlSyntax.FormatPrimaryKey(definition); - var indexes = sqlSyntax.Format(definition.Indexes); - var keys = sqlSyntax.Format(definition.ForeignKeys); + string create = SqlContext.SqlSyntax.Format(definition); + string primaryKey = SqlContext.SqlSyntax.FormatPrimaryKey(definition); + var indexes = SqlContext.SqlSyntax.Format(definition.Indexes); + var keys = SqlContext.SqlSyntax.Format(definition.ForeignKeys); Console.WriteLine(create); Console.WriteLine(primaryKey); @@ -142,7 +139,6 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine, TableName = "TheTable", SchemaName = "dbo" }; - } - + } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs index 3523b61943..19b52c55a8 100644 --- a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs +++ b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs @@ -145,7 +145,7 @@ namespace Umbraco.Tests.Services var pages = MockedContent.CreateTextpageContent(contentType, -1, 100); ServiceContext.ContentService.Save(pages, 0); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var tRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), MappingResolver)) @@ -177,7 +177,7 @@ namespace Umbraco.Tests.Services var pages = MockedContent.CreateTextpageContent(contentType, -1, 1000); ServiceContext.ContentService.Save(pages, 0); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var tRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), MappingResolver)) using (var tagRepo = new TagRepository(unitOfWork, DisabledCache, Logger, SqlSyntax, MappingResolver)) @@ -206,7 +206,7 @@ namespace Umbraco.Tests.Services var pages = MockedContent.CreateTextpageContent(contentType, -1, 100); ServiceContext.ContentService.Save(pages, 0); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var tRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), MappingResolver)) @@ -240,7 +240,7 @@ namespace Umbraco.Tests.Services var pages = MockedContent.CreateTextpageContent(contentType, -1, 1000); ServiceContext.ContentService.Save(pages, 0); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); using (var tRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of(), MappingResolver)) using (var tagRepo = new TagRepository(unitOfWork, DisabledCache, Logger, SqlSyntax, MappingResolver)) diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 1346812c2f..5dea7521c0 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -745,7 +745,7 @@ namespace Umbraco.Tests.Services var content = contentService.GetById(NodeDto.NodeIdSeed + 1); bool published = contentService.Publish(content, 0); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var uow = provider.GetUnitOfWork(); Assert.IsTrue(uow.Database.Exists(content.Id)); @@ -807,7 +807,7 @@ namespace Umbraco.Tests.Services } var allContent = rootContent.Concat(rootContent.SelectMany(x => x.Descendants())); //for testing we need to clear out the contentXml table so we can see if it worked - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var uow = provider.GetUnitOfWork()) { uow.Database.TruncateTable(SqlSyntax, "cmsContentXml"); @@ -841,7 +841,7 @@ namespace Umbraco.Tests.Services } var allContent = rootContent.Concat(rootContent.SelectMany(x => x.Descendants())).ToList(); //for testing we need to clear out the contentXml table so we can see if it worked - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var uow = provider.GetUnitOfWork()) { @@ -1331,8 +1331,10 @@ namespace Umbraco.Tests.Services [Test] public void Can_Save_Lazy_Content() - { - var unitOfWork = PetaPocoUnitOfWorkProvider.CreateUnitOfWork(Logger); + { + var databaseFactory = new DefaultDatabaseFactory(Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName, Logger); + var provider = new NPocoUnitOfWorkProvider(databaseFactory); + var unitOfWork = provider.GetUnitOfWork(); var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage"); var root = ServiceContext.ContentService.GetById(NodeDto.NodeIdSeed + 1); @@ -1447,7 +1449,7 @@ namespace Umbraco.Tests.Services contentService.Save(content); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var uow = provider.GetUnitOfWork()) { @@ -1471,7 +1473,7 @@ namespace Umbraco.Tests.Services contentService.Save(content); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var uow = provider.GetUnitOfWork()) { diff --git a/src/Umbraco.Tests/Services/MacroServiceTests.cs b/src/Umbraco.Tests/Services/MacroServiceTests.cs index 7267568025..7a6f68ff40 100644 --- a/src/Umbraco.Tests/Services/MacroServiceTests.cs +++ b/src/Umbraco.Tests/Services/MacroServiceTests.cs @@ -25,7 +25,7 @@ namespace Umbraco.Tests.Services { base.CreateTestData(); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var unitOfWork = provider.GetUnitOfWork()) using (var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, MappingResolver)) { diff --git a/src/Umbraco.Tests/Services/MediaServiceTests.cs b/src/Umbraco.Tests/Services/MediaServiceTests.cs index 12d4b4b0aa..35c2a9d1b9 100644 --- a/src/Umbraco.Tests/Services/MediaServiceTests.cs +++ b/src/Umbraco.Tests/Services/MediaServiceTests.cs @@ -90,7 +90,7 @@ namespace Umbraco.Tests.Services mediaService.Save(media); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); var uow = provider.GetUnitOfWork(); Assert.IsTrue(uow.Database.Exists(media.Id)); diff --git a/src/Umbraco.Tests/Services/MemberServiceTests.cs b/src/Umbraco.Tests/Services/MemberServiceTests.cs index 17b4e3499c..3e7a59a228 100644 --- a/src/Umbraco.Tests/Services/MemberServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberServiceTests.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Events; @@ -1017,12 +1018,12 @@ namespace Umbraco.Tests.Services result.LastLoginDate.TruncateTo(DateTimeExtensions.DateTruncate.Second)); //now ensure the col is correct - var sql = new Sql().Select("cmsPropertyData.*") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, dto => dto.PropertyTypeId, dto => dto.Id) - .Where(SqlSyntax, dto => dto.NodeId == member.Id) - .Where(SqlSyntax, dto => dto.Alias == Constants.Conventions.Member.LastLoginDate); + var sql = NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, DatabaseContext.Database)).Select("cmsPropertyData.*") + .From() + .InnerJoin() + .On(dto => dto.PropertyTypeId, dto => dto.Id) + .Where(dto => dto.NodeId == member.Id) + .Where(dto => dto.Alias == Constants.Conventions.Member.LastLoginDate); var colResult = DatabaseContext.Database.Fetch(sql); @@ -1056,7 +1057,7 @@ namespace Umbraco.Tests.Services var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); ServiceContext.MemberService.Save(customMember); - var provider = new PetaPocoUnitOfWorkProvider(Logger); + var provider = new NPocoUnitOfWorkProvider(Logger); using (var uow = provider.GetUnitOfWork()) { diff --git a/src/Umbraco.Tests/Services/PerformanceTests.cs b/src/Umbraco.Tests/Services/PerformanceTests.cs index f92866d81f..b362ff3597 100644 --- a/src/Umbraco.Tests/Services/PerformanceTests.cs +++ b/src/Umbraco.Tests/Services/PerformanceTests.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using System.Threading; using System.Xml.Linq; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; @@ -286,8 +287,8 @@ namespace Umbraco.Tests.Services DatabaseContext.Database.BulkInsertRecords(SqlSyntax, nodes); //re-get the nodes with ids - var sql = new Sql(); - sql.Select("*").From(SqlSyntax).Where(SqlSyntax, x => x.NodeObjectType == customObjectType); + var sql = NPoco.Sql.BuilderFor(new SqlContext(SqlSyntax, DatabaseContext.Database)); + sql.SelectAll().From().Where(x => x.NodeObjectType == customObjectType); nodes = DatabaseContext.Database.Fetch(sql); //create the cmsContent data, each with a new content type id (so we can query on it later if needed) diff --git a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs index da7a1079ed..b4560b072b 100644 --- a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Services [TestFixture, RequiresSTA] public class ThreadSafetyServiceTest : BaseDatabaseFactoryTest { - private PerThreadPetaPocoUnitOfWorkProvider _uowProvider; + private PerThreadNPocoUnitOfWorkProvider _uowProvider; private PerThreadDatabaseFactory _dbFactory; [SetUp] @@ -47,7 +47,7 @@ namespace Umbraco.Tests.Services //global Database object but this is NOT how it should work in the web world or in any multi threaded scenario. //we need a new Database object for each thread. var repositoryFactory = new RepositoryFactory(SqlSyntax, Container); - _uowProvider = new PerThreadPetaPocoUnitOfWorkProvider(_dbFactory); + _uowProvider = new PerThreadNPocoUnitOfWorkProvider(_dbFactory); var evtMsgs = new TransientMessagesFactory(); ApplicationContext.Services = new ServiceContext( repositoryFactory, @@ -254,11 +254,11 @@ namespace Umbraco.Tests.Services /// /// Creates a UOW with a Database object per thread /// - internal class PerThreadPetaPocoUnitOfWorkProvider : DisposableObject, IDatabaseUnitOfWorkProvider + internal class PerThreadNPocoUnitOfWorkProvider : DisposableObject, IDatabaseUnitOfWorkProvider { private readonly PerThreadDatabaseFactory _dbFactory; - public PerThreadPetaPocoUnitOfWorkProvider(PerThreadDatabaseFactory dbFactory) + public PerThreadNPocoUnitOfWorkProvider(PerThreadDatabaseFactory dbFactory) { _dbFactory = dbFactory; } @@ -267,7 +267,7 @@ namespace Umbraco.Tests.Services { //Create or get a database instance for this thread. var db = _dbFactory.CreateDatabase(); - return new PetaPocoUnitOfWork(db); + return new NPocoUnitOfWork(db); } protected override void DisposeResources() diff --git a/src/Umbraco.Tests/Services/UserServiceTests.cs b/src/Umbraco.Tests/Services/UserServiceTests.cs index a9ebc159ec..6b522efddd 100644 --- a/src/Umbraco.Tests/Services/UserServiceTests.cs +++ b/src/Umbraco.Tests/Services/UserServiceTests.cs @@ -4,12 +4,9 @@ using System.Security.Cryptography; using System.Text; using NUnit.Framework; using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Web._Legacy.Actions; namespace Umbraco.Tests.Services @@ -397,9 +394,10 @@ namespace Umbraco.Tests.Services var user1 = ServiceContext.UserService.CreateUserWithIdentity("test1", "test1@test.com", userType); - var result1 = ServiceContext.UserService.GetUserById((int)user1.Id); + var result1 = ServiceContext.UserService.GetUserById(user1.Id); //expect 2 sections by default - Assert.AreEqual(2, result1.AllowedSections.Count()); + // 3: see commit eb59d33 + Assert.AreEqual(3, result1.AllowedSections.Count()); //adds some allowed sections user1.AddAllowedSection("test1"); @@ -408,9 +406,9 @@ namespace Umbraco.Tests.Services user1.AddAllowedSection("test4"); ServiceContext.UserService.Save(user1); - result1 = ServiceContext.UserService.GetUserById((int)user1.Id); - //expect 6 sections including the two default sections - Assert.AreEqual(6, result1.AllowedSections.Count()); + result1 = ServiceContext.UserService.GetUserById(user1.Id); + //expect 7 sections including the two default sections + Assert.AreEqual(7, result1.AllowedSections.Count()); //simulate clearing the sections foreach (var s in user1.AllowedSections) @@ -424,7 +422,7 @@ namespace Umbraco.Tests.Services //assert //re-get - result1 = ServiceContext.UserService.GetUserById((int)user1.Id); + result1 = ServiceContext.UserService.GetUserById(user1.Id); Assert.AreEqual(2, result1.AllowedSections.Count()); } @@ -547,7 +545,7 @@ namespace Umbraco.Tests.Services Assert.That(updatedItem.StartMediaId, Is.EqualTo(originalUser.StartMediaId)); Assert.That(updatedItem.Email, Is.EqualTo(originalUser.Email)); Assert.That(updatedItem.Username, Is.EqualTo(originalUser.Username)); - Assert.That(updatedItem.AllowedSections.Count(), Is.EqualTo(2)); + Assert.That(updatedItem.AllowedSections.Count(), Is.EqualTo(3)); // 3: see commit eb59d33 } } } diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index e0ed618da2..abc3c0ee40 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -39,7 +39,7 @@ namespace Umbraco.Tests.TestHelpers { /// /// Use this abstract class for tests that requires a Sql Ce database populated with the umbraco db schema. - /// The PetaPoco Database class should be used through the . + /// The NPoco Database class should be used through the . /// [TestFixture, RequiresSTA] public abstract class BaseDatabaseFactoryTest : BaseUmbracoApplicationTest @@ -86,12 +86,12 @@ namespace Umbraco.Tests.TestHelpers } protected override void SetupApplicationContext() - { + { var dbFactory = new DefaultDatabaseFactory( GetDbConnectionString(), GetDbProviderName(), Logger); - + var evtMsgs = new TransientMessagesFactory(); _appContext = new ApplicationContext( //assign the db context @@ -99,7 +99,7 @@ namespace Umbraco.Tests.TestHelpers //assign the service context new ServiceContext( Container.GetInstance(), - new PetaPocoUnitOfWorkProvider(dbFactory), + new NPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), CacheHelper, @@ -149,7 +149,7 @@ namespace Umbraco.Tests.TestHelpers ///
protected virtual string GetDbConnectionString() { - return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;"; + return @"Datasource=|DataDirectory|UmbracoNPocoTests.sdf;Flush Interval=1;"; } /// @@ -168,7 +168,7 @@ namespace Umbraco.Tests.TestHelpers Core.Configuration.GlobalSettings.UmbracoConnectionName, GetDbConnectionString()); - _dbPath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); + _dbPath = string.Concat(path, "\\UmbracoNPocoTests.sdf"); //create a new database file if // - is the first test in the session @@ -181,7 +181,7 @@ namespace Umbraco.Tests.TestHelpers || (DatabaseTestBehavior == DatabaseBehavior.NewDbFileAndSchemaPerTest || DatabaseTestBehavior == DatabaseBehavior.EmptyDbFilePerTest) || (_isFirstTestInFixture && DatabaseTestBehavior == DatabaseBehavior.NewDbFileAndSchemaPerFixture)) { - + using (ProfilingLogger.TraceDuration("Remove database file")) { RemoveDatabaseFile(ex => @@ -210,7 +210,7 @@ namespace Umbraco.Tests.TestHelpers } } - + /// /// sets up resolvers before resolution is frozen @@ -256,7 +256,7 @@ namespace Umbraco.Tests.TestHelpers //Create the umbraco database and its base data schemaHelper.CreateDatabaseSchema(_appContext); - //close the connections, we're gonna read this baby in as a byte array so we don't have to re-initialize the + //close the connections, we're gonna read this baby in as a byte array so we don't have to re-initialize the // damn db for each test CloseDbConnections(); @@ -291,7 +291,7 @@ namespace Umbraco.Tests.TestHelpers private void CloseDbConnections() { - //Ensure that any database connections from a previous test is disposed. + //Ensure that any database connections from a previous test is disposed. //This is really just double safety as its also done in the TearDown. if (ApplicationContext != null && DatabaseContext != null && DatabaseContext.Database != null) DatabaseContext.Database.Dispose(); @@ -332,7 +332,7 @@ namespace Umbraco.Tests.TestHelpers string path = TestHelper.CurrentAssemblyDirectory; try { - string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); + string filePath = string.Concat(path, "\\UmbracoNPocoTests.sdf"); if (File.Exists(filePath)) { File.Delete(filePath); @@ -368,7 +368,7 @@ namespace Umbraco.Tests.TestHelpers doc.LoadXml(GetXmlContent(templateId)); return doc; }); - + PublishedContentCache.UnitTesting = true; var httpContext = GetHttpContextFactory(url, routeData).HttpContext; @@ -398,7 +398,7 @@ namespace Umbraco.Tests.TestHelpers protected virtual string GetXmlContent(int templateId) { return @" - @@ -411,7 +411,7 @@ namespace Umbraco.Tests.TestHelpers 1 This is some content]]> - + diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs index e6065e780d..24a5c5f34d 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs @@ -193,9 +193,14 @@ namespace Umbraco.Tests.TestHelpers } } - protected virtual void SetupCacheHelper() + private void SetupCacheHelper() { - CacheHelper = CacheHelper.CreateDisabledCacheHelper(); + CacheHelper = CreateCacheHelper(); + } + + protected virtual CacheHelper CreateCacheHelper() + { + return CacheHelper.CreateDisabledCacheHelper(); } /// @@ -211,7 +216,7 @@ namespace Umbraco.Tests.TestHelpers //assign the service context new ServiceContext( Container.GetInstance(), - new PetaPocoUnitOfWorkProvider(Logger), + new NPocoUnitOfWorkProvider(Logger), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), CacheHelper, @@ -241,7 +246,6 @@ namespace Umbraco.Tests.TestHelpers Assembly.Load("Umbraco.Core"), Assembly.Load("umbraco"), Assembly.Load("Umbraco.Tests"), - Assembly.Load("businesslogic"), Assembly.Load("cms"), Assembly.Load("controls"), } diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index f1ff37bbb6..c88df8ba4f 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -1,5 +1,6 @@ using LightInject; using Moq; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; @@ -9,28 +10,31 @@ using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Profiling; using Umbraco.Core.DependencyInjection; +using Umbraco.Core.Persistence; namespace Umbraco.Tests.TestHelpers { [TestFixture] public abstract class BaseUsingSqlCeSyntax { - protected virtual SqlCeSyntaxProvider SqlSyntax - { - get { return new SqlCeSyntaxProvider(); } - } - private MappingResolver _mappingResolver; - protected IMappingResolver MappingResolver + + protected IMappingResolver MappingResolver => _mappingResolver; + + protected SqlContext SqlContext { get; private set; } + + protected Sql Sql() { - get { return _mappingResolver; } + return NPoco.Sql.BuilderFor(SqlContext); } [SetUp] public virtual void Initialize() { + var sqlSyntax = new SqlCeSyntaxProvider(); + var container = new ServiceContainer(); - container.RegisterSingleton(factory => SqlSyntax); + container.RegisterSingleton(factory => sqlSyntax); container.RegisterSingleton(factory => Mock.Of()); container.RegisterSingleton(factory => Mock.Of()); @@ -43,6 +47,10 @@ namespace Umbraco.Tests.TestHelpers logger, false); + var mappers = new MapperCollection { new PocoMapper() }; + var pocoDataFactory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, mappers).Init()); + SqlContext = new SqlContext(sqlSyntax, pocoDataFactory, DatabaseType.SQLCe); + Resolution.Freeze(); SetUp(); } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index d079b3bb83..fb3e318538 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -94,6 +94,10 @@ ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll True + + ..\packages\NPoco.3.1.0-u005\lib\net45\NPoco.dll + True + False ..\packages\NUnit.2.6.2\lib\nunit.framework.dll @@ -197,6 +201,7 @@ + @@ -295,7 +300,7 @@ - + @@ -405,7 +410,7 @@ - + diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config index 7b5780daa2..3c4ac7ecb4 100644 --- a/src/Umbraco.Tests/packages.config +++ b/src/Umbraco.Tests/packages.config @@ -19,6 +19,7 @@ + diff --git a/src/Umbraco.Web/Install/InstallSteps/MajorVersion7UpgradeReport.cs b/src/Umbraco.Web/Install/InstallSteps/MajorVersion7UpgradeReport.cs index f1903f96a4..74c3c683c4 100644 --- a/src/Umbraco.Web/Install/InstallSteps/MajorVersion7UpgradeReport.cs +++ b/src/Umbraco.Web/Install/InstallSteps/MajorVersion7UpgradeReport.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Persistence; diff --git a/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs b/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs index a03f9e36a6..92325ecaa7 100644 --- a/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs +++ b/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core; using Umbraco.Core.Events; using Umbraco.Core.Models; diff --git a/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs b/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs index e51d6d59b8..66958a2c9d 100644 --- a/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs +++ b/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Core.Events; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; @@ -32,19 +33,19 @@ namespace Umbraco.Web.Strategies.Migrations var target = new Version(6, 0, 0); if (e.ConfiguredVersion < target) { - var sql = new Sql(); - sql.Select("*") - .From(_sqlSyntax) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, left => left.VersionId, right => right.VersionId) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, left => left.NodeId, right => right.NodeId) - .InnerJoin(_sqlSyntax) - .On(_sqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(_sqlSyntax, x => x.NodeObjectType == new Guid(Constants.ObjectTypes.Document)) - .Where(_sqlSyntax, x => x.Path.StartsWith("-1")); + var sql = Sql.BuilderFor(new SqlContext(_sqlSyntax, e.MigrationContext.Database)) + .SelectAll() + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == new Guid(Constants.ObjectTypes.Document)) + .Where(x => x.Path.StartsWith("-1")); - var dtos = e.MigrationContext.Database.Fetch(sql); + var dtos = e.MigrationContext.Database.Fetch(sql); var toUpdate = new List(); var versionGroup = dtos.GroupBy(x => x.NodeId); foreach (var grp in versionGroup) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 5ae1a5ec51..66e9b2c6e7 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -197,6 +197,10 @@ ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll True + + ..\packages\NPoco.3.1.0-u005\lib\net45\NPoco.dll + True + False ..\packages\Owin.1.0\lib\net40\Owin.dll @@ -225,6 +229,7 @@ False ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + diff --git a/src/Umbraco.Web/WebApi/Filters/DisableBrowserCacheAttribute.cs b/src/Umbraco.Web/WebApi/Filters/DisableBrowserCacheAttribute.cs index e1890326fb..ad71ccf720 100644 --- a/src/Umbraco.Web/WebApi/Filters/DisableBrowserCacheAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/DisableBrowserCacheAttribute.cs @@ -24,6 +24,9 @@ namespace Umbraco.Web.WebApi.Filters base.OnActionExecuted(actionExecutedContext); + // happens if exception + if (actionExecutedContext.Response == null) return; + //NOTE: Until we upgraded to WebApi 2, this didn't work correctly and we had to revert to using // HttpContext.Current responses. I've changed this back to what it should be now since it works // and now with WebApi2, the HttpContext.Current responses dont! Anyways, all good now. diff --git a/src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs b/src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs index 3e95c9ee22..589801a829 100644 --- a/src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs +++ b/src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs @@ -1,5 +1,6 @@ using System; using System.Web.Http; +using NPoco; using Umbraco.Core; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; @@ -37,13 +38,13 @@ namespace Umbraco.Web.WebServices { var totalPublished = Services.ContentService.CountPublished(); - var subQuery = new Sql() + var subQuery = DatabaseContext.Sql() .Select("DISTINCT cmsContentXml.nodeId") - .From(DatabaseContext.SqlSyntax) - .InnerJoin(DatabaseContext.SqlSyntax) - .On(DatabaseContext.SqlSyntax, left => left.NodeId, right => right.NodeId); + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId); - var totalXml = ApplicationContext.DatabaseContext.Database.ExecuteScalar("SELECT COUNT(*) FROM (" + subQuery.SQL + ") as tmp"); + var totalXml = DatabaseContext.Database.ExecuteScalar("SELECT COUNT(*) FROM (" + subQuery.SQL + ") as tmp"); return totalXml == totalPublished; } @@ -53,13 +54,13 @@ namespace Umbraco.Web.WebServices { var total = Services.MediaService.Count(); var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); - var subQuery = new Sql() - .Select("Count(*)") - .From(DatabaseContext.SqlSyntax) - .InnerJoin(DatabaseContext.SqlSyntax) - .On(DatabaseContext.SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(DatabaseContext.SqlSyntax, dto => dto.NodeObjectType == mediaObjectType); - var totalXml = ApplicationContext.DatabaseContext.Database.ExecuteScalar(subQuery); + var subQuery = DatabaseContext.Sql() + .SelectCount() + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == mediaObjectType); + var totalXml = DatabaseContext.Database.ExecuteScalar(subQuery); return totalXml == total; } @@ -69,13 +70,13 @@ namespace Umbraco.Web.WebServices { var total = Services.MemberService.Count(); var memberObjectType = Guid.Parse(Constants.ObjectTypes.Member); - var subQuery = new Sql() - .Select("Count(*)") - .From(DatabaseContext.SqlSyntax) - .InnerJoin(DatabaseContext.SqlSyntax) - .On(DatabaseContext.SqlSyntax, left => left.NodeId, right => right.NodeId) - .Where(DatabaseContext.SqlSyntax, dto => dto.NodeObjectType == memberObjectType); - var totalXml = ApplicationContext.DatabaseContext.Database.ExecuteScalar(subQuery); + var subQuery = DatabaseContext.Sql() + .SelectCount() + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == memberObjectType); + var totalXml = DatabaseContext.Database.ExecuteScalar(subQuery); return totalXml == total; } diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index abafc5dcc2..97242e1500 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -29,6 +29,7 @@ + diff --git a/src/UmbracoExamine/DataServices/PropertyAliasDto.cs b/src/UmbracoExamine/DataServices/PropertyAliasDto.cs index 84e63ccf5c..64c3c5b14c 100644 --- a/src/UmbracoExamine/DataServices/PropertyAliasDto.cs +++ b/src/UmbracoExamine/DataServices/PropertyAliasDto.cs @@ -1,7 +1,7 @@ namespace UmbracoExamine.DataServices { /// - /// A Dto object for returning property aliases from PetaPoco + /// A Dto object for returning property aliases from NPoco /// public class PropertyAliasDto { diff --git a/src/UmbracoExamine/UmbracoExamine.csproj b/src/UmbracoExamine/UmbracoExamine.csproj index 7f137d11d0..21721da6b6 100644 --- a/src/UmbracoExamine/UmbracoExamine.csproj +++ b/src/UmbracoExamine/UmbracoExamine.csproj @@ -95,12 +95,21 @@ ..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + + + ..\packages\NPoco.3.1.0-u005\lib\net45\NPoco.dll + True + 3.5 + diff --git a/src/UmbracoExamine/packages.config b/src/UmbracoExamine/packages.config index 722e13f2d5..3b7d941dd4 100644 --- a/src/UmbracoExamine/packages.config +++ b/src/UmbracoExamine/packages.config @@ -2,5 +2,7 @@ + + \ No newline at end of file diff --git a/src/umbraco.cms/packages.config b/src/umbraco.cms/packages.config index c00e2f0c3d..12c1341ac8 100644 --- a/src/umbraco.cms/packages.config +++ b/src/umbraco.cms/packages.config @@ -3,5 +3,6 @@ + \ No newline at end of file diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj index 492272eb1d..c261253c33 100644 --- a/src/umbraco.cms/umbraco.cms.csproj +++ b/src/umbraco.cms/umbraco.cms.csproj @@ -123,6 +123,10 @@ ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll True + + ..\packages\NPoco.3.1.0-u005\lib\net45\NPoco.dll + True + System @@ -134,6 +138,7 @@ System.Data + System.Security