Merge origin/dev-v7.6 into dev-v8-zbwip (builds, not tested)

This commit is contained in:
Stephan
2016-11-23 10:33:12 +01:00
171 changed files with 3049 additions and 2024 deletions
+1 -1
View File
@@ -144,5 +144,5 @@ build/docs.zip
build/ui-docs.zip
build/csharp-docs.zip
build/msbuild.log
.vs/
src/packages/
@@ -122,6 +122,11 @@ namespace Umbraco.Core
/// MediaType alias for an image.
/// </summary>
public const string Image = "Image";
/// <summary>
/// MediaType alias indicating allowing auto-selection.
/// </summary>
public const string AutoSelect = "umbracoAutoSelect";
}
/// <summary>
+11 -5
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using AutoMapper;
using LightInject;
@@ -71,11 +72,16 @@ namespace Umbraco.Core
// register a server registrar, by default it's the db registrar unless the dev
// has the legacy dist calls enabled - fixme - should obsolete the legacy thing
composition.Container.RegisterSingleton(factory => UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled
? (IServerRegistrar)new ConfigServerRegistrar(UmbracoConfig.For.UmbracoSettings())
: (IServerRegistrar)new DatabaseServerRegistrar(
new Lazy<IServerRegistrationService>(factory.GetInstance<IServerRegistrationService>),
new DatabaseServerRegistrarOptions()));
composition.Container.RegisterSingleton<IServerRegistrar>(f =>
{
if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled)
return new ConfigServerRegistrar(UmbracoConfig.For.UmbracoSettings());
if ("true".InvariantEquals(ConfigurationManager.AppSettings["umbracoDisableElectionForSingleServer"]))
return new SingleServerRegistrar(f.GetInstance<IRuntimeState>());
return new DatabaseServerRegistrar(
new Lazy<IServerRegistrationService>(f.GetInstance<IServerRegistrationService>),
new DatabaseServerRegistrarOptions());
});
// by default we'll use the database server messenger with default options (no callbacks),
// this will be overridden by either the legacy thing or the db thing in the corresponding
@@ -4,6 +4,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.IO;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Plugins;
@@ -26,6 +27,9 @@ namespace Umbraco.Core.DI
container.RegisterSingleton<IUnitOfWorkProvider, FileUnitOfWorkProvider>();
container.RegisterSingleton<IDatabaseUnitOfWorkProvider, NPocoUnitOfWorkProvider>();
// register query factory
container.RegisterSingleton<IQueryFactory, QueryFactory>();
// register repository factory
container.RegisterSingleton<RepositoryFactory>();
+1 -1
View File
@@ -326,7 +326,7 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// <summary>
/// A boolean flag indicating if a property type has been removed from this instance.
/// </summary>
/// <remarks>
+3 -3
View File
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Models
NoAccessNodeId = noAccessNode.Id;
_protectedNodeId = protectedNode.Id;
_ruleCollection = new ObservableCollection<PublicAccessRule>(ruleCollection);
_ruleCollection = new ObservableCollection<PublicAccessRule>(ruleCollection);
_ruleCollection.CollectionChanged += _ruleCollection_CollectionChanged;
}
@@ -81,7 +81,7 @@ namespace Umbraco.Core.Models
internal IEnumerable<Guid> RemovedRules
{
get { return _removedRules; }
}
}
public IEnumerable<PublicAccessRule> Rules
{
@@ -123,7 +123,7 @@ namespace Umbraco.Core.Models
get { return _noAccessNodeId; }
set { SetPropertyValueAndDetectChanges(value, ref _noAccessNodeId, Ps.Value.NoAccessNodeIdSelector); }
}
[DataMember]
public int ProtectedNodeId
{
@@ -12,5 +12,21 @@
/// <returns>The strongly-typed model representing the published content, or the published content
/// itself it the factory has no model for that content type.</returns>
IPublishedContent CreateModel(IPublishedContent content);
T CreateModel<T>(IPublishedFragment content);
// fixme
// and we'd need a
// PublishedContentModel = ContentModel : ContentWrapper
// PublishedFragmentModel = FragmentModel : FragmentWrapper
//
// ModelFactory.Meta.Model("thing").ClrType (find the our post?)
//
// then
// make a plan to get NestedContent in
// and an equivalent of Vorto with different syntax
//
// then
// VARIANTS ARCHITECTURE FFS!
}
}
@@ -6,5 +6,10 @@
{
return content;
}
public T CreateModel<T>(IPublishedFragment content)
{
throw new System.NotImplementedException();
}
}
}
@@ -81,5 +81,10 @@ namespace Umbraco.Core.Models.PublishedContent
? constructor(content)
: content;
}
public T CreateModel<T>(IPublishedFragment content)
{
throw new NotImplementedException();
}
}
}
@@ -12,7 +12,6 @@ namespace Umbraco.Core.Models.Rdbms
{
[Column("id")]
[PrimaryKeyColumn]
[Index(IndexTypes.NonClustered, Name = "IX_cmsPropertyData")]
public int Id { get; set; }
[Column("contentNodeId")]
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence
{
ValidateDatabase(database);
database.Execute("UPDATE umbracoNode SET sortOrder = (CASE WHEN (sortOrder=1) THEN -1 ELSE 1 END) WHERE id=@id",
database.Execute("UPDATE umbracoLock SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id=@id",
new { @id = nodeId });
}
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Persistence
{
ValidateDatabase(database);
database.ExecuteScalar<int>("SELECT sortOrder FROM umbracoNode WHERE id=@id",
database.ExecuteScalar<int>("SELECT value FROM umbracoLock WHERE id=@id",
new { @id = nodeId });
}
}
@@ -28,7 +28,6 @@ namespace Umbraco.Core.Persistence
/// </remarks>
internal class DefaultDatabaseFactory : DisposableObject, IDatabaseFactory
{
private readonly IMapperCollection _mappers;
private readonly IUmbracoDatabaseAccessor _umbracoDatabaseAccessor;
private readonly ISqlSyntaxProvider[] _sqlSyntaxProviders;
private readonly ILogger _logger;
@@ -42,7 +41,6 @@ namespace Umbraco.Core.Persistence
private ISqlSyntaxProvider _sqlSyntax;
private RetryPolicy _connectionRetryPolicy;
private RetryPolicy _commandRetryPolicy;
private IQueryFactory _queryFactory;
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
/// <summary>
@@ -51,10 +49,10 @@ namespace Umbraco.Core.Persistence
/// <param name="sqlSyntaxProviders">The collection of available sql syntax providers.</param>
/// <param name="logger">A logger.</param>
/// <param name="umbracoDatabaseAccessor"></param>
/// <param name="mappers"></param>
/// <param name="queryFactory"></param>
/// <remarks>Used by LightInject.</remarks>
public DefaultDatabaseFactory(IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IMapperCollection mappers)
: this(GlobalSettings.UmbracoConnectionName, sqlSyntaxProviders, logger, umbracoDatabaseAccessor, mappers)
public DefaultDatabaseFactory(IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IQueryFactory queryFactory)
: this(GlobalSettings.UmbracoConnectionName, sqlSyntaxProviders, logger, umbracoDatabaseAccessor, queryFactory)
{
if (Configured == false)
DatabaseContext.GiveLegacyAChance(this, logger);
@@ -67,17 +65,17 @@ namespace Umbraco.Core.Persistence
/// <param name="sqlSyntaxProviders">The collection of available sql syntax providers.</param>
/// <param name="logger">A logger</param>
/// <param name="umbracoDatabaseAccessor"></param>
/// <param name="mappers"></param>
/// <param name="queryFactory"></param>
/// <remarks>Used by the other ctor and in tests.</remarks>
public DefaultDatabaseFactory(string connectionStringName, IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IMapperCollection mappers)
public DefaultDatabaseFactory(string connectionStringName, IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IQueryFactory queryFactory)
{
if (sqlSyntaxProviders == null) throw new ArgumentNullException(nameof(sqlSyntaxProviders));
if (logger == null) throw new ArgumentNullException(nameof(logger));
if (umbracoDatabaseAccessor == null) throw new ArgumentNullException(nameof(umbracoDatabaseAccessor));
if (string.IsNullOrWhiteSpace(connectionStringName)) throw new ArgumentNullOrEmptyException(nameof(connectionStringName));
if (mappers == null) throw new ArgumentNullException(nameof(mappers));
if (queryFactory == null) throw new ArgumentNullException(nameof(queryFactory));
_mappers = mappers;
QueryFactory = queryFactory;
_sqlSyntaxProviders = sqlSyntaxProviders.ToArray();
_logger = logger;
_umbracoDatabaseAccessor = umbracoDatabaseAccessor;
@@ -107,16 +105,16 @@ namespace Umbraco.Core.Persistence
/// <param name="sqlSyntaxProviders">The collection of available sql syntax providers.</param>
/// <param name="logger">A logger.</param>
/// <param name="umbracoDatabaseAccessor"></param>
/// <param name="mappers"></param>
/// <param name="queryFactory"></param>
/// <remarks>Used in tests.</remarks>
public DefaultDatabaseFactory(string connectionString, string providerName, IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IMapperCollection mappers)
public DefaultDatabaseFactory(string connectionString, string providerName, IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IUmbracoDatabaseAccessor umbracoDatabaseAccessor, IQueryFactory queryFactory)
{
if (sqlSyntaxProviders == null) throw new ArgumentNullException(nameof(sqlSyntaxProviders));
if (logger == null) throw new ArgumentNullException(nameof(logger));
if (umbracoDatabaseAccessor == null) throw new ArgumentNullException(nameof(umbracoDatabaseAccessor));
if (mappers == null) throw new ArgumentNullException(nameof(mappers));
if (queryFactory == null) throw new ArgumentNullException(nameof(queryFactory));
_mappers = mappers;
QueryFactory = queryFactory;
_sqlSyntaxProviders = sqlSyntaxProviders.ToArray();
_logger = logger;
_umbracoDatabaseAccessor = umbracoDatabaseAccessor;
@@ -156,14 +154,7 @@ namespace Umbraco.Core.Persistence
/// <summary>
/// Gets the database query factory.
/// </summary>
public IQueryFactory QueryFactory
{
get
{
EnsureConfigured();
return _queryFactory ?? (_queryFactory = new QueryFactory(SqlSyntax, _mappers));
}
}
public IQueryFactory QueryFactory { get; }
// will be configured by the database context
public void Configure(string connectionString, string providerName)
@@ -39,6 +39,11 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
CreateUmbracoLockData();
}
if (tableName.Equals("umbracoLock"))
{
CreateUmbracoLockData();
}
if (tableName.Equals("cmsContentType"))
{
CreateCmsContentTypeData();
@@ -165,8 +170,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
private void CreateCmsContentTypeData()
{
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true });
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture" });
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document" });
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true });
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true });
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user" });
}
@@ -0,0 +1,37 @@
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Rdbms;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive
{
[Migration("7.5.5", 101, GlobalSettings.UmbracoMigrationName)]
public class AddLockObjects : MigrationBase
{
public AddLockObjects(IMigrationContext context)
: base(context)
{ }
public override void Up()
{
EnsureLockObject(Constants.Locks.Servers, "Servers");
}
public override void Down()
{
// not implemented
}
private void EnsureLockObject(int id, string name)
{
Execute.Code(db =>
{
var exists = db.Exists<LockDto>(id);
if (exists) return string.Empty;
// be safe: delete old umbracoNode lock objects if any
db.Execute("DELETE FROM umbracoNode WHERE id=@id;", new { id });
// then create umbracoLock object
db.Execute("INSERT umbracoLock (id, name, value) VALUES (@id, @name, 1);", new { id, name });
return string.Empty;
});
}
}
}
@@ -0,0 +1,30 @@
using System.Linq;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive
{
[Migration("7.5.5", 100, GlobalSettings.UmbracoMigrationName)]
public class AddLockTable : MigrationBase
{
public AddLockTable(IMigrationContext context)
: base(context)
{ }
public override void Up()
{
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
if (tables.InvariantContains("umbracoLock") == false)
{
Create.Table("umbracoLock")
.WithColumn("id").AsInt32().PrimaryKey("PK_umbracoLock")
.WithColumn("value").AsInt32().NotNullable()
.WithColumn("name").AsString(64).NotNullable();
}
}
public override void Down()
{
// not implemented
}
}
}
@@ -0,0 +1,25 @@
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive
{
/// <summary>
/// See: http://issues.umbraco.org/issue/U4-4196
/// </summary>
[Migration("7.5.5", 1, GlobalSettings.UmbracoMigrationName)]
public class UpdateAllowedMediaTypesAtRoot : MigrationBase
{
public UpdateAllowedMediaTypesAtRoot(IMigrationContext context)
: base(context)
{ }
public override void Up()
{
Execute.Sql("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1032 OR nodeId = 1033");
}
public override void Down()
{ }
}
}
@@ -0,0 +1,38 @@
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
{
/// <summary>
/// See: http://issues.umbraco.org/issue/U4-9188
/// </summary>
[Migration("7.6.0", 0, GlobalSettings.UmbracoMigrationName)]
public class UpdateUniqueIndexOnCmsPropertyData : MigrationBase
{
public UpdateUniqueIndexOnCmsPropertyData(IMigrationContext context)
: base(context)
{
}
public override void Up()
{
//tuple = tablename, indexname, columnname, unique
var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
var found = indexes.FirstOrDefault(
x => x.Item1.InvariantEquals("cmsPropertyData")
&& x.Item2.InvariantEquals("IX_cmsPropertyData"));
if (found != null)
{
//drop the index
Delete.Index("IX_cmsPropertyData").OnTable("cmsPropertyData");
}
}
public override void Down()
{
}
}
}
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence
public static Sql<SqlContext> Where<T>(this Sql<SqlContext> sql, Expression<Func<T, bool>> predicate)
{
var expresionist = new PocoToSqlExpressionHelper<T>(sql.SqlContext);
var expresionist = new PocoToSqlExpressionVisitor<T>(sql.SqlContext);
var whereExpression = expresionist.Visit(predicate);
sql.Where(whereExpression, expresionist.GetSqlParameters());
return sql;
@@ -2,7 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
@@ -13,27 +12,117 @@ namespace Umbraco.Core.Persistence.Querying
{
// fixme.npoco - are we basically duplicating entire parts of NPoco just because of SqlSyntax ?!
internal abstract class BaseExpressionHelper<T> : BaseExpressionHelper
/// <summary>
/// Represents an expression which caches the visitor's result.
/// </summary>
internal class CachedExpression : Expression
{
protected BaseExpressionHelper(ISqlSyntaxProvider sqlSyntax)
: base(sqlSyntax)
private string _visitResult;
/// <summary>
/// Gets or sets the inner Expression.
/// </summary>
public Expression InnerExpression { get; private set; }
/// <summary>
/// Gets or sets the compiled SQL statement output.
/// </summary>
public string VisitResult
{
get { return _visitResult; }
set
{
if (Visited)
throw new InvalidOperationException("Cached expression has already been visited.");
_visitResult = value;
Visited = true;
}
}
protected abstract string VisitMemberAccess(MemberExpression m);
/// <summary>
/// Gets or sets a value indicating whether the cache Expression has been compiled already.
/// </summary>
public bool Visited { get; private set; }
protected internal virtual string Visit(Expression exp)
/// <summary>
/// Replaces the inner expression.
/// </summary>
/// <param name="expression">expression.</param>
/// <remarks>The new expression is assumed to have different parameter but produce the same SQL statement.</remarks>
public void Wrap(Expression expression)
{
InnerExpression = expression;
}
}
if (exp == null) return string.Empty;
switch (exp.NodeType)
/// <summary>
/// An expression tree parser to create SQL statements and SQL parameters based on a strongly typed expression.
/// </summary>
/// <remarks>This object is stateful and cannot be re-used to parse an expression.</remarks>
internal abstract class ExpressionVisitorBase
{
protected ExpressionVisitorBase(ISqlSyntaxProvider sqlSyntax)
{
SqlSyntax = sqlSyntax;
}
/// <summary>
/// Gets or sets a value indicating whether the visited expression has been visited already,
/// in which case visiting will just populate the SQL parameters.
/// </summary>
protected bool Visited { get; set; }
/// <summary>
/// Gets or sets the SQL syntax provider for the current database.
/// </summary>
protected ISqlSyntaxProvider SqlSyntax { get; private set; }
/// <summary>
/// Gets the list of SQL parameters.
/// </summary>
protected readonly List<object> SqlParameters = new List<object>();
/// <summary>
/// Gets the SQL parameters.
/// </summary>
/// <returns></returns>
public object[] GetSqlParameters()
{
return SqlParameters.ToArray();
}
/// <summary>
/// Visits the expression and produces the corresponding SQL statement.
/// </summary>
/// <param name="expression">The expression</param>
/// <returns>The SQL statement corresponding to the expression.</returns>
/// <remarks>Also populates the SQL parameters.</remarks>
public virtual string Visit(Expression expression)
{
// if the expression is a CachedExpression,
// visit the inner expression if not already visited
var cachedExpression = expression as CachedExpression;
if (cachedExpression != null)
{
Visited = cachedExpression.Visited;
expression = cachedExpression.InnerExpression;
}
if (expression == null) return string.Empty;
string result;
switch (expression.NodeType)
{
case ExpressionType.Lambda:
return VisitLambda(exp as LambdaExpression);
result = VisitLambda(expression as LambdaExpression);
break;
case ExpressionType.MemberAccess:
return VisitMemberAccess(exp as MemberExpression);
result = VisitMemberAccess(expression as MemberExpression);
break;
case ExpressionType.Constant:
return VisitConstant(exp as ConstantExpression);
result = VisitConstant(expression as ConstantExpression);
break;
case ExpressionType.Add:
case ExpressionType.AddChecked:
case ExpressionType.Subtract:
@@ -57,7 +146,8 @@ namespace Umbraco.Core.Persistence.Querying
case ExpressionType.RightShift:
case ExpressionType.LeftShift:
case ExpressionType.ExclusiveOr:
return VisitBinary(exp as BinaryExpression);
result = VisitBinary(expression as BinaryExpression);
break;
case ExpressionType.Negate:
case ExpressionType.NegateChecked:
case ExpressionType.Not:
@@ -66,35 +156,54 @@ namespace Umbraco.Core.Persistence.Querying
case ExpressionType.ArrayLength:
case ExpressionType.Quote:
case ExpressionType.TypeAs:
return VisitUnary(exp as UnaryExpression);
result = VisitUnary(expression as UnaryExpression);
break;
case ExpressionType.Parameter:
return VisitParameter(exp as ParameterExpression);
result = VisitParameter(expression as ParameterExpression);
break;
case ExpressionType.Call:
return VisitMethodCall(exp as MethodCallExpression);
result = VisitMethodCall(expression as MethodCallExpression);
break;
case ExpressionType.New:
return VisitNew(exp as NewExpression);
result = VisitNew(expression as NewExpression);
break;
case ExpressionType.NewArrayInit:
case ExpressionType.NewArrayBounds:
return VisitNewArray(exp as NewArrayExpression);
result = VisitNewArray(expression as NewArrayExpression);
break;
default:
return exp.ToString();
result = expression.ToString();
break;
}
// if the expression is a CachedExpression,
// and is not already compiled, assign the result
if (cachedExpression != null)
{
if (cachedExpression.Visited == false)
cachedExpression.VisitResult = result;
result = cachedExpression.VisitResult;
}
return result;
}
protected abstract string VisitMemberAccess(MemberExpression m);
protected virtual string VisitLambda(LambdaExpression lambda)
{
if (lambda.Body.NodeType == ExpressionType.MemberAccess)
{
var m = lambda.Body as MemberExpression;
if (m.Expression != null)
if (m != null && m.Expression != null)
{
//This deals with members that are boolean (i.e. x => IsTrashed )
string r = VisitMemberAccess(m);
SqlParameters.Add(true);
return string.Format("{0} = @{1}", r, SqlParameters.Count - 1);
var r = VisitMemberAccess(m);
//return string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(true);
return Visited ? string.Empty : string.Format("{0} = @{1}", r, SqlParameters.Count - 1);
}
}
@@ -103,19 +212,24 @@ namespace Umbraco.Core.Persistence.Querying
protected virtual string VisitBinary(BinaryExpression b)
{
string left, right;
var left = string.Empty;
var right = string.Empty;
var operand = BindOperant(b.NodeType);
if (operand == "AND" || operand == "OR")
{
MemberExpression m = b.Left as MemberExpression;
var m = b.Left as MemberExpression;
if (m != null && m.Expression != null)
{
string r = VisitMemberAccess(m);
SqlParameters.Add(1);
left = string.Format("{0} = @{1}", r, SqlParameters.Count - 1);
//left = string.Format("{0}={1}", r, GetQuotedTrueValue());
//don't execute if compiled
if (Visited == false)
{
left = string.Format("{0} = @{1}", r, SqlParameters.Count - 1);
}
}
else
{
@@ -124,12 +238,15 @@ namespace Umbraco.Core.Persistence.Querying
m = b.Right as MemberExpression;
if (m != null && m.Expression != null)
{
string r = VisitMemberAccess(m);
var r = VisitMemberAccess(m);
SqlParameters.Add(1);
right = string.Format("{0} = @{1}", r, SqlParameters.Count - 1);
//right = string.Format("{0}={1}", r, GetQuotedTrueValue());
//don't execute if compiled
if (Visited == false)
{
right = string.Format("{0} = @{1}", r, SqlParameters.Count - 1);
}
}
else
{
@@ -140,14 +257,14 @@ 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))
return ((bool) constRight.Value) ? VisitNotNot(b.Left) : VisitNot(b.Left);
if (constRight != null && constRight.Type == typeof(bool))
return (bool)constRight.Value ? VisitNotNot(b.Left) : VisitNot(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))
return ((bool) constLeft.Value) ? VisitNotNot(b.Right) : VisitNot(b.Right);
if (constLeft != null && constLeft.Type == typeof(bool))
return (bool)constLeft.Value ? VisitNotNot(b.Right) : VisitNot(b.Right);
left = Visit(b.Left);
}
else if (operand == "<>")
@@ -155,13 +272,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))
return ((bool) constRight.Value) ? VisitNot(b.Left) : VisitNotNot(b.Left);
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))
return ((bool) constLeft.Value) ? VisitNot(b.Right) : VisitNotNot(b.Right);
return (bool)constLeft.Value ? VisitNot(b.Right) : VisitNotNot(b.Right);
left = Visit(b.Left);
}
else
@@ -186,26 +303,38 @@ namespace Umbraco.Core.Persistence.Querying
{
case "MOD":
case "COALESCE":
return string.Format("{0}({1},{2})", operand, left, right);
//don't execute if compiled
if (Visited == false)
{
return string.Format("{0}({1},{2})", operand, left, right);
}
//already compiled, return
return string.Empty;
default:
return "(" + left + " " + operand + " " + right + ")";
//don't execute if compiled
if (Visited == false)
{
return string.Concat("(", left, " ", operand, " ", right, ")");
}
//already compiled, return
return string.Empty;
}
}
protected virtual List<Object> VisitExpressionList(ReadOnlyCollection<Expression> original)
protected virtual List<object> VisitExpressionList(ReadOnlyCollection<Expression> original)
{
var list = new List<Object>();
var list = new List<object>();
for (int i = 0, n = original.Count; i < n; i++)
{
if (original[i].NodeType == ExpressionType.NewArrayInit ||
original[i].NodeType == ExpressionType.NewArrayBounds)
original[i].NodeType == ExpressionType.NewArrayBounds)
{
list.AddRange(VisitNewArrayFromExpressionList(original[i] as NewArrayExpression));
}
else
{
list.Add(Visit(original[i]));
}
}
return list;
}
@@ -218,27 +347,37 @@ namespace Umbraco.Core.Persistence.Querying
try
{
var getter = lambda.Compile();
object o = getter();
var o = getter();
SqlParameters.Add(o);
return string.Format("@{0}", SqlParameters.Count - 1);
//return GetQuotedValue(o, o.GetType());
//don't execute if compiled
if (Visited == false)
{
return string.Format("@{0}", SqlParameters.Count - 1);
}
//already compiled, return
return string.Empty;
}
catch (InvalidOperationException)
{
// FieldName ?
List<Object> exprs = VisitExpressionList(nex.Arguments);
var r = new StringBuilder();
foreach (Object e in exprs)
//don't execute if compiled
if (Visited == false)
{
r.AppendFormat("{0}{1}",
r.Length > 0 ? "," : "",
e);
// FieldName ?
List<object> exprs = VisitExpressionList(nex.Arguments);
var r = new StringBuilder();
foreach (var e in exprs)
{
r.AppendFormat("{0}{1}",
r.Length > 0 ? "," : "",
e);
}
return r.ToString();
}
return r.ToString();
//already compiled, return
return string.Empty;
}
}
protected virtual string VisitParameter(ParameterExpression p)
@@ -252,14 +391,14 @@ namespace Umbraco.Core.Persistence.Querying
return "null";
SqlParameters.Add(c.Value);
return string.Format("@{0}", SqlParameters.Count - 1);
//if (c.Value is bool)
//{
// object o = GetQuotedValue(c.Value, c.Value.GetType());
// return string.Format("({0}={1})", GetQuotedTrueValue(), o);
//}
//return GetQuotedValue(c.Value, c.Value.GetType());
//don't execute if compiled
if (Visited == false)
{
return string.Format("@{0}", SqlParameters.Count - 1);
}
//already compiled, return
return string.Empty;
}
protected virtual string VisitUnary(UnaryExpression u)
@@ -285,10 +424,22 @@ namespace Umbraco.Core.Persistence.Querying
case ExpressionType.MemberAccess:
// false property , i.e. x => !Trashed
SqlParameters.Add(true);
return string.Format("NOT ({0} = @{1})", o, SqlParameters.Count - 1);
//don't execute if compiled
if (Visited == false)
{
return string.Format("NOT ({0} = @{1})", o, SqlParameters.Count - 1);
}
//already compiled, return
return string.Empty;
default:
// could be anything else, such as: x => !x.Path.StartsWith("-20")
return "NOT (" + o + ")";
//don't execute if compiled
if (Visited == false)
{
// could be anything else, such as: x => !x.Path.StartsWith("-20")
return string.Concat("NOT (", o, ")");
}
//already compiled, return
return string.Empty;
}
}
@@ -301,7 +452,14 @@ namespace Umbraco.Core.Persistence.Querying
case ExpressionType.MemberAccess:
// true property, i.e. x => Trashed
SqlParameters.Add(true);
return string.Format("({0} = @{1})", o, SqlParameters.Count - 1);
//don't execute if compiled
if (Visited == false)
{
return string.Format("({0} = @{1})", o, SqlParameters.Count - 1);
}
//already compiled, return
return string.Empty;
default:
// could be anything else, such as: x => x.Path.StartsWith("-20")
return o;
@@ -310,27 +468,31 @@ namespace Umbraco.Core.Persistence.Querying
protected virtual string VisitNewArray(NewArrayExpression na)
{
var exprs = VisitExpressionList(na.Expressions);
List<Object> exprs = VisitExpressionList(na.Expressions);
var r = new StringBuilder();
foreach (Object e in exprs)
//don't execute if compiled
if (Visited == false)
{
r.Append(r.Length > 0 ? "," + e : e);
}
var r = new StringBuilder();
foreach (var e in exprs)
{
r.Append(r.Length > 0 ? "," + e : e);
}
return r.ToString();
return r.ToString();
}
//already compiled, return
return string.Empty;
}
protected virtual List<Object> VisitNewArrayFromExpressionList(NewArrayExpression na)
protected virtual List<object> VisitNewArrayFromExpressionList(NewArrayExpression na)
{
List<Object> exprs = VisitExpressionList(na.Expressions);
var exprs = VisitExpressionList(na.Expressions);
return exprs;
}
protected virtual string BindOperant(ExpressionType e)
{
switch (e)
{
case ExpressionType.Equal:
@@ -369,16 +531,16 @@ namespace Umbraco.Core.Persistence.Querying
protected virtual string VisitMethodCall(MethodCallExpression m)
{
//Here's what happens with a MethodCallExpression:
// If a method is called that contains a single argument,
// If a method is called that contains a single argument,
// then m.Object is the object on the left hand side of the method call, example:
// x.Path.StartsWith(content.Path)
// m.Object = x.Path
// and m.Arguments.Length == 1, therefor m.Arguments[0] == content.Path
// If a method is called that contains multiple arguments, then m.Object == null and the
// If a method is called that contains multiple arguments, then m.Object == null and the
// m.Arguments collection contains the left hand side of the method call, example:
// x.Path.SqlStartsWith(content.Path, TextColumnType.NVarchar)
// m.Object == null
// m.Arguments.Length == 3, therefor, m.Arguments[0] == x.Path, m.Arguments[1] == content.Path, m.Arguments[2] == TextColumnType.NVarchar
// m.Arguments.Length == 3, therefor, m.Arguments[0] == x.Path, m.Arguments[1] == content.Path, m.Arguments[2] == TextColumnType.NVarchar
// So, we need to cater for these scenarios.
var objectForMethod = m.Object ?? m.Arguments[0];
@@ -391,11 +553,23 @@ namespace Umbraco.Core.Persistence.Querying
{
case "ToString":
SqlParameters.Add(objectForMethod.ToString());
return string.Format("@{0}", SqlParameters.Count - 1);
//don't execute if compiled
if (Visited == false)
return string.Format("@{0}", SqlParameters.Count - 1);
//already compiled, return
return string.Empty;
case "ToUpper":
return string.Format("upper({0})", visitedObjectForMethod);
//don't execute if compiled
if (Visited == false)
return string.Format("upper({0})", visitedObjectForMethod);
//already compiled, return
return string.Empty;
case "ToLower":
return string.Format("lower({0})", visitedObjectForMethod);
//don't execute if compiled
if (Visited == false)
return string.Format("lower({0})", visitedObjectForMethod);
//already compiled, return
return string.Empty;
case "SqlWildcard":
case "StartsWith":
case "EndsWith":
@@ -496,7 +670,12 @@ namespace Umbraco.Core.Persistence.Querying
SqlParameters.Add(RemoveQuote(replaceValue));
return string.Format("replace({0}, @{1}, @{2})", visitedObjectForMethod, SqlParameters.Count - 2, SqlParameters.Count - 1);
//don't execute if compiled
if (Visited == false)
return string.Format("replace({0}, @{1}, @{2})", visitedObjectForMethod, SqlParameters.Count - 2, SqlParameters.Count - 1);
//already compiled, return
return string.Empty;
//case "Substring":
// var startIndex = Int32.Parse(args[0].ToString()) + 1;
// if (args.Count == 2)
@@ -563,87 +742,28 @@ namespace Umbraco.Core.Persistence.Querying
throw new ArgumentOutOfRangeException("No logic supported for " + m.Method.Name);
//var s2 = new StringBuilder();
//foreach (Object e in args)
//{
// s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType()));
//}
//return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString());
//var s2 = new StringBuilder();
//foreach (Object e in args)
//{
// s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType()));
//}
//return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString());
}
}
public virtual string GetQuotedTableName(string tableName)
{
return string.Format("\"{0}\"", tableName);
return Visited ? tableName : string.Format("\"{0}\"", tableName);
}
public virtual string GetQuotedColumnName(string columnName)
{
return string.Format("\"{0}\"", columnName);
return Visited ? columnName : string.Format("\"{0}\"", columnName);
}
public virtual string GetQuotedName(string name)
{
return string.Format("\"{0}\"", name);
}
//private string GetQuotedTrueValue()
//{
// return GetQuotedValue(true, typeof(bool));
//}
//private string GetQuotedFalseValue()
//{
// return GetQuotedValue(false, typeof(bool));
//}
//public virtual string GetQuotedValue(object value, Type fieldType)
//{
// return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
//}
//private string GetTrueExpression()
//{
// object o = GetQuotedTrueValue();
// return string.Format("({0}={1})", o, o);
//}
//private string GetFalseExpression()
//{
// return string.Format("({0}={1})",
// GetQuotedTrueValue(),
// GetQuotedFalseValue());
//}
//private bool IsTrueExpression(string exp)
//{
// return (exp == GetTrueExpression());
//}
//private bool IsFalseExpression(string exp)
//{
// return (exp == GetFalseExpression());
//}
}
/// <summary>
/// Logic that is shared with the expression helpers
/// </summary>
internal abstract class BaseExpressionHelper
{
public ISqlSyntaxProvider SqlSyntax { get; private set; }
protected BaseExpressionHelper(ISqlSyntaxProvider sqlSyntax)
{
SqlSyntax = sqlSyntax;
}
protected List<object> SqlParameters = new List<object>();
public object[] GetSqlParameters()
{
return SqlParameters.ToArray();
return Visited ? name : string.Format("\"{0}\"", name);
}
protected string HandleStringComparison(string col, string val, string verb, TextColumnType columnType)
@@ -652,25 +772,45 @@ namespace Umbraco.Core.Persistence.Querying
{
case "SqlWildcard":
SqlParameters.Add(RemoveQuote(val));
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//don't execute if compiled
if (Visited == false)
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//already compiled, return
return string.Empty;
case "Equals":
SqlParameters.Add(RemoveQuote(val));
return SqlSyntax.GetStringColumnEqualComparison(col, SqlParameters.Count - 1, columnType);
//don't execute if compiled
if (Visited == false)
return SqlSyntax.GetStringColumnEqualComparison(col, SqlParameters.Count - 1, columnType);
//already compiled, return
return string.Empty;
case "StartsWith":
SqlParameters.Add(string.Format("{0}{1}",
RemoveQuote(val),
SqlSyntax.GetWildcardPlaceholder()));
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//don't execute if compiled
if (Visited == false)
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//already compiled, return
return string.Empty;
case "EndsWith":
SqlParameters.Add(string.Format("{0}{1}",
SqlSyntax.GetWildcardPlaceholder(),
RemoveQuote(val)));
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//don't execute if compiled
if (Visited == false)
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//already compiled, return
return string.Empty;
case "Contains":
SqlParameters.Add(string.Format("{0}{1}{0}",
SqlSyntax.GetWildcardPlaceholder(),
RemoveQuote(val)));
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//don't execute if compiled
if (Visited == false)
return SqlSyntax.GetStringColumnWildcardComparison(col, SqlParameters.Count - 1, columnType);
//already compiled, return
return string.Empty;
case "InvariantEquals":
case "SqlEquals":
//recurse
@@ -755,16 +895,9 @@ namespace Umbraco.Core.Persistence.Querying
protected virtual string RemoveQuote(string exp)
{
//if (exp.StartsWith("'") && exp.EndsWith("'"))
//{
// exp = exp.Remove(0, 1);
// exp = exp.Remove(exp.Length - 1, 1);
//}
//return exp;
if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'"))
&&
(exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'")))
&&
(exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'")))
{
exp = exp.Remove(0, 1);
exp = exp.Remove(exp.Length - 1, 1);
@@ -772,17 +905,17 @@ namespace Umbraco.Core.Persistence.Querying
return exp;
}
//protected virtual string RemoveQuoteFromAlias(string exp)
//protected virtual string RemoveQuoteFromAlias(string expression)
//{
// if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'"))
// if ((expression.StartsWith("\"") || expression.StartsWith("`") || expression.StartsWith("'"))
// &&
// (exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'")))
// (expression.EndsWith("\"") || expression.EndsWith("`") || expression.EndsWith("'")))
// {
// exp = exp.Remove(0, 1);
// exp = exp.Remove(exp.Length - 1, 1);
// expression = expression.Remove(0, 1);
// expression = expression.Remove(expression.Length - 1, 1);
// }
// return exp;
// return expression;
//}
}
}
@@ -5,7 +5,6 @@ using System.Linq.Expressions;
namespace Umbraco.Core.Persistence.Querying
{
/// <summary>
/// Represents a query for building Linq translatable SQL queries
/// </summary>
@@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Querying
{
internal class ModelToSqlExpressionHelper<T> : BaseExpressionHelper<T>
{
private readonly BaseMapper _mapper;
public ModelToSqlExpressionHelper(ISqlSyntaxProvider sqlSyntax, BaseMapper mapper)
: base(sqlSyntax)
{
if (mapper == null) throw new ArgumentNullException("mapper");
_mapper = mapper;
}
public ModelToSqlExpressionHelper(ISqlSyntaxProvider sqlSyntax, IMapperCollection mappers)
: base(sqlSyntax)
{
_mapper = mappers[typeof(T)]; // throws if not found
}
protected override string VisitMemberAccess(MemberExpression m)
{
if (m.Expression != null &&
m.Expression.NodeType == ExpressionType.Parameter
&& m.Expression.Type == typeof(T))
{
var field = _mapper.Map(SqlSyntax, m.Member.Name, true);
if (field.IsNullOrWhiteSpace())
throw new InvalidOperationException("The mapper returned an empty field for the member name: " + m.Member.Name);
return field;
}
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
{
var field = _mapper.Map(SqlSyntax, m.Member.Name, true);
if (field.IsNullOrWhiteSpace())
throw new InvalidOperationException("The mapper returned an empty field for the member name: " + m.Member.Name);
return field;
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
object o = getter();
SqlParameters.Add(o);
return string.Format("@{0}", SqlParameters.Count - 1);
//return GetQuotedValue(o, o != null ? o.GetType() : null);
}
//protected bool IsFieldName(string quotedExp)
//{
// //Not entirely sure this is reliable, but its better then simply returning true
// return quotedExp.LastIndexOf("'", StringComparison.InvariantCultureIgnoreCase) + 1 != quotedExp.Length;
//}
}
}
@@ -0,0 +1,80 @@
using System;
using System.Linq.Expressions;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Querying
{
/// <summary>
/// An expression tree parser to create SQL statements and SQL parameters based on a strongly typed expression,
/// based on Umbraco's business logic models.
/// </summary>
/// <remarks>This object is stateful and cannot be re-used to parse an expression.</remarks>
internal class ModelToSqlExpressionVisitor<T> : ExpressionVisitorBase
{
private readonly BaseMapper _mapper;
public ModelToSqlExpressionVisitor(ISqlSyntaxProvider sqlSyntax, BaseMapper mapper)
: base(sqlSyntax)
{
if (mapper == null) throw new ArgumentNullException(nameof(mapper));
_mapper = mapper;
}
public ModelToSqlExpressionVisitor(ISqlSyntaxProvider sqlSyntax, IMapperCollection mappers)
: base(sqlSyntax)
{
_mapper = mappers[typeof(T)]; // throws if not found
}
protected override string VisitMemberAccess(MemberExpression m)
{
if (m.Expression != null &&
m.Expression.NodeType == ExpressionType.Parameter
&& m.Expression.Type == typeof(T))
{
//don't execute if compiled
if (Visited == false)
{
var field = _mapper.Map(SqlSyntax, m.Member.Name, true);
if (field.IsNullOrWhiteSpace())
throw new InvalidOperationException("The mapper returned an empty field for the member name: " + m.Member.Name);
return field;
}
//already compiled, return
return string.Empty;
}
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
{
//don't execute if compiled
if (Visited == false)
{
var field = _mapper.Map(SqlSyntax, m.Member.Name, true);
if (field.IsNullOrWhiteSpace())
throw new InvalidOperationException("The mapper returned an empty field for the member name: " + m.Member.Name);
return field;
}
//already compiled, return
return string.Empty;
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
var o = getter();
SqlParameters.Add(o);
//don't execute if compiled
if (Visited == false)
return $"@{SqlParameters.Count - 1}";
//already compiled, return
return string.Empty;
}
}
}
@@ -1,51 +1,69 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using NPoco;
namespace Umbraco.Core.Persistence.Querying
{
internal class PocoToSqlExpressionHelper<T> : BaseExpressionHelper<T>
{
private readonly PocoData _pd;
public PocoToSqlExpressionHelper(SqlContext sqlContext)
: base(sqlContext.SqlSyntax)
{
_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))
{
var field = GetFieldName(_pd, m.Member.Name);
return field;
}
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
{
var field = GetFieldName(_pd, m.Member.Name);
return field;
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
var o = getter();
SqlParameters.Add(o);
return $"@{SqlParameters.Count - 1}";
}
protected virtual string GetFieldName(PocoData pocoData, string name)
{
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);
return $"{tableName}.{columnName}";
}
}
using System;
using System.Linq;
using System.Linq.Expressions;
using NPoco;
namespace Umbraco.Core.Persistence.Querying
{
/// <summary>
/// An expression tree parser to create SQL statements and SQL parameters based on a strongly typed expression,
/// based on Umbraco's DTOs.
/// </summary>
/// <remarks>This object is stateful and cannot be re-used to parse an expression.</remarks>
internal class PocoToSqlExpressionVisitor<T> : ExpressionVisitorBase
{
private readonly PocoData _pd;
public PocoToSqlExpressionVisitor(SqlContext sqlContext)
: base(sqlContext.SqlSyntax)
{
_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))
{
//don't execute if compiled
if (Visited == false)
return GetFieldName(_pd, m.Member.Name);
//already compiled, return
return string.Empty;
}
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
{
//don't execute if compiled
if (Visited == false)
return GetFieldName(_pd, m.Member.Name);
//already compiled, return
return string.Empty;
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
var o = getter();
SqlParameters.Add(o);
//don't execute if compiled
if (Visited == false)
return $"@{SqlParameters.Count - 1}";
//already compiled, return
return string.Empty;
}
protected virtual string GetFieldName(PocoData pocoData, string name)
{
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);
return $"{tableName}.{columnName}";
}
}
}
@@ -1,9 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -34,7 +32,8 @@ namespace Umbraco.Core.Persistence.Querying
{
if (predicate != null)
{
var expressionHelper = new ModelToSqlExpressionHelper<T>(_sqlSyntax, _mappers);
//TODO: This should have an SqlSyntax object passed in, this ctor is relying on a singleton
var expressionHelper = new ModelToSqlExpressionVisitor<T>(_sqlSyntax, _mappers);
string whereExpression = expressionHelper.Visit(predicate);
_wheres.Add(new Tuple<string, object[]>(whereExpression, expressionHelper.GetSqlParameters()));
@@ -46,7 +45,7 @@ namespace Umbraco.Core.Persistence.Querying
{
if (fieldSelector != null)
{
var expressionHelper = new ModelToSqlExpressionHelper<T>(_sqlSyntax, _mappers);
var expressionHelper = new ModelToSqlExpressionVisitor<T>(_sqlSyntax, _mappers);
string whereExpression = expressionHelper.Visit(fieldSelector);
_wheres.Add(new Tuple<string, object[]>(whereExpression + " IN (@values)", new object[] { new { @values = values } }));
@@ -62,6 +61,5 @@ namespace Umbraco.Core.Persistence.Querying
{
return _wheres;
}
}
}
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Persistence.Querying
{
/// <summary>
/// SD: This is a horrible hack but unless we break compatibility with anyone who's actually implemented IQuery{T} there's not much we can do.
/// The IQuery{T} interface is useless without having a GetWhereClauses method and cannot be used for tests.
/// We have to wait till v8 to make this change I suppose.
/// </summary>
internal static class QueryExtensions
{
/// <summary>
/// Returns all translated where clauses and their sql parameters
/// </summary>
/// <returns></returns>
public static IEnumerable<Tuple<string, object[]>> GetWhereClauses<T>(this IQuery<T> query)
{
var q = query as Query<T>;
if (q == null)
{
throw new NotSupportedException(typeof(IQuery<T>) + " cannot be cast to " + typeof(Query<T>));
}
return q.GetWhereClauses();
}
}
}
@@ -8,17 +8,15 @@ using Umbraco.Core.DI;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class AuditRepository : NPocoRepositoryBase<int, AuditItem>, IAuditRepository
{
public AuditRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public AuditRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -4,12 +4,12 @@ using System.Globalization;
using System.Linq;
using System.Xml;
using NPoco;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -32,8 +32,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly CacheHelper _cacheHelper;
private PermissionRepository<IContent> _permissionRepository;
public ContentRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection, IMapperCollection mappers)
: base(work, cacheHelper, logger, contentSection, mappers)
public ContentRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection, IQueryFactory queryFactory)
: base(work, cacheHelper, logger, contentSection, queryFactory)
{
if (contentTypeRepository == null) throw new ArgumentNullException(nameof(contentTypeRepository));
if (templateRepository == null) throw new ArgumentNullException(nameof(templateRepository));
@@ -43,6 +43,8 @@ namespace Umbraco.Core.Persistence.Repositories
_tagRepository = tagRepository;
_cacheHelper = cacheHelper;
_publishedQuery = queryFactory.Create<IContent>().Where(x => x.Published);
EnsureUniqueNaming = true;
}
@@ -109,6 +111,12 @@ namespace Umbraco.Core.Persistence.Repositories
#endregion
#region Static Queries
private readonly IQuery<IContent> _publishedQuery;
#endregion
#region Overrides of NPocoRepositoryBase<IContent>
protected override Sql<SqlContext> GetBaseQuery(bool isCount)
@@ -587,18 +595,7 @@ namespace Umbraco.Core.Persistence.Repositories
.OrderBy<NodeDto>(x => x.Level)
.OrderBy<NodeDto>(x => x.SortOrder);
//NOTE: This doesn't allow properties to be part of the query
var dtos = Database.Fetch<DocumentDto>(sql);
foreach (var dto in dtos)
{
// check cache first, if it exists and is published, use it
// it may exist and not be published as the cache has 'latest version used'
var fromCache = RuntimeCache.GetCacheItem<IContent>(GetCacheIdKey<IContent>(dto.NodeId));
yield return fromCache != null && fromCache.Published
? fromCache
: CreateContentFromDto(dto, dto.VersionId);
}
return MapQueryDtos(Database.Fetch<DocumentDto>(sql), true);
}
public int CountPublished(string contentTypeAlias = null)
@@ -700,7 +697,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
return GetPagedResultsByQuery<DocumentDto>(query, pageIndex, pageSize, out totalRecords,
MapQueryDtos,
x => MapQueryDtos(x),
orderBy, orderDirection, orderBySystemField, "cmsDocument",
filterSql);
}
@@ -762,80 +759,76 @@ WHERE (@path LIKE {5})",
return base.GetDatabaseFieldNameForOrderBy(orderBy);
}
private IEnumerable<IContent> MapQueryDtos(List<DocumentDto> dtos)
private IEnumerable<IContent> MapQueryDtos(List<DocumentDto> dtos, bool withCache = false)
{
//nothing found
if (dtos.Any() == false) return Enumerable.Empty<IContent>();
var content = new IContent[dtos.Count];
var defs = new List<DocumentDefinition>();
var templateIds = new List<int>();
//content types
//NOTE: This should be ok for an SQL 'IN' statement, there shouldn't be an insane amount of content types
var contentTypes = _contentTypeRepository.GetAll(dtos.Select(x => x.ContentVersionDto.ContentDto.ContentTypeId).ToArray())
.ToArray();
var ids = dtos
.Where(dto => dto.TemplateId.HasValue && dto.TemplateId.Value > 0)
.Select(x => x.TemplateId.Value).ToArray();
//NOTE: This should be ok for an SQL 'IN' statement, there shouldn't be an insane amount of content types
var templates = ids.Length == 0 ? Enumerable.Empty<ITemplate>() : _templateRepository.GetAll(ids).ToArray();
var dtosWithContentTypes = dtos
//This select into and null check are required because we don't have a foreign damn key on the contentType column
// http://issues.umbraco.org/issue/U4-5503
.Select(x => new { dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentVersionDto.ContentDto.ContentTypeId) })
.Where(x => x.contentType != null)
.ToArray();
//Go get the property data for each document
var docDefs = dtosWithContentTypes.Select(d => new DocumentDefinition(
d.dto.NodeId,
d.dto.VersionId,
d.dto.ContentVersionDto.VersionDate,
d.dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
d.contentType));
var propertyData = GetPropertyCollection(docDefs.ToArray());
return dtosWithContentTypes.Select(d => CreateContentFromDto(
d.dto,
contentTypes.First(ct => ct.Id == d.dto.ContentVersionDto.ContentDto.ContentTypeId),
templates.FirstOrDefault(tem => tem.Id == (d.dto.TemplateId ?? -1)),
propertyData[d.dto.NodeId]));
}
/// <summary>
/// Private method to create a content object from a DocumentDto, which is used by Get and GetByVersion.
/// </summary>
/// <param name="dto"></param>
/// <param name="contentType"></param>
/// <param name="template"></param>
/// <param name="propCollection"></param>
/// <returns></returns>
private IContent CreateContentFromDto(DocumentDto dto,
IContentType contentType,
ITemplate template,
PropertyCollection propCollection)
{
var factory = new ContentFactory(contentType, NodeObjectTypeId, dto.NodeId);
var content = factory.BuildEntity(dto);
//Check if template id is set on DocumentDto, and get ITemplate if it is.
if (dto.TemplateId.HasValue && dto.TemplateId.Value > 0)
for (var i = 0; i < dtos.Count; i++)
{
content.Template = template ?? _templateRepository.Get(dto.TemplateId.Value);
}
else
{
//ensure there isn't one set.
content.Template = null;
var dto = dtos[i];
// if the cache contains the published version, use it
if (withCache)
{
var cached = RuntimeCache.GetCacheItem<IContent>(GetCacheIdKey<IContent>(dto.NodeId));
if (cached != null && cached.Published)
{
content[i] = cached;
continue;
}
}
// else, need to fetch from the database
// content type repository is full-cache so OK to get each one independently
var contentType = _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId);
var factory = new ContentFactory(contentType, NodeObjectTypeId, dto.NodeId);
content[i] = factory.BuildEntity(dto);
// need template
if (dto.TemplateId.HasValue && dto.TemplateId.Value > 0)
templateIds.Add(dto.TemplateId.Value);
// need properties
defs.Add(new DocumentDefinition(
dto.NodeId,
dto.VersionId,
dto.ContentVersionDto.VersionDate,
dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
contentType
));
}
content.Properties = propCollection;
// load all required templates in 1 query
var templates = _templateRepository.GetAll(templateIds.ToArray())
.ToDictionary(x => x.Id, x => x);
// load all properties for all documents from database in 1 query
var propertyData = GetPropertyCollection(defs.ToArray());
// assign
var dtoIndex = 0;
foreach (var def in defs)
{
// move to corresponding item (which has to exist)
while (dtos[dtoIndex].NodeId != def.Id) dtoIndex++;
// complete the item
var cc = content[dtoIndex];
var dto = dtos[dtoIndex];
ITemplate template = null;
if (dto.TemplateId.HasValue)
templates.TryGetValue(dto.TemplateId.Value, out template); // else null
cc.Template = template;
cc.Properties = propertyData[cc.Id];
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity) cc).ResetDirtyProperties(false);
}
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity)content).ResetDirtyProperties(false);
return content;
}
@@ -22,8 +22,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ITemplateRepository _templateRepository;
private IRepositoryCachePolicy<IContentType, int> _cachePolicy;
public ContentTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ITemplateRepository templateRepository, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public ContentTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ITemplateRepository templateRepository, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
_templateRepository = templateRepository;
}
@@ -31,10 +31,9 @@ namespace Umbraco.Core.Persistence.Repositories
internal abstract class ContentTypeRepositoryBase<TEntity> : NPocoRepositoryBase<int, TEntity>, IReadRepository<Guid, TEntity>
where TEntity : class, IContentTypeComposition
{
protected ContentTypeRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
{
}
protected ContentTypeRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
public IEnumerable<MoveEventInfo<TEntity>> Move(TEntity moving, EntityContainer container)
{
@@ -31,12 +31,11 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly IContentTypeRepository _contentTypeRepository;
private readonly DataTypePreValueRepository _preValRepository;
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger,
IContentTypeRepository contentTypeRepository, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentTypeRepository contentTypeRepository, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
_contentTypeRepository = contentTypeRepository;
_preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, mappers);
_preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, queryFactory);
}
#region Overrides of RepositoryBase<int,DataTypeDefinition>
@@ -534,8 +533,8 @@ AND umbracoNode.id <> @id",
/// </summary>
private class DataTypePreValueRepository : NPocoRepositoryBase<int, PreValueEntity>
{
public DataTypePreValueRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public DataTypePreValueRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -21,13 +21,10 @@ namespace Umbraco.Core.Persistence.Repositories
internal class DictionaryRepository : NPocoRepositoryBase<int, IDictionaryItem>, IDictionaryRepository
{
private IRepositoryCachePolicy<IDictionaryItem, int> _cachePolicy;
private readonly IMapperCollection _mappers;
public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
{
_mappers = mappers;
}
public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy<IDictionaryItem, int> CachePolicy
{
@@ -243,13 +240,13 @@ namespace Umbraco.Core.Persistence.Repositories
public IDictionaryItem Get(Guid uniqueId)
{
var uniqueIdRepo = new DictionaryByUniqueIdRepository(this, UnitOfWork, RepositoryCache, Logger, _mappers);
var uniqueIdRepo = new DictionaryByUniqueIdRepository(this, UnitOfWork, RepositoryCache, Logger, QueryFactory);
return uniqueIdRepo.Get(uniqueId);
}
public IDictionaryItem Get(string key)
{
var keyRepo = new DictionaryByKeyRepository(this, UnitOfWork, RepositoryCache, Logger, _mappers);
var keyRepo = new DictionaryByKeyRepository(this, UnitOfWork, RepositoryCache, Logger, QueryFactory);
return keyRepo.Get(key);
}
@@ -297,8 +294,8 @@ namespace Umbraco.Core.Persistence.Repositories
private IRepositoryCachePolicy<IDictionaryItem, Guid> _cachePolicy;
private readonly DictionaryRepository _dictionaryRepository;
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
_dictionaryRepository = dictionaryRepository;
}
@@ -358,8 +355,8 @@ namespace Umbraco.Core.Persistence.Repositories
private IRepositoryCachePolicy<IDictionaryItem, string> _cachePolicy;
private readonly DictionaryRepository _dictionaryRepository;
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
_dictionaryRepository = dictionaryRepository;
}
@@ -6,12 +6,8 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.FaultHandling;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -22,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy<IDomain, int> _cachePolicy;
public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -22,8 +22,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly Guid _containerObjectType;
public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers, Guid containerObjectType)
: base(work, cache, logger, mappers)
public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory, Guid containerObjectType)
: base(work, cache, logger, queryFactory)
{
var allowedContainers = new[] {Constants.ObjectTypes.DocumentTypeContainerGuid, Constants.ObjectTypes.MediaTypeContainerGuid, Constants.ObjectTypes.DataTypeContainerGuid};
_containerObjectType = containerObjectType;
@@ -6,9 +6,7 @@ using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -21,12 +19,12 @@ namespace Umbraco.Core.Persistence.Repositories
/// </remarks>
internal class EntityRepository : DisposableObject, IEntityRepository
{
private readonly QueryFactory _queryFactory;
private readonly IQueryFactory _queryFactory;
public EntityRepository(IDatabaseUnitOfWork work, IMapperCollection mappers)
public EntityRepository(IDatabaseUnitOfWork work, IQueryFactory queryFactory)
{
UnitOfWork = work;
_queryFactory = new QueryFactory(work.Database.SqlSyntax, mappers);
_queryFactory = queryFactory;
}
/// <summary>
@@ -9,17 +9,15 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Identity;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class ExternalLoginRepository : NPocoRepositoryBase<int, IIdentityUserLogin>, IExternalLoginRepository
{
public ExternalLoginRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public ExternalLoginRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -1,14 +1,14 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
class DataTypeContainerRepository : EntityContainerRepository, IDataTypeContainerRepository
{
public DataTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(uow, cache, logger, mappers, Constants.ObjectTypes.DataTypeContainerGuid)
public DataTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(uow, cache, logger, queryFactory, Constants.ObjectTypes.DataTypeContainerGuid)
{ }
}
}
@@ -1,14 +1,15 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
class DocumentTypeContainerRepository : EntityContainerRepository, IDocumentTypeContainerRepository
{
public DocumentTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(uow, cache, logger, mappers, Constants.ObjectTypes.DocumentTypeContainerGuid)
public DocumentTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(uow, cache, logger, queryFactory, Constants.ObjectTypes.DocumentTypeContainerGuid)
{ }
}
}
@@ -1,14 +1,15 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
class MediaTypeContainerRepository : EntityContainerRepository, IMediaTypeContainerRepository
{
public MediaTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(uow, cache, logger, mappers, Constants.ObjectTypes.MediaTypeContainerGuid)
public MediaTypeContainerRepository(IDatabaseUnitOfWork uow, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(uow, cache, logger, queryFactory, Constants.ObjectTypes.MediaTypeContainerGuid)
{ }
}
}
@@ -9,9 +9,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -23,8 +21,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy<ILanguage, int> _cachePolicy;
public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -9,9 +9,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -19,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories
internal class MacroRepository : NPocoRepositoryBase<int, IMacro>, IMacroRepository
{
public MacroRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public MacroRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
@@ -11,12 +10,9 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -29,8 +25,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly IMediaTypeRepository _mediaTypeRepository;
private readonly ITagRepository _tagRepository;
public MediaRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection, IMapperCollection mappers)
: base(work, cache, logger, contentSection, mappers)
public MediaRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection, IQueryFactory queryFactory)
: base(work, cache, logger, contentSection, queryFactory)
{
if (mediaTypeRepository == null) throw new ArgumentNullException(nameof(mediaTypeRepository));
if (tagRepository == null) throw new ArgumentNullException(nameof(tagRepository));
@@ -76,7 +72,7 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Where("umbracoNode.id in (@ids)", new { /*ids =*/ ids });
}
return ProcessQuery(sql);
return MapQueryDtos(Database.Fetch<ContentVersionDto>(sql));
}
protected override IEnumerable<IMedia> PerformGetByQuery(IQuery<IMedia> query)
@@ -86,7 +82,7 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = translator.Translate()
.OrderBy<NodeDto>(x => x.SortOrder);
return ProcessQuery(sql);
return MapQueryDtos(Database.Fetch<ContentVersionDto>(sql));
}
#endregion
@@ -144,6 +140,15 @@ namespace Umbraco.Core.Persistence.Repositories
#region Overrides of VersionableRepositoryBase<IContent>
public override IEnumerable<IMedia> GetAllVersions(int id)
{
var sql = GetBaseQuery(false)
.Where(GetBaseWhereClause(), new { Id = id })
.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
return MapQueryDtos(Database.Fetch<ContentVersionDto>(sql), true);
}
public override IMedia GetByVersion(Guid versionId)
{
var sql = GetBaseQuery(false);
@@ -421,46 +426,66 @@ namespace Umbraco.Core.Persistence.Repositories
}
return GetPagedResultsByQuery<ContentVersionDto>(query, pageIndex, pageSize, out totalRecords,
MapQueryDtos, orderBy, orderDirection, orderBySystemField, "cmsContentVersion",
x => MapQueryDtos(x), orderBy, orderDirection, orderBySystemField, "cmsContentVersion",
filterSql);
}
private IEnumerable<IMedia> ProcessQuery(Sql sql)
private IEnumerable<IMedia> MapQueryDtos(List<ContentVersionDto> dtos, bool withCache = false)
{
//NOTE: This doesn't allow properties to be part of the query
var dtos = Database.Fetch<ContentVersionDto>(sql);
return MapQueryDtos(dtos);
}
var content = new IMedia[dtos.Count];
var defs = new List<DocumentDefinition>();
private IEnumerable<IMedia> MapQueryDtos(List<ContentVersionDto> dtos)
{
var ids = dtos.Select(x => x.ContentDto.ContentTypeId).ToArray();
for (var i = 0; i < dtos.Count; i++)
{
var dto = dtos[i];
//content types
var contentTypes = ids.Length == 0 ? Enumerable.Empty<IMediaType>() : _mediaTypeRepository.GetAll(ids).ToArray();
// if the cache contains the item, use it
if (withCache)
{
var cached = RuntimeCache.GetCacheItem<IMedia>(GetCacheIdKey<IMedia>(dto.NodeId));
if (cached != null)
{
content[i] = cached;
continue;
}
}
var dtosWithContentTypes = dtos
//This select into and null check are required because we don't have a foreign damn key on the contentType column
// http://issues.umbraco.org/issue/U4-5503
.Select(x => new { dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentDto.ContentTypeId) })
.Where(x => x.contentType != null)
.ToArray();
// else, need to fetch from the database
// content type repository is full-cache so OK to get each one independently
var contentType = _mediaTypeRepository.Get(dto.ContentDto.ContentTypeId);
var factory = new MediaFactory(contentType, NodeObjectTypeId, dto.NodeId);
content[i] = factory.BuildEntity(dto);
//Go get the property data for each document
var docDefs = dtosWithContentTypes.Select(d => new DocumentDefinition(
d.dto.NodeId,
d.dto.VersionId,
d.dto.VersionDate,
d.dto.ContentDto.NodeDto.CreateDate,
d.contentType))
.ToArray();
// need properties
defs.Add(new DocumentDefinition(
dto.NodeId,
dto.VersionId,
dto.VersionDate,
dto.ContentDto.NodeDto.CreateDate,
contentType
));
}
var propertyData = GetPropertyCollection(docDefs);
// load all properties for all documents from database in 1 query
var propertyData = GetPropertyCollection(defs.ToArray());
return dtosWithContentTypes.Select(d => CreateMediaFromDto(
d.dto,
contentTypes.First(ct => ct.Id == d.dto.ContentDto.ContentTypeId),
propertyData[d.dto.NodeId]));
// assign
var dtoIndex = 0;
foreach (var def in defs)
{
// move to corresponding item (which has to exist)
while (dtos[dtoIndex].NodeId != def.Id) dtoIndex++;
// complete the item
var cc = content[dtoIndex];
cc.Properties = propertyData[cc.Id];
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity)cc).ResetDirtyProperties(false);
}
return content;
}
/// <summary>
@@ -6,7 +6,6 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -19,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy<IMediaType, int> _cachePolicy;
public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy<IMediaType, int> CachePolicy
@@ -10,7 +10,6 @@ using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Cache;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Persistence.Repositories
{
@@ -18,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories
internal class MemberGroupRepository : NPocoRepositoryBase<int, IMemberGroup>, IMemberGroupRepository
{
public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
private readonly MemberGroupFactory _modelFactory = new MemberGroupFactory();
@@ -11,7 +11,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Cache;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -30,8 +30,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ITagRepository _tagRepository;
private readonly IMemberGroupRepository _memberGroupRepository;
public MemberRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, IContentSection contentSection, IMapperCollection mappers)
: base(work, cache, logger, contentSection, mappers)
public MemberRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, IContentSection contentSection, IQueryFactory queryFactory)
: base(work, cache, logger, contentSection, queryFactory)
{
if (memberTypeRepository == null) throw new ArgumentNullException(nameof(memberTypeRepository));
if (tagRepository == null) throw new ArgumentNullException(nameof(tagRepository));
@@ -564,7 +564,7 @@ namespace Umbraco.Core.Persistence.Repositories
// better to create the query text only once!
return GetPagedResultsByQuery<MemberDto>(query, pageIndex, pageSize, out totalRecords,
MapQueryDtos, orderBy, orderDirection, orderBySystemField, "cmsMember",
x => MapQueryDtos(x), orderBy, orderDirection, orderBySystemField, "cmsMember",
filterSql);
}
@@ -598,56 +598,62 @@ namespace Umbraco.Core.Persistence.Repositories
return base.GetDatabaseFieldNameForOrderBy(orderBy);
}
private IEnumerable<IMember> MapQueryDtos(List<MemberDto> dtos)
private IEnumerable<IMember> MapQueryDtos(List<MemberDto> dtos, bool withCache = false)
{
var ids = dtos.Select(x => x.ContentVersionDto.ContentDto.ContentTypeId).ToArray();
var content = new IMember[dtos.Count];
var defs = new List<DocumentDefinition>();
//content types
var contentTypes = ids.Length == 0 ? Enumerable.Empty<IMemberType>() : _memberTypeRepository.GetAll(ids).ToArray();
for (var i = 0; i < dtos.Count; i++)
{
var dto = dtos[i];
var dtosWithContentTypes = dtos
//This select into and null check are required because we don't have a foreign damn key on the contentType column
// http://issues.umbraco.org/issue/U4-5503
.Select(x => new { dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentVersionDto.ContentDto.ContentTypeId) })
.Where(x => x.contentType != null)
.ToArray();
// if the cache contains the item, use it
if (withCache)
{
var cached = RuntimeCache.GetCacheItem<IMember>(GetCacheIdKey<IMember>(dto.NodeId));
if (cached != null)
{
content[i] = cached;
continue;
}
}
//Go get the property data for each document
IEnumerable<DocumentDefinition> docDefs = dtosWithContentTypes.Select(d => new DocumentDefinition(
d.dto.NodeId,
d.dto.ContentVersionDto.VersionId,
d.dto.ContentVersionDto.VersionDate,
d.dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
d.contentType));
// else, need to fetch from the database
// content type repository is full-cache so OK to get each one independently
var contentType = _memberTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId);
var factory = new MemberFactory(contentType, NodeObjectTypeId, dto.NodeId);
content[i] = factory.BuildEntity(dto);
var propertyData = GetPropertyCollection(docDefs.ToArray());
// need properties
defs.Add(new DocumentDefinition(
dto.NodeId,
dto.ContentVersionDto.VersionId,
dto.ContentVersionDto.VersionDate,
dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
contentType
));
}
return dtosWithContentTypes.Select(d => CreateMemberFromDto(
d.dto,
contentTypes.First(ct => ct.Id == d.dto.ContentVersionDto.ContentDto.ContentTypeId),
propertyData[d.dto.NodeId]));
}
// load all properties for all documents from database in 1 query
var propertyData = GetPropertyCollection(defs.ToArray());
/// <summary>
/// Private method to create a member object from a MemberDto
/// </summary>
/// <param name="dto"></param>
/// <param name="contentType"></param>
/// <param name="propCollection"></param>
/// <returns></returns>
private IMember CreateMemberFromDto(MemberDto dto,
IMemberType contentType,
PropertyCollection propCollection)
{
var factory = new MemberFactory(contentType, NodeObjectTypeId, dto.ContentVersionDto.NodeId);
var member = factory.BuildEntity(dto);
// assign
var dtoIndex = 0;
foreach (var def in defs)
{
// move to corresponding item (which has to exist)
while (dtos[dtoIndex].NodeId != def.Id) dtoIndex++;
member.Properties = propCollection;
// complete the item
var cc = content[dtoIndex];
cc.Properties = propertyData[cc.Id];
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity)member).ResetDirtyProperties(false);
return member;
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity)cc).ResetDirtyProperties(false);
}
return content;
}
/// <summary>
@@ -21,8 +21,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy<IMemberType, int> _cachePolicy;
public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy<IMemberType, int> CachePolicy
@@ -10,17 +10,15 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class MigrationEntryRepository : NPocoRepositoryBase<int, IMigrationEntry>, IMigrationEntryRepository
{
public MigrationEntryRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public MigrationEntryRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -4,7 +4,6 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -25,11 +24,11 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="work">A database unit of work.</param>
/// <param name="cache">A cache helper.</param>
/// <param name="logger">A logger.</param>
/// <param name="mappers">A mappers collection.</param>
protected NPocoRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
/// <param name="queryFactory">A query factory.</param>
protected NPocoRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger)
{
QueryFactory = new QueryFactory(SqlSyntax, mappers);
QueryFactory = queryFactory;
}
/// <summary>
@@ -7,9 +7,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -18,8 +16,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy<PublicAccessEntry, Guid> _cachePolicy;
public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy<PublicAccessEntry, Guid> CachePolicy
@@ -4,6 +4,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -12,8 +13,8 @@ namespace Umbraco.Core.Persistence.Repositories
where TEntity : class, IUmbracoEntity
where TRepository : class, IRepository
{
protected RecycleBinRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IMapperCollection mappers)
: base(work, cache, logger, contentSection, mappers)
protected RecycleBinRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IQueryFactory queryFactory)
: base(work, cache, logger, contentSection, queryFactory)
{
}
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -16,8 +13,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class RedirectUrlRepository : NPocoRepositoryBase<Guid, IRedirectUrl>, IRedirectUrlRepository
{
public RedirectUrlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public RedirectUrlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
protected override int PerformCount(IQuery<IRedirectUrl> query)
@@ -11,9 +11,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -25,8 +23,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IRelationTypeRepository _relationTypeRepository;
public RelationRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IRelationTypeRepository relationTypeRepository, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public RelationRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IRelationTypeRepository relationTypeRepository, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
_relationTypeRepository = relationTypeRepository;
}
@@ -47,34 +45,17 @@ namespace Umbraco.Core.Persistence.Repositories
throw new Exception(string.Format("RelationType with Id: {0} doesn't exist", dto.RelationType));
var factory = new RelationFactory(relationType);
var entity = factory.BuildEntity(dto);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((TracksChangesEntityBase)entity).ResetDirtyProperties(false);
return entity;
return DtoToEntity(dto, factory);
}
//TODO: Fix N+1 !
protected override IEnumerable<IRelation> PerformGetAll(params int[] ids)
{
if (ids.Any())
{
foreach (var id in ids)
{
yield return Get(id);
}
}
else
{
var dtos = Database.Fetch<RelationDto>("WHERE id > 0");
foreach (var dto in dtos)
{
yield return Get(dto.Id);
}
}
var sql = GetBaseQuery(false);
if (ids.Length > 0)
sql.WhereIn<RelationDto>(x => x.Id, ids);
sql.OrderBy<RelationDto>(x => x.RelationType);
var dtos = Database.Fetch<RelationDto>(sql);
return DtosToEntities(dtos);
}
protected override IEnumerable<IRelation> PerformGetByQuery(IQuery<IRelation> query)
@@ -82,13 +63,36 @@ namespace Umbraco.Core.Persistence.Repositories
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator<IRelation>(sqlClause, query);
var sql = translator.Translate();
sql.OrderBy<RelationDto>(x => x.RelationType);
var dtos = Database.Fetch<RelationDto>(sql);
return DtosToEntities(dtos);
}
foreach (var dto in dtos)
private IEnumerable<IRelation> DtosToEntities(IEnumerable<RelationDto> dtos)
{
// in most cases, the relation type will be the same for all of them,
// plus we've ordered the relations by type, so try to allocate as few
// factories as possible - bearing in mind that relation types are cached
RelationFactory factory = null;
var relationTypeId = -1;
return dtos.Select(x =>
{
yield return Get(dto.Id);
}
if (relationTypeId != x.RelationType)
factory = new RelationFactory(_relationTypeRepository.Get(relationTypeId = x.RelationType));
return DtoToEntity(x, factory);
});
}
private static IRelation DtoToEntity(RelationDto dto, RelationFactory factory)
{
var entity = factory.BuildEntity(dto);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((TracksChangesEntityBase)entity).ResetDirtyProperties(false);
return entity;
}
#endregion
@@ -1,19 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LightInject;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.DI;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -23,50 +18,45 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class RelationTypeRepository : NPocoRepositoryBase<int, IRelationType>, IRelationTypeRepository
{
private IRepositoryCachePolicy<IRelationType, int> _cachePolicy;
public RelationTypeRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public RelationTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{ }
protected override IRepositoryCachePolicy<IRelationType, int> CachePolicy
{
get
{
if (_cachePolicy != null) return _cachePolicy;
// assuming we don't have tons of relation types, use a FullDataSet policy, ie
// cache the entire GetAll result once in a single collection - which can expire
_cachePolicy = new FullDataSetRepositoryCachePolicy<IRelationType, int>(RuntimeCache, GetEntityId, /*expires:*/ true);
return _cachePolicy;
}
}
#region Overrides of RepositoryBase<int,RelationType>
protected override IRelationType PerformGet(int id)
{
var sql = GetBaseQuery(false);
sql.Where(GetBaseWhereClause(), new { Id = id });
var dto = Database.Fetch<RelationTypeDto>(SqlSyntax.SelectTop(sql, 1)).FirstOrDefault();
if (dto == null)
return null;
var factory = new RelationTypeFactory();
var entity = factory.BuildEntity(dto);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((TracksChangesEntityBase)entity).ResetDirtyProperties(false);
return entity;
// use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Id == id);
}
protected override IEnumerable<IRelationType> PerformGetAll(params int[] ids)
{
var sql = GetBaseQuery(false);
// should not happen due to the cache policy
if (ids.Any())
{
foreach (var id in ids)
{
yield return Get(id);
}
}
else
{
var dtos = Database.Fetch<RelationTypeDto>("WHERE id > 0");
foreach (var dto in dtos)
{
yield return Get(dto.Id);
}
}
throw new NotImplementedException();
var dtos = Database.Fetch<RelationTypeDto>(sql);
var factory = new RelationTypeFactory();
return dtos.Select(x => DtoToEntity(x, factory));
}
protected override IEnumerable<IRelationType> PerformGetByQuery(IQuery<IRelationType> query)
@@ -76,11 +66,19 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = translator.Translate();
var dtos = Database.Fetch<RelationTypeDto>(sql);
var factory = new RelationTypeFactory();
return dtos.Select(x => DtoToEntity(x, factory));
}
foreach (var dto in dtos)
{
yield return Get(dto.Id);
}
private static IRelationType DtoToEntity(RelationTypeDto dto, RelationTypeFactory factory)
{
var entity = factory.BuildEntity(dto);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((TracksChangesEntityBase) entity).ResetDirtyProperties(false);
return entity;
}
#endregion
@@ -71,6 +71,12 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
public abstract IQueryFactory QueryFactory { get; }
#region Static Queries
private IQuery<TEntity> _hasIdQuery;
#endregion
protected virtual TId GetEntityId(TEntity entity)
{
return (TId)(object)entity.Id;
@@ -91,9 +97,14 @@ namespace Umbraco.Core.Persistence.Repositories
var options = new RepositoryCachePolicyOptions(() =>
{
//create it once if it is needed (no need for locking here)
if (_hasIdQuery == null)
{
_hasIdQuery = Query.Where(x => x.Id != 0);
}
//Get count of all entities of current type (TEntity) to ensure cached result is correct
var query = Query.Where(x => x.Id != 0);
return PerformCount(query);
return PerformCount(_hasIdQuery);
});
_cachePolicy = new DefaultRepositoryCachePolicy<TEntity, TId>(RuntimeCache, options);
@@ -5,10 +5,8 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -18,8 +16,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private IRepositoryCachePolicy<IServerRegistration, int> _cachePolicy;
public ServerRegistrationRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IMapperCollection mappers)
: base(work, CacheHelper.CreateDisabledCacheHelper(), logger, mappers)
public ServerRegistrationRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IQueryFactory queryFactory)
: base(work, CacheHelper.CreateDisabledCacheHelper(), logger, queryFactory)
{ }
protected override IRepositoryCachePolicy<IServerRegistration, int> CachePolicy => _cachePolicy
@@ -5,9 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -20,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories
where TDto: class
{
protected SimpleGetRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
protected SimpleGetRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -9,17 +9,15 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class TagRepository : NPocoRepositoryBase<int, ITag>, ITagRepository
{
public TagRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public TagRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -1,27 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using LightInject;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.DI;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class TaskRepository : NPocoRepositoryBase<int, Task>, ITaskRepository
{
public TaskRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public TaskRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -9,17 +9,15 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class TaskTypeRepository : NPocoRepositoryBase<int, TaskType>, ITaskTypeRepository
{
public TaskTypeRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public TaskTypeRepository(IDatabaseUnitOfWork work, [Inject(RepositoryCompositionRoot.DisabledCache)] CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -37,8 +37,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly MasterPageHelper _masterPageHelper;
private IRepositoryCachePolicy<ITemplate, int> _cachePolicy;
public TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
_masterpagesFileSystem = masterpageFileSystem;
_viewsFileSystem = viewFileSystem;
@@ -28,8 +28,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly CacheHelper _cacheHelper;
private PermissionRepository<IContent> _permissionRepository;
public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository, IMapperCollection mappers)
: base(work, cacheHelper, logger, mappers)
public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository, IQueryFactory queryFactory)
: base(work, cacheHelper, logger, queryFactory)
{
_userTypeRepository = userTypeRepository;
_cacheHelper = cacheHelper;
@@ -20,8 +20,8 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class UserTypeRepository : NPocoRepositoryBase<int, IUserType>, IUserTypeRepository
{
public UserTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMapperCollection mappers)
: base(work, cache, logger, mappers)
public UserTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
}
@@ -50,8 +50,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
//private readonly IContentSection _contentSection;
protected VersionableRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IMapperCollection mappers)
: base(work, cache, logger, mappers)
protected VersionableRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IContentSection contentSection, IQueryFactory queryFactory)
: base(work, cache, logger, queryFactory)
{
//_contentSection = contentSection;
}
@@ -7,7 +7,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Represents an SqlSyntaxProvider for Sql Server
/// Represents an SqlSyntaxProvider for Sql Server.
/// </summary>
[SqlSyntaxProvider(Constants.DbProviderNames.SqlServer)]
public class SqlServerSyntaxProvider : MicrosoftSqlSyntaxProviderBase<SqlServerSyntaxProvider>
@@ -38,6 +38,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
V2008 = 4,
V2012 = 5,
V2014 = 6,
V2016 = 7,
Other = 99
}
@@ -70,6 +71,9 @@ namespace Umbraco.Core.Persistence.SqlSyntax
case "??":
ProductVersionName = VersionName.Invalid;
break;
case "13":
ProductVersionName = VersionName.V2016;
break;
case "12":
ProductVersionName = VersionName.V2014;
break;
@@ -136,7 +140,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
{
var items = db.Fetch<dynamic>("SELECT TableName = t.Name,ColumnName = c.Name,dc.Name,dc.[Definition] FROM sys.tables t INNER JOIN sys.default_constraints dc ON t.object_id = dc.parent_object_id INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND c.column_id = dc.parent_column_id");
return items.Select(x => new Tuple<string, string, string, string>(x.TableName, x.ColumnName, x.Name, x.Definition));
}
}
public override IEnumerable<string> GetTablesInSchema(Database db)
{
@@ -181,9 +185,9 @@ from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id
inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id]
WHERE I.name NOT LIKE 'PK_%'
order by T.name, I.name");
return items.Select(item => new Tuple<string, string, string, bool>(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
return items.Select(item => new Tuple<string, string, string, bool>(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
item.UNIQUE == 1)).ToList();
}
public override bool DoesTableExist(Database db, string tableName)
@@ -225,7 +229,7 @@ order by T.name, I.name");
switch (systemMethod)
{
case SystemMethods.NewGuid:
return "NEWID()";
return "NEWID()";
case SystemMethods.CurrentDateTime:
return "GETDATE()";
//case SystemMethods.NewSequentialId:
@@ -239,7 +243,6 @@ order by T.name, I.name");
public override string DeleteDefaultConstraint => "ALTER TABLE [{0}] DROP CONSTRAINT [DF_{0}_{1}]";
public override string DropIndex => "DROP INDEX {0} ON {1}";
public override string RenameColumn => "sp_rename '{0}.{1}', '{2}', 'COLUMN'";
+9 -2
View File
@@ -28,14 +28,22 @@ namespace Umbraco.Core.Services
IDatabaseUnitOfWorkProvider provider,
ILogger logger,
IEventMessagesFactory eventMessagesFactory,
IQueryFactory queryFactory,
MediaFileSystem mediaFileSystem)
: base(provider, logger, eventMessagesFactory)
{
_mediaFileSystem = mediaFileSystem;
_notTrashedQuery = queryFactory.Create<IContent>().Where(x => x.Trashed == false);
}
#endregion
#region Static Queries
private readonly IQuery<IContent> _notTrashedQuery;
#endregion
#region Count
public int CountPublished(string contentTypeAlias = null)
@@ -826,8 +834,7 @@ namespace Umbraco.Core.Services
{
uow.ReadLock(Constants.Locks.ContentTree);
var repository = uow.CreateRepository<IContentRepository>();
var query = repository.Query.Where(x => x.Trashed == false);
var content = repository.GetByPublishedVersion(query);
var content = repository.GetByPublishedVersion(_notTrashedQuery);
uow.Complete();
return content;
}
+12 -6
View File
@@ -20,17 +20,18 @@ namespace Umbraco.Core.Services
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>> _supportedObjectTypes;
public EntityService(IDatabaseUnitOfWorkProvider provider, ILogger logger, IEventMessagesFactory eventMessagesFactory,
IContentService contentService, IContentTypeService contentTypeService,
IContentService contentService, IContentTypeService contentTypeService,
IMediaService mediaService, IMediaTypeService mediaTypeService,
IDataTypeService dataTypeService,
IMemberService memberService, IMemberTypeService memberTypeService,
IQueryFactory queryFactory,
IRuntimeCacheProvider runtimeCache)
: base(provider, logger, eventMessagesFactory)
{
_runtimeCache = runtimeCache;
_rootEntityQuery = queryFactory.Create<IUmbracoEntity>().Where(x => x.ParentId == -1);
_supportedObjectTypes = new Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>>
{
@@ -60,12 +61,18 @@ namespace Umbraco.Core.Services
// ParentId = found.ParentId
// };
// }
//})}
};
}
#region Static Queries
private readonly IQuery<IUmbracoEntity> _rootEntityQuery;
#endregion
/// <summary>
/// Returns the integer id for a given GUID
/// </summary>
@@ -108,7 +115,7 @@ namespace Umbraco.Core.Services
}
uow.Complete();
return id;
}
}
});
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt<int>.Fail();
}
@@ -435,8 +442,7 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.CreateUnitOfWork())
{
var repository = uow.CreateRepository<IEntityRepository>();
var query = repository.Query.Where(x => x.ParentId == -1);
var entities = repository.GetByQuery(query, objectTypeId);
var entities = repository.GetByQuery(_rootEntityQuery, objectTypeId);
uow.Complete();
return entities;
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using System.IO;
using Umbraco.Core.Models;
+1 -1
View File
@@ -181,7 +181,7 @@ namespace Umbraco.Core
/// <param name="input"></param>
/// <param name="ignoreFromClean"></param>
/// <returns></returns>
internal static string CleanForXss(this string input, params char[] ignoreFromClean)
public static string CleanForXss(this string input, params char[] ignoreFromClean)
{
//remove any html
input = input.StripHtml();
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Sync
{
public class SingleServerRegistrar : IServerRegistrar
{
private readonly IRuntimeState _runtime;
private readonly Lazy<IServerAddress[]> _registrations;
public IEnumerable<IServerAddress> Registrations => _registrations.Value;
public SingleServerRegistrar(IRuntimeState runtime)
{
_runtime = runtime;
_registrations = new Lazy<IServerAddress[]>(() => new[] { new ServerAddressImpl(_runtime.ApplicationUrl.ToString()) });
}
public ServerRole GetCurrentServerRole()
{
return ServerRole.Single;
}
public string GetCurrentServerUmbracoApplicationUrl()
{
return _runtime.ApplicationUrl.ToString();
}
private class ServerAddressImpl : IServerAddress
{
public ServerAddressImpl(string serverAddress)
{
ServerAddress = serverAddress;
}
public string ServerAddress { get; }
}
}
}
+13 -7
View File
@@ -331,7 +331,6 @@
<Compile Include="Models\ContentTypeAvailableCompositionsResult.cs" />
<Compile Include="Models\ContentTypeAvailableCompositionsResults.cs" />
<Compile Include="Models\EntityContainer.cs" />
<Compile Include="Models\Rdbms\LockDto.cs" />
<Compile Include="Models\Identity\IdentityModelMappings.cs" />
<Compile Include="Models\Identity\IdentityUser.cs" />
<Compile Include="Models\Identity\IdentityUserClaim.cs" />
@@ -349,7 +348,6 @@
<Compile Include="Models\PublicAccessRule.cs" />
<Compile Include="Models\Rdbms\AccessDto.cs" />
<Compile Include="Persistence\Constants-DbProviderNames.cs" />
<Compile Include="Persistence\Constants-Locks.cs" />
<Compile Include="Persistence\FaultHandling\RetryDbConnection.cs">
<SubType>Component</SubType>
</Compile>
@@ -374,6 +372,7 @@
<Compile Include="Media\Exif\ExifTag.cs" />
<Compile Include="Media\Exif\ExifTagFactory.cs" />
<Compile Include="Models\Rdbms\AccessRuleDto.cs" />
<Compile Include="Models\Rdbms\LockDto.cs" />
<Compile Include="Models\Rdbms\RedirectUrlDto.cs" />
<Compile Include="Models\Rdbms\DocumentPublishedReadOnlyDto.cs" />
<Compile Include="Models\Rdbms\ExternalLoginDto.cs" />
@@ -386,7 +385,7 @@
<Compile Include="Models\DoNotCloneAttribute.cs" />
<Compile Include="Models\IDomain.cs" />
<Compile Include="Persistence\BulkDataReader.cs" />
<Compile Include="SafeCallContext.cs" />
<Compile Include="Persistence\Constants-Locks.cs" />
<Compile Include="Persistence\DatabaseNodeLockExtensions.cs" />
<Compile Include="Persistence\Factories\ExternalLoginFactory.cs" />
<Compile Include="Persistence\Factories\MigrationEntryFactory.cs" />
@@ -398,6 +397,9 @@
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
<Compile Include="Persistence\Migrations\LocalMigrationContext.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionFourOneZero\AddPreviewXmlTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveFive\AddLockObjects.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveFive\AddLockTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveFive\UpdateAllowedMediaTypesAtRoot.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\AddRedirectUrlTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\RemoveStylesheetDataAndTablesAgain.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\UpdateUniqueIndexOnCmsPropertyData.cs" />
@@ -407,6 +409,7 @@
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\AddUniqueIdPropertyTypeGroupColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\RemoveParentIdPropertyTypeGroupColumn.cs" />
<Compile Include="Persistence\Mappers\TaskTypeMapper.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\RemovePropertyDataIdIndex.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeTwo\EnsureMigrationsTableIdentityIsCorrect.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\EnsureContentTypeUniqueIdsAreConsistent.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddExternalLoginsTable.cs" />
@@ -442,6 +445,7 @@
<Compile Include="Media\Exif\Utility.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeOne\UpdateUserLanguagesToIsoCode.cs" />
<Compile Include="Persistence\PocoDataDataReader.cs" />
<Compile Include="Persistence\Querying\QueryExtensions.cs" />
<Compile Include="Persistence\RecordPersistenceType.cs" />
<Compile Include="Persistence\Repositories\AuditRepository.cs" />
<Compile Include="Persistence\Repositories\EntityContainerRepository.cs" />
@@ -503,6 +507,7 @@
<Compile Include="Services\Changes\DomainChangeTypes.cs" />
<Compile Include="Services\UnPublishedStatusType.cs" />
<Compile Include="Services\UnPublishStatus.cs" />
<Compile Include="SafeCallContext.cs" />
<Compile Include="Security\ActiveDirectoryBackOfficeUserPasswordChecker.cs" />
<Compile Include="Security\BackOfficeClaimsIdentityFactory.cs" />
<Compile Include="Security\BackOfficeCookieAuthenticationProvider.cs" />
@@ -987,10 +992,10 @@
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\UpdateCmsPropertyTypeGroupTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSix\RenameCmsTabTable.cs" />
<Compile Include="Persistence\NPocoDatabaseExtensions.cs" />
<Compile Include="Persistence\Querying\BaseExpressionHelper.cs" />
<Compile Include="Persistence\Querying\PocoToSqlExpressionHelper.cs" />
<Compile Include="Persistence\Querying\ExpressionVisitorBase.cs" />
<Compile Include="Persistence\Querying\PocoToSqlExpressionVisitor.cs" />
<Compile Include="Persistence\Querying\IQuery.cs" />
<Compile Include="Persistence\Querying\ModelToSqlExpressionHelper.cs" />
<Compile Include="Persistence\Querying\ModelToSqlExpressionVisitor.cs" />
<Compile Include="Persistence\Querying\Query.cs" />
<Compile Include="Persistence\Querying\SqlTranslator.cs" />
<Compile Include="Persistence\Repositories\ContentRepository.cs" />
@@ -1256,6 +1261,7 @@
<Compile Include="Sync\ApplicationUrlHelper.cs" />
<Compile Include="Sync\RefreshMethodType.cs" />
<Compile Include="Sync\ServerMessengerBase.cs" />
<Compile Include="Sync\SingleServerRegistrar.cs" />
<Compile Include="ThreadExtensions.cs" />
<Compile Include="TopologicalSorter.cs" />
<Compile Include="Strings\DefaultUrlSegmentProvider.cs" />
@@ -1365,7 +1371,7 @@
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
@@ -13,6 +13,7 @@ using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Migrations.Initial;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Tests.TestHelpers;
using ILogger = Umbraco.Core.Logging.ILogger;
@@ -47,25 +48,27 @@ namespace Umbraco.Tests.Benchmarks
{
IDatabaseFactory f = null;
var l = new Lazy<IDatabaseFactory>(() => f);
var p = new SqlServerSyntaxProvider(l);
f = new DefaultDatabaseFactory(
"server=.\\SQLExpress;database=YOURDB;user id=YOURUSER;password=YOURPASS",
Constants.DatabaseProviders.SqlServer,
new [] { new SqlServerSyntaxProvider(l) },
new [] { p },
logger,
new ThreadStaticUmbracoDatabaseAccessor(),
new MapperCollection(Enumerable.Empty<BaseMapper>()));
new QueryFactory(p, new MapperCollection(Enumerable.Empty<BaseMapper>())));
return f.GetDatabase();
}
private UmbracoDatabase GetSqlCeDatabase(string cstr, ILogger logger)
{
var p = new SqlCeSyntaxProvider();
var f = new DefaultDatabaseFactory(
cstr,
Constants.DatabaseProviders.SqlCe,
new[] { new SqlCeSyntaxProvider() },
new[] { p },
logger,
new ThreadStaticUmbracoDatabaseAccessor(),
new MapperCollection(Enumerable.Empty<BaseMapper>()));
new QueryFactory(p, new MapperCollection(Enumerable.Empty<BaseMapper>())));
return f.GetDatabase();
}
@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.Diagnostics;
using System.IO;
using System.Linq.Expressions;
using System.Threading;
using System.Xml;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Diagnostics.Windows;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Validators;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Migrations.Initial;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Tests.TestHelpers;
using ILogger = Umbraco.Core.Logging.ILogger;
namespace Umbraco.Tests.Benchmarks
{
[Config(typeof(Config))]
public class ModelToSqlExpressionHelperBenchmarks
{
private class Config : ManualConfig
{
public Config()
{
Add(new MemoryDiagnoser());
}
}
public ModelToSqlExpressionHelperBenchmarks()
{
_contentMapper = new ContentMapper();
// _contentMapper.BuildMap(); // fixme - protected?
_cachedExpression = new CachedExpression();
}
private readonly ISqlSyntaxProvider _syntaxProvider = new SqlCeSyntaxProvider();
private readonly BaseMapper _contentMapper;
private readonly CachedExpression _cachedExpression;
[Benchmark(Baseline = true)]
public void WithNonCached()
{
for (int i = 0; i < 100; i++)
{
var a = i;
var b = i*10;
Expression<Func<IContent, bool>> predicate = content =>
content.Path.StartsWith("-1") && content.Published && (content.ContentTypeId == a || content.ContentTypeId == b);
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IContent>(_syntaxProvider, _contentMapper);
var result = modelToSqlExpressionHelper.Visit(predicate);
}
}
[Benchmark()]
public void WithCachedExpression()
{
for (int i = 0; i < 100; i++)
{
var a = i;
var b = i * 10;
Expression<Func<IContent, bool>> predicate = content =>
content.Path.StartsWith("-1") && content.Published && (content.ContentTypeId == a || content.ContentTypeId == b);
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IContent>(_syntaxProvider, _contentMapper);
//wrap it!
_cachedExpression.Wrap(predicate);
var result = modelToSqlExpressionHelper.Visit(_cachedExpression);
}
}
}
}
+1 -6
View File
@@ -8,12 +8,7 @@ namespace Umbraco.Tests.Benchmarks
{
public static void Main(string[] args)
{
if (args.Length == 0)
{
var summary = BenchmarkRunner.Run<BulkInsertBenchmarks>();
Console.ReadLine();
}
else if (args.Length == 1)
if (args.Length == 1)
{
var type = Assembly.GetExecutingAssembly().GetType("Umbraco.Tests.Benchmarks." +args[0]);
if (type == null)
@@ -104,6 +104,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ModelToSqlExpressionHelperBenchmarks.cs" />
<Compile Include="BulkInsertBenchmarks.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -10,6 +10,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
@@ -37,7 +38,7 @@ namespace Umbraco.Tests.Persistence
_sqlCeSyntaxProvider = new SqlCeSyntaxProvider();
_sqlSyntaxProviders = new[] { (ISqlSyntaxProvider) _sqlCeSyntaxProvider };
_logger = Mock.Of<ILogger>();
var dbFactory = new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, _sqlSyntaxProviders, _logger, new TestUmbracoDatabaseAccessor(), Mock.Of<IMapperCollection>());
var dbFactory = new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, _sqlSyntaxProviders, _logger, new TestUmbracoDatabaseAccessor(), Mock.Of<IQueryFactory>());
_runtime = Mock.Of<IRuntimeState>();
_migrationEntryService = Mock.Of<IMigrationEntryService>();
_dbContext = new DatabaseContext(dbFactory, _logger, _runtime, _migrationEntryService);
@@ -90,7 +91,7 @@ namespace Umbraco.Tests.Persistence
}
// re-create the database factory and database context with proper connection string
var dbFactory = new DefaultDatabaseFactory(connString, Constants.DbProviderNames.SqlCe, _sqlSyntaxProviders, _logger, new TestUmbracoDatabaseAccessor(), Mock.Of<IMapperCollection>());
var dbFactory = new DefaultDatabaseFactory(connString, Constants.DbProviderNames.SqlCe, _sqlSyntaxProviders, _logger, new TestUmbracoDatabaseAccessor(), Mock.Of<IQueryFactory>());
_dbContext = new DatabaseContext(dbFactory, _logger, _runtime, _migrationEntryService);
// create application context
@@ -6,6 +6,7 @@ using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
@@ -22,7 +23,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling
const string connectionString = @"server=.\SQLEXPRESS;database=EmptyForTest;user id=x;password=umbraco";
const string providerName = Constants.DbProviderNames.SqlServer;
var sqlSyntax = new[] { new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null)) };
var factory = new DefaultDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), new TestUmbracoDatabaseAccessor(), Mock.Of<IMapperCollection>());
var factory = new DefaultDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), new TestUmbracoDatabaseAccessor(), Mock.Of<IQueryFactory>());
var database = factory.GetDatabase();
//Act
@@ -37,7 +38,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling
const string connectionString = @"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco";
const string providerName = Constants.DbProviderNames.SqlServer;
var sqlSyntax = new[] { new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null)) };
var factory = new DefaultDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), new TestUmbracoDatabaseAccessor(), Mock.Of<IMapperCollection>());
var factory = new DefaultDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), new TestUmbracoDatabaseAccessor(), Mock.Of<IQueryFactory>());
var database = factory.GetDatabase();
//Act
+268
View File
@@ -0,0 +1,268 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlServerCe;
using System.Threading;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Services;
using Umbraco.Tests.Services;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Persistence
{
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
// fixme [Ignore("Takes too much time.")]
public class LocksTests : TestWithDatabaseBase
{
//private ThreadSafetyServiceTest.PerThreadPetaPocoUnitOfWorkProvider _uowProvider;
//private ThreadSafetyServiceTest.PerThreadDatabaseFactory _dbFactory;
public override void SetUp()
{
base.SetUp();
// need to use a special IDatabaseFactory because we MUST ensure that a Database instance
// is created per thread - though... now the default one is LCC based, should it work? fixme
Container.Register<IDatabaseFactory, ThreadSafetyServiceTest.PerThreadSqlCeDatabaseFactory>();
// create a few lock objects
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.Execute("SET IDENTITY_INSERT umbracoLock ON");
database.Insert("umbracoLock", "id", false, new LockDto { Id = 1, Name = "Lock.1" });
database.Insert("umbracoLock", "id", false, new LockDto { Id = 2, Name = "Lock.2" });
database.Insert("umbracoLock", "id", false, new LockDto { Id = 3, Name = "Lock.3" });
database.Execute("SET IDENTITY_INSERT umbracoLock OFF");
database.CompleteTransaction();
}
catch
{
database.AbortTransaction();
}
}
[Test]
public void Test()
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.AcquireLockNodeReadLock(Constants.Locks.Servers);
}
finally
{
database.CompleteTransaction();
}
}
[Test]
public void ConcurrentReadersTest()
{
var threads = new List<Thread>();
var locker = new object();
var acquired = 0;
var maxAcquired = 0;
for (var i = 0; i < 5; i++)
{
threads.Add(new Thread(() =>
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.AcquireLockNodeReadLock(Constants.Locks.Servers);
lock (locker)
{
acquired++;
}
Thread.Sleep(500);
lock (locker)
{
if (maxAcquired < acquired) maxAcquired = acquired;
}
Thread.Sleep(500);
lock (locker)
{
acquired--;
}
}
finally
{
database.CompleteTransaction();
}
}));
}
foreach (var thread in threads) thread.Start();
foreach (var thread in threads) thread.Join();
Assert.AreEqual(5, maxAcquired);
}
[Test]
public void ConcurrentWritersTest()
{
var threads = new List<Thread>();
var locker = new object();
var acquired = 0;
var maxAcquired = 0;
for (var i = 0; i < 5; i++)
{
threads.Add(new Thread(() =>
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.AcquireLockNodeWriteLock(Constants.Locks.Servers);
lock (locker)
{
acquired++;
}
Thread.Sleep(500);
lock (locker)
{
if (maxAcquired < acquired) maxAcquired = acquired;
}
Thread.Sleep(500);
lock (locker)
{
acquired--;
}
}
finally
{
database.CompleteTransaction();
}
}));
}
foreach (var thread in threads) thread.Start();
foreach (var thread in threads) thread.Join();
Assert.AreEqual(1, maxAcquired);
}
[Test]
public void DeadLockTest()
{
Exception e1 = null, e2 = null;
var thread1 = new Thread(() =>
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.AcquireLockNodeWriteLock(1);
Thread.Sleep(1000);
database.AcquireLockNodeWriteLock(2);
Thread.Sleep(1000);
}
catch (Exception e)
{
e1 = e;
}
finally
{
database.CompleteTransaction();
}
});
var thread2 = new Thread(() =>
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.AcquireLockNodeWriteLock(2);
Thread.Sleep(1000);
database.AcquireLockNodeWriteLock(1);
Thread.Sleep(1000);
}
catch (Exception e)
{
e2 = e;
}
finally
{
database.CompleteTransaction();
}
});
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Assert.IsNotNull(e1);
Assert.IsNotNull(e2);
Assert.IsInstanceOf<SqlCeLockTimeoutException>(e1);
Assert.IsInstanceOf<SqlCeLockTimeoutException>(e2);
}
[Test]
public void NoDeadLockTest()
{
Exception e1 = null, e2 = null;
var thread1 = new Thread(() =>
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
database.AcquireLockNodeWriteLock(1);
var info = database.Query<dynamic>("SELECT * FROM sys.lock_information;");
Console.WriteLine("LOCKS:");
foreach (var row in info)
Console.WriteLine(string.Format("> {0} {1} {2} {3} {4} {5} {6}", row.request_spid,
row.resource_type, row.resource_description, row.request_mode, row.resource_table,
row.resource_table_id, row.request_status));
Thread.Sleep(6000);
}
catch (Exception e)
{
e1 = e;
}
finally
{
database.CompleteTransaction();
}
});
var thread2 = new Thread(() =>
{
var database = DatabaseContext.Database;
database.BeginTransaction(IsolationLevel.RepeatableRead);
try
{
Thread.Sleep(1000);
database.AcquireLockNodeWriteLock(2);
var info = database.Query<dynamic>("SELECT * FROM sys.lock_information;");
Console.WriteLine("LOCKS:");
foreach (var row in info)
Console.WriteLine(string.Format("> {0} {1} {2} {3} {4} {5} {6}", row.request_spid,
row.resource_type, row.resource_description, row.request_mode, row.resource_table,
row.resource_table_id, row.request_status));
Thread.Sleep(1000);
}
catch (Exception e)
{
e2 = e;
}
finally
{
database.CompleteTransaction();
}
});
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Assert.IsNull(e1);
Assert.IsNull(e2);
}
}
}
@@ -19,30 +19,53 @@ namespace Umbraco.Tests.Persistence.Querying
[TestFixture]
public class ExpressionTests : BaseUsingSqlCeSyntax
{
// [Test]
// public void Can_Query_With_Content_Type_Alias()
// {
// //Arrange
// Expression<Func<IMedia, bool>> predicate = content => content.ContentType.Alias == "Test";
// var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IContent>();
// var result = modelToSqlExpressionHelper.Visit(predicate);
// [Test]
// public void Can_Query_With_Content_Type_Alias()
// {
// //Arrange
// Expression<Func<IMedia, bool>> predicate = content => content.ContentType.Alias == "Test";
// var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IContent>();
// var result = modelToSqlExpressionHelper.Visit(predicate);
// Debug.Print("Model to Sql ExpressionHelper: \n" + result);
// Debug.Print("Model to Sql ExpressionHelper: \n" + result);
// Assert.AreEqual("[cmsContentType].[alias] = @0", result);
// Assert.AreEqual("Test", modelToSqlExpressionHelper.GetSqlParameters()[0]);
// }
// Assert.AreEqual("[cmsContentType].[alias] = @0", result);
// Assert.AreEqual("Test", modelToSqlExpressionHelper.GetSqlParameters()[0]);
// }
[Test]
public void CachedExpression_Can_Verify_Path_StartsWith_Predicate_In_Same_Result()
{
//Arrange
//use a single cached expression for multiple expressions and ensure the correct output
// is done for both of them.
var cachedExpression = new CachedExpression();
Expression<Func<IContent, bool>> predicate1 = content => content.Path.StartsWith("-1");
cachedExpression.Wrap(predicate1);
var modelToSqlExpressionHelper1 = new ModelToSqlExpressionVisitor<IContent>(SqlContext.SqlSyntax, Mappers);
var result1 = modelToSqlExpressionHelper1.Visit(cachedExpression);
Assert.AreEqual("upper([umbracoNode].[path]) LIKE upper(@0)", result1);
Assert.AreEqual("-1%", modelToSqlExpressionHelper1.GetSqlParameters()[0]);
Expression<Func<IContent, bool>> predicate2 = content => content.Path.StartsWith("-1,123,97");
cachedExpression.Wrap(predicate2);
var modelToSqlExpressionHelper2 = new ModelToSqlExpressionVisitor<IContent>(SqlContext.SqlSyntax, Mappers);
var result2 = modelToSqlExpressionHelper2.Visit(cachedExpression);
Assert.AreEqual("upper([umbracoNode].[path]) LIKE upper(@0)", result2);
Assert.AreEqual("-1,123,97%", modelToSqlExpressionHelper2.GetSqlParameters()[0]);
}
[Test]
public void Can_Verify_Path_StartsWith_Predicate_In_Same_Result()
{
//Arrange
Expression<Func<IContent, bool>> predicate = content => content.Path.StartsWith("-1");
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IContent>(SqlContext.SqlSyntax, new ContentMapper());
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IContent>(SqlContext.SqlSyntax, new ContentMapper());
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
Assert.AreEqual("upper([umbracoNode].[path]) LIKE upper(@0)", result);
Assert.AreEqual("-1%", modelToSqlExpressionHelper.GetSqlParameters()[0]);
}
@@ -52,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Querying
{
//Arrange
Expression<Func<IContent, bool>> predicate = content => content.ParentId == -1;
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IContent>(SqlContext.SqlSyntax, new ContentMapper());
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IContent>(SqlContext.SqlSyntax, new ContentMapper());
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
@@ -65,7 +88,7 @@ namespace Umbraco.Tests.Persistence.Querying
public void Equals_Operator_For_Value_Gets_Escaped()
{
Expression<Func<IUser, bool>> predicate = user => user.Username == "hello@world.com";
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>(SqlContext.SqlSyntax, new UserMapper());
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IUser>(SqlContext.SqlSyntax, new UserMapper());
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
@@ -79,7 +102,7 @@ namespace Umbraco.Tests.Persistence.Querying
{
var sqlSyntax = new SqlCeSyntaxProvider();
Expression<Func<IUser, bool>> predicate = user => user.Username.Equals("hello@world.com");
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>(SqlContext.SqlSyntax, new UserMapper());
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IUser>(SqlContext.SqlSyntax, new UserMapper());
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
@@ -96,7 +119,7 @@ namespace Umbraco.Tests.Persistence.Querying
var sqlContext = new SqlContext(sqlSyntax, SqlContext.PocoDataFactory, DatabaseType.MySQL);
Expression<Func<IUser, bool>> predicate = user => user.Username.Equals("mydomain\\myuser");
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>(sqlContext.SqlSyntax, new UserMapper());
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IUser>(sqlContext.SqlSyntax, new UserMapper());
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
@@ -113,7 +136,7 @@ namespace Umbraco.Tests.Persistence.Querying
var sqlContext = new SqlContext(sqlSyntax, SqlContext.PocoDataFactory, DatabaseType.MySQL);
Expression<Func<UserDto, bool>> predicate = user => user.Login.StartsWith("mydomain\\myuser");
var modelToSqlExpressionHelper = new PocoToSqlExpressionHelper<UserDto>(sqlContext);
var modelToSqlExpressionHelper = new PocoToSqlExpressionVisitor<UserDto>(sqlContext);
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Poco to Sql ExpressionHelper: \n" + result);
@@ -126,7 +149,7 @@ namespace Umbraco.Tests.Persistence.Querying
public void Sql_Replace_Mapped()
{
Expression<Func<IUser, bool>> predicate = user => user.Username.Replace("@world", "@test") == "hello@test.com";
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>(SqlContext.SqlSyntax, new UserMapper());
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IUser>(SqlContext.SqlSyntax, new UserMapper());
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
@@ -18,7 +18,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new AuditRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new AuditRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
repo.AddOrUpdate(new AuditItem(-1, "This is a System audit trail", AuditType.System, 0));
unitOfWork.Complete();
}
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Persistence.Repositories
{
TemplateRepository tr;
var ctRepository = CreateRepository(unitOfWork, out contentTypeRepository, out tr);
dtdRepository = new DataTypeDefinitionRepository(unitOfWork, CacheHelper, Logger, contentTypeRepository, Mappers);
dtdRepository = new DataTypeDefinitionRepository(unitOfWork, CacheHelper, Logger, contentTypeRepository, QueryFactory);
return ctRepository;
}
@@ -52,20 +52,20 @@ namespace Umbraco.Tests.Persistence.Repositories
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out TemplateRepository templateRepository)
{
templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, Mappers);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, templateRepository, Mappers);
var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, templateRepository, QueryFactory);
var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
/// <summary>
/// This test ensures that when property values using special database fields are saved, the actual data in the
/// object being stored is also transformed in the same way as the data being stored in the database is.
/// Before you would see that ex: a decimal value being saved as 100 or "100", would be that exact value in the
/// Before you would see that ex: a decimal value being saved as 100 or "100", would be that exact value in the
/// object, but the value saved to the database was actually 100.000000.
/// When querying the database for the value again - the value would then differ from what is in the object.
/// This caused inconsistencies between saving+publishing and simply saving and then publishing, due to the former
/// When querying the database for the value again - the value would then differ from what is in the object.
/// This caused inconsistencies between saving+publishing and simply saving and then publishing, due to the former
/// sending the non-transformed data directly on to publishing.
/// </summary>
[Test]
@@ -99,10 +99,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage", propertyTypeCollection);
contentTypeRepository.AddOrUpdate(contentType);
unitOfWork.Complete();
// Int and decimal values are passed in as strings as they would be from the backoffice UI
var textpage = MockedContent.CreateSimpleContentWithSpecialDatabaseTypes(contentType, "test@umbraco.org", -1, "100", "150", dateValue);
// Act
repository.AddOrUpdate(textpage);
unitOfWork.Complete();
@@ -110,7 +110,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Assert
Assert.That(contentType.HasIdentity, Is.True);
Assert.That(textpage.HasIdentity, Is.True);
var persistedTextpage = repository.Get(textpage.Id);
Assert.That(persistedTextpage.Name, Is.EqualTo(textpage.Name));
Assert.AreEqual(100m, persistedTextpage.GetValue(decimalPropertyAlias));
@@ -176,7 +176,6 @@ namespace Umbraco.Tests.Persistence.Repositories
// Assert
Assert.That(contentType.HasIdentity, Is.True);
Assert.That(textpage.HasIdentity, Is.True);
}
}
@@ -608,10 +607,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out contentTypeRepository);
// Act
var query = repository.Query.Where(x => x.Level == 2);
long totalRecords;
var filterQuery = new Query<IContent>(SqlSyntax, Mappers).Where(x => x.Name.Contains("Page 2"));
var filterQuery = QueryFactory.Create<IContent>().Where(x => x.Name.Contains("Page 2"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true, filterQuery);
// Assert
@@ -635,7 +634,7 @@ namespace Umbraco.Tests.Persistence.Repositories
long totalRecords;
var filterQuery = new Query<IContent>(SqlSyntax, Mappers).Where(x => x.Name.Contains("text"));
var filterQuery = QueryFactory.Create<IContent>().Where(x => x.Name.Contains("text"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true, filterQuery);
// Assert
@@ -36,29 +36,29 @@ namespace Umbraco.Tests.Persistence.Repositories
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, templateRepository, Mappers);
var repository = new ContentRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var tagRepository = new TagRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, templateRepository, QueryFactory);
var repository = new ContentRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
private ContentTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, templateRepository, Mappers);
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, templateRepository, QueryFactory);
return contentTypeRepository;
}
private MediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork unitOfWork)
{
var contentTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers);
var contentTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory);
return contentTypeRepository;
}
private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork, Guid containerEntityType)
{
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers, containerEntityType);
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory, containerEntityType);
}
//TODO Add test to verify SetDefaultTemplates updates both AllowedTemplates and DefaultTemplate(id).
@@ -71,7 +71,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var templateRepo = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var templateRepo = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var repository = CreateRepository(unitOfWork);
var templates = new[]
{
@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork)
{
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers, Constants.ObjectTypes.DataTypeContainerGuid);
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory, Constants.ObjectTypes.DataTypeContainerGuid);
}
[TestCase("UmbracoPreVal87-21,3,48", 3, true)]
@@ -309,7 +309,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<IDataTypeDefinition>(SqlSyntax, Mappers).Where(x => x.PropertyEditorAlias == Constants.PropertyEditors.RadioButtonListAlias);
var query = QueryFactory.Create<IDataTypeDefinition>().Where(x => x.PropertyEditorAlias == Constants.PropertyEditors.RadioButtonListAlias);
var result = repository.GetByQuery(query);
// Assert
@@ -329,7 +329,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<IDataTypeDefinition>(SqlSyntax, Mappers).Where(x => x.Name.StartsWith("D"));
var query = QueryFactory.Create<IDataTypeDefinition>().Where(x => x.Name.StartsWith("D"));
int count = repository.Count(query);
// Assert
@@ -205,7 +205,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<IDictionaryItem>(SqlSyntax, Mappers).Where(x => x.ItemKey == "Article");
var query = QueryFactory.Create<IDictionaryItem>().Where(x => x.ItemKey == "Article");
var result = repository.GetByQuery(query);
// Assert
@@ -225,7 +225,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<IDictionaryItem>(SqlSyntax, Mappers).Where(x => x.ItemKey.StartsWith("Read"));
var query = QueryFactory.Create<IDictionaryItem>().Where(x => x.ItemKey.StartsWith("Read"));
var result = repository.Count(query);
// Assert
@@ -19,12 +19,12 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private DomainRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out ContentRepository contentRepository, out LanguageRepository languageRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, Mappers);
contentTypeRepository = new ContentTypeRepository(unitOfWork, DisabledCache, Logger, templateRepository, Mappers);
contentRepository = new ContentRepository(unitOfWork, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
languageRepository = new LanguageRepository(unitOfWork, DisabledCache, Logger, Mappers);
var domainRepository = new DomainRepository(unitOfWork, DisabledCache, Logger, Mappers);
var templateRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
contentTypeRepository = new ContentTypeRepository(unitOfWork, DisabledCache, Logger, templateRepository, QueryFactory);
contentRepository = new ContentRepository(unitOfWork, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
languageRepository = new LanguageRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
var domainRepository = new DomainRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
return domainRepository;
}
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private LanguageRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
return new LanguageRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
return new LanguageRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
}
@@ -175,7 +175,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<ILanguage>(SqlSyntax, Mappers).Where(x => x.IsoCode == "da-DK");
var query = QueryFactory.Create<ILanguage>().Where(x => x.IsoCode == "da-DK");
var result = repository.GetByQuery(query);
// Assert
@@ -195,7 +195,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<ILanguage>(SqlSyntax, Mappers).Where(x => x.IsoCode.StartsWith("D"));
var query = QueryFactory.Create<ILanguage>().Where(x => x.IsoCode.StartsWith("D"));
int count = repository.Count(query);
// Assert
@@ -33,7 +33,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = new Macro("test1", "Test", "~/usercontrol/blah.ascx", "MyAssembly", "test.xslt", "~/views/macropartials/test.cshtml");
repository.AddOrUpdate(macro);
@@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = repository.Get(1);
macro.Alias = "test2";
@@ -67,7 +67,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Assert
Assert.That(repository, Is.Not.Null);
@@ -81,7 +81,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var macro = repository.Get(1);
@@ -112,7 +112,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var macros = repository.GetAll();
@@ -130,10 +130,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var query = new Query<IMacro>(SqlSyntax, Mappers).Where(x => x.Alias.ToUpper() == "TEST1");
var query = QueryFactory.Create<IMacro>().Where(x => x.Alias.ToUpper() == "TEST1");
var result = repository.GetByQuery(query);
// Assert
@@ -148,10 +148,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var query = new Query<IMacro>(SqlSyntax, Mappers).Where(x => x.Name.StartsWith("Test"));
var query = QueryFactory.Create<IMacro>().Where(x => x.Name.StartsWith("Test"));
int count = repository.Count(query);
// Assert
@@ -166,7 +166,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var macro = new Macro("test", "Test", "~/usercontrol/blah.ascx", "MyAssembly", "test.xslt", "~/views/macropartials/test.cshtml");
@@ -188,7 +188,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var macro = repository.Get(2);
@@ -230,7 +230,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var macro = repository.Get(3);
@@ -252,7 +252,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
// Act
var exists = repository.Exists(3);
@@ -271,7 +271,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = repository.Get(1);
macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test"));
@@ -299,7 +299,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = new Macro("newmacro", "A new macro", "~/usercontrol/test1.ascx", "MyAssembly1", "test1.xslt", "~/views/macropartials/test1.cshtml");
macro.Properties.Add(new MacroProperty("blah1", "New1", 4, "test.editor"));
@@ -325,7 +325,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = new Macro("newmacro", "A new macro", "~/usercontrol/test1.ascx", "MyAssembly1", "test1.xslt", "~/views/macropartials/test1.cshtml");
macro.Properties.Add(new MacroProperty("blah1", "New1", 4, "test.editor"));
@@ -351,7 +351,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = new Macro("newmacro", "A new macro", "~/usercontrol/test1.ascx", "MyAssembly1", "test1.xslt", "~/views/macropartials/test1.cshtml");
var prop1 = new MacroProperty("blah1", "New1", 4, "test.editor");
@@ -383,7 +383,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = repository.Get(1);
macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test"));
@@ -412,7 +412,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var macro = repository.Get(1);
macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test"));
@@ -442,7 +442,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
repository.AddOrUpdate(new Macro("test1", "Test1", "~/usercontrol/test1.ascx", "MyAssembly1", "test1.xslt", "~/views/macropartials/test1.cshtml"));
repository.AddOrUpdate(new Macro("test2", "Test2", "~/usercontrol/test2.ascx", "MyAssembly2", "test2.xslt", "~/views/macropartials/test2.cshtml"));
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Moq;
@@ -30,9 +31,9 @@ namespace Umbraco.Tests.Persistence.Repositories
private MediaRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository)
{
mediaTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper, Logger, Mappers);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repository = new MediaRepository(unitOfWork, CacheHelper, Logger, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
mediaTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var repository = new MediaRepository(unitOfWork, CacheHelper, Logger, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
@@ -231,7 +232,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var result = repository.GetByQuery(query);
// Assert
@@ -250,7 +251,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true);
@@ -272,7 +273,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 1, 1, out totalRecords, "SortOrder", Direction.Ascending, true);
@@ -294,7 +295,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "SortOrder", Direction.Ascending, true);
@@ -316,7 +317,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Descending, true);
@@ -338,7 +339,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true);
@@ -360,10 +361,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var filter = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Name.Contains("File"));
var filter = QueryFactory.Create<IMedia>().Where(x => x.Name.Contains("File"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true,
filter);
@@ -385,10 +386,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == 2);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var filter = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Name.Contains("Test"));
var filter = QueryFactory.Create<IMedia>().Where(x => x.Name.Contains("Test"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true,
filter);
@@ -473,7 +474,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
int level = 2;
var query = new Query<IMedia>(SqlSyntax, Mappers).Where(x => x.Level == level);
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == level);
var result = repository.Count(query);
// Assert
@@ -22,12 +22,12 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private MediaTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
return new MediaTypeRepository(unitOfWork, DisabledCache, Logger, Mappers);
return new MediaTypeRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
}
private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork)
{
return new EntityContainerRepository(unitOfWork, DisabledCache, Logger, Mappers, Constants.ObjectTypes.MediaTypeContainerGuid);
return new EntityContainerRepository(unitOfWork, DisabledCache, Logger, QueryFactory, Constants.ObjectTypes.MediaTypeContainerGuid);
}
@@ -26,10 +26,10 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private MemberRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out MemberTypeRepository memberTypeRepository, out MemberGroupRepository memberGroupRepository)
{
memberTypeRepository = new MemberTypeRepository(unitOfWork, DisabledCache, Logger, Mappers);
memberGroupRepository = new MemberGroupRepository(unitOfWork, DisabledCache, Logger, Mappers);
var tagRepo = new TagRepository(unitOfWork, DisabledCache, Logger, Mappers);
var repository = new MemberRepository(unitOfWork, DisabledCache, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of<IContentSection>(), Mappers);
memberTypeRepository = new MemberTypeRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
memberGroupRepository = new MemberGroupRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
var tagRepo = new TagRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
var repository = new MemberRepository(unitOfWork, DisabledCache, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
@@ -115,7 +115,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var member = CreateTestMember(key: key);
// Act
var query = new Query<IMember>(SqlSyntax, Mappers).Where(x => x.Key == key);
var query = QueryFactory.Create<IMember>().Where(x => x.Key == key);
var result = repository.GetByQuery(query);
// Assert
@@ -248,7 +248,7 @@ namespace Umbraco.Tests.Persistence.Repositories
[Test]
public void Can_Create_Correct_Subquery()
{
var query = new Query<IMember>(SqlSyntax, Mappers).Where(x =>
var query = QueryFactory.Create<IMember>().Where(x =>
((Member) x).LongStringPropertyValue.Contains("1095") &&
((Member) x).PropertyTypeAlias == "headshot");
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private MemberTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
return new MemberTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
return new MemberTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
}
[Test]
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -58,7 +58,7 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var unitOfWork = provider.CreateUnitOfWork())
{
unitOfWork.Database.EnableSqlTrace = true;
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -98,7 +98,7 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var unitOfWork = provider.CreateUnitOfWork())
{
unitOfWork.Database.EnableSqlTrace = true;
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -143,7 +143,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -181,7 +181,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -209,7 +209,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry1 = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -247,7 +247,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var entry1 = new PublicAccessEntry(content[0], content[1], content[2], new[]
{
@@ -279,10 +279,10 @@ namespace Umbraco.Tests.Persistence.Repositories
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, Mappers);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, templateRepository, Mappers);
var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, templateRepository, QueryFactory);
var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
@@ -186,7 +186,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private IRedirectUrlRepository CreateRepository(IDatabaseUnitOfWork uow)
{
return new RedirectUrlRepository(uow, CacheHelper, Logger, Mappers);
return new RedirectUrlRepository(uow, CacheHelper, Logger, QueryFactory);
}
private IContent _textpage, _subpage, _otherpage, _trashed;
@@ -30,8 +30,8 @@ namespace Umbraco.Tests.Persistence.Repositories
private RelationRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out RelationTypeRepository relationTypeRepository)
{
relationTypeRepository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new RelationRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), relationTypeRepository, Mappers);
relationTypeRepository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var repository = new RelationRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), relationTypeRepository, QueryFactory);
return repository;
}
@@ -199,7 +199,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out repositoryType);
// Act
var query = new Query<IRelation>(SqlSyntax, Mappers).Where(x => x.ParentId == NodeDto.NodeIdSeed + 1);
var query = QueryFactory.Create<IRelation>().Where(x => x.ParentId == NodeDto.NodeIdSeed + 1);
int count = repository.Count(query);
// Assert
@@ -218,7 +218,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out repositoryType);
// Act
var query = new Query<IRelation>(SqlSyntax, Mappers).Where(x => x.RelationTypeId == RelationTypeDto.NodeIdSeed);
var query = QueryFactory.Create<IRelation>().Where(x => x.RelationTypeId == RelationTypeDto.NodeIdSeed);
var relations = repository.GetByQuery(query);
// Assert
@@ -266,8 +266,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var relationTypeRepository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var relationRepository = new RelationRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), relationTypeRepository, Mappers);
var relationTypeRepository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var relationRepository = new RelationRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), relationTypeRepository, QueryFactory);
relationTypeRepository.AddOrUpdate(relateContent);
relationTypeRepository.AddOrUpdate(relateContentType);
@@ -29,7 +29,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private RelationTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
return new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
return new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
}
@@ -192,7 +192,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = new Query<IRelationType>(SqlSyntax, Mappers).Where(x => x.Alias.StartsWith("relate"));
var query = QueryFactory.Create<IRelationType>().Where(x => x.Alias.StartsWith("relate"));
int count = repository.Count(query);
// Assert
@@ -211,7 +211,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var childObjType = new Guid(Constants.ObjectTypes.DocumentType);
var query = new Query<IRelationType>(SqlSyntax, Mappers).Where(x => x.ChildObjectType == childObjType);
var query = QueryFactory.Create<IRelationType>().Where(x => x.ChildObjectType == childObjType);
var result = repository.GetByQuery(query);
// Assert
@@ -236,7 +236,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new RelationTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
repository.AddOrUpdate(relateContent);//Id 2
repository.AddOrUpdate(relateContentType);//Id 3
@@ -31,7 +31,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private ServerRegistrationRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
return new ServerRegistrationRepository(unitOfWork, _cacheHelper, Logger, Mappers);
return new ServerRegistrationRepository(unitOfWork, _cacheHelper, Logger, QueryFactory);
}
[Test]
@@ -23,7 +23,7 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private TagRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, Mappers);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
return tagRepository;
}
@@ -993,18 +993,18 @@ namespace Umbraco.Tests.Persistence.Repositories
private ContentRepository CreateContentRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, Mappers);
contentTypeRepository = new ContentTypeRepository(unitOfWork, DisabledCache, Logger, templateRepository, Mappers);
var repository = new ContentRepository(unitOfWork, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
var templateRepository = new TemplateRepository(unitOfWork, DisabledCache, Logger, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>(), QueryFactory);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
contentTypeRepository = new ContentTypeRepository(unitOfWork, DisabledCache, Logger, templateRepository, QueryFactory);
var repository = new ContentRepository(unitOfWork, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
private MediaRepository CreateMediaRepository(IDatabaseUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository)
{
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, Mappers);
mediaTypeRepository = new MediaTypeRepository(unitOfWork, DisabledCache, Logger, Mappers);
var repository = new MediaRepository(unitOfWork, DisabledCache, Logger, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
mediaTypeRepository = new MediaTypeRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
var repository = new MediaRepository(unitOfWork, DisabledCache, Logger, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
return repository;
}
}
@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var created = DateTime.Now;
var task = new Task(new TaskType("asdfasdf"))
@@ -47,7 +47,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var created = DateTime.Now;
repo.AddOrUpdate(new Task(new TaskType("asdfasdf"))
@@ -80,7 +80,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var task = new Task(new TaskType("asdfasdf"))
{
@@ -117,7 +117,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var task = new Task(new TaskType("asdfasdf"))
{
@@ -146,7 +146,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var found = repo.GetAll().ToArray();
Assert.AreEqual(20, found.Count());
@@ -162,7 +162,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var found = repo.GetTasks(includeClosed: true).ToArray();
Assert.AreEqual(15, found.Count());
@@ -178,7 +178,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var found = repo.GetTasks(itemId:-20).ToArray();
Assert.AreEqual(10, found.Count());
@@ -194,7 +194,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var found = repo.GetTasks(includeClosed: false);
Assert.AreEqual(10, found.Count());
@@ -206,7 +206,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
for (int i = 0; i < count; i++)
{
@@ -19,8 +19,8 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var unitOfWork = provider.CreateUnitOfWork())
{
var taskType = new TaskType("asdfasdf");
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, Mappers);
var taskTypeRepo = new TaskTypeRepository(unitOfWork, CacheHelper, Logger, Mappers);
var repo = new TaskRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var taskTypeRepo = new TaskTypeRepository(unitOfWork, CacheHelper, Logger, QueryFactory);
var created = DateTime.Now;
var task = new Task(taskType)
@@ -31,7 +31,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private ITemplateRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, ITemplatesSection templatesSection = null)
{
return new TemplateRepository(unitOfWork, DisabledCache, Logger, _masterPageFileSystem, _viewsFileSystem,
templatesSection ?? Mock.Of<ITemplatesSection>(t => t.DefaultRenderingEngine == RenderingEngine.Mvc), Mappers);
templatesSection ?? Mock.Of<ITemplatesSection>(t => t.DefaultRenderingEngine == RenderingEngine.Mvc), QueryFactory);
}
public override void SetUp()
@@ -406,9 +406,9 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var templateRepository = CreateRepository(unitOfWork);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, Mappers);
var contentTypeRepository = new ContentTypeRepository(unitOfWork, DisabledCache, Logger, templateRepository, Mappers);
var contentRepo = new ContentRepository(unitOfWork, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), Mappers);
var tagRepository = new TagRepository(unitOfWork, DisabledCache, Logger, QueryFactory);
var contentTypeRepository = new ContentTypeRepository(unitOfWork, DisabledCache, Logger, templateRepository, QueryFactory);
var contentRepo = new ContentRepository(unitOfWork, DisabledCache, Logger, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>(), QueryFactory);
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");
var textpage = MockedContent.CreateSimpleContent(contentType);
@@ -23,8 +23,8 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private UserRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out UserTypeRepository userTypeRepository)
{
userTypeRepository = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), userTypeRepository, Mappers);
userTypeRepository = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), userTypeRepository, QueryFactory);
return repository;
}
@@ -166,8 +166,8 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Flush();
var id = user.Id;
var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers);
var repository2 = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo, Mappers);
var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory);
var repository2 = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo, QueryFactory);
repository2.Delete(user);
unitOfWork.Flush();
@@ -244,7 +244,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateAndCommitMultipleUsers(repository, unitOfWork);
// Act
var query = new Query<IUser>(SqlSyntax, Mappers).Where(x => x.Username == "TestUser1");
var query = QueryFactory.Create<IUser>().Where(x => x.Username == "TestUser1");
var result = repository.GetByQuery(query);
// Assert
@@ -329,7 +329,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var users = CreateAndCommitMultipleUsers(repository, unitOfWork);
// Act
var query = new Query<IUser>(SqlSyntax, Mappers).Where(x => x.Username == "TestUser1" || x.Username == "TestUser2");
var query = QueryFactory.Create<IUser>().Where(x => x.Username == "TestUser1" || x.Username == "TestUser2");
var result = repository.Count(query);
// Assert
@@ -484,8 +484,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo, Mappers);
var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo, QueryFactory);
// Act
var user1 = MockedUser.CreateUser(CreateAndCommitUserType(), "1", "test", "media");
@@ -535,7 +535,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
var repository = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers);
var repository = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory);
var userType = MockedUserType.CreateUserType();
repository.AddOrUpdate(userType);
unitOfWork.Complete();
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.Persistence.Repositories
{
private UserTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
{
return new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), Mappers);
return new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), QueryFactory);
}
[Test]
@@ -134,7 +134,7 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Flush();
var id = userType.Id;
var repository2 = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, Mappers);
var repository2 = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, QueryFactory);
repository2.Delete(userType);
unitOfWork.Flush();
@@ -183,7 +183,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateAndCommitMultipleUserTypes(repository, unitOfWork);
// Act
var query = new Query<IUserType>(SqlSyntax, Mappers).Where(x => x.Alias == "testUserType1");
var query = QueryFactory.Create<IUserType>().Where(x => x.Alias == "testUserType1");
var result = repository.GetByQuery(query);
// Assert
@@ -264,7 +264,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var userTypes = CreateAndCommitMultipleUserTypes(repository, unitOfWork);
// Act
var query = new Query<IUserType>(SqlSyntax, Mappers).Where(x => x.Alias == "testUserType1" || x.Alias == "testUserType2");
var query = QueryFactory.Create<IUserType>().Where(x => x.Alias == "testUserType1" || x.Alias == "testUserType2");
var result = repository.Count(query);
// Assert

Some files were not shown because too many files have changed in this diff Show More