Persistence reorg

This commit is contained in:
Stephan
2016-12-16 14:18:37 +01:00
parent 467f71e392
commit 49d54f497d
113 changed files with 622 additions and 641 deletions

View File

@@ -148,7 +148,7 @@ namespace Umbraco.Core
{
try
{
var dbfactory = container.GetInstance<IDatabaseFactory>();
var dbfactory = container.GetInstance<IUmbracoDatabaseFactory>();
SetRuntimeStateLevel(_state, dbfactory, Logger);
Logger.Debug<CoreRuntime>($"Runtime level: {_state.Level}");
}
@@ -225,14 +225,11 @@ namespace Umbraco.Core
// will be initialized with syntax providers and a logger, and will try to configure
// from the default connection string name, if possible, else will remain non-configured
// until the database context configures it properly (eg when installing)
container.RegisterSingleton<IDatabaseFactory, UmbracoDatabaseFactory>();
container.RegisterSingleton<IUmbracoDatabaseFactory, UmbracoDatabaseFactory>();
// register database context
container.RegisterSingleton<DatabaseContext>();
// register query factory - fixme kill
container.RegisterSingleton(f => f.GetInstance<IDatabaseFactory>().QueryFactory);
// register a database accessor - required by database factory
// will be replaced by HybridUmbracoDatabaseAccessor in the web runtime
// fixme - we should NOT be using thread static at all + will NOT get replaced = wtf?
@@ -247,7 +244,7 @@ namespace Umbraco.Core
builder.AddCore();
}
private void SetRuntimeStateLevel(RuntimeState runtimeState, IDatabaseFactory databaseFactory, ILogger logger)
private void SetRuntimeStateLevel(RuntimeState runtimeState, IUmbracoDatabaseFactory databaseFactory, ILogger logger)
{
var localVersion = LocalVersion; // the local, files, version
var codeVersion = runtimeState.SemanticVersion; // the executing code version
@@ -340,14 +337,12 @@ namespace Umbraco.Core
runtimeState.Level = RuntimeLevel.Upgrade;
}
protected virtual bool EnsureMigration(IDatabaseFactory databaseFactory, SemVersion codeVersion)
protected virtual bool EnsureMigration(IUmbracoDatabaseFactory databaseFactory, SemVersion codeVersion)
{
var uf = databaseFactory as UmbracoDatabaseFactory; // fixme
if (uf == null) throw new Exception("oops: db.");
using (var database = uf.CreateDatabase()) // no scope - just the database
using (var database = databaseFactory.CreateDatabase()) // no scope - just the database
{
var codeVersionString = codeVersion.ToString();
var sql = database.Sql()
var sql = databaseFactory.Sql()
.Select<MigrationDto>()
.From<MigrationDto>()
.Where<MigrationDto>(x => x.Name.InvariantEquals(GlobalSettings.UmbracoMigrationName) && x.Version == codeVersionString);

View File

@@ -22,14 +22,14 @@ namespace Umbraco.Core
/// </summary>
public class DatabaseBuilder
{
private readonly IDatabaseFactory _databaseFactory;
private readonly IUmbracoDatabaseFactory _databaseFactory;
private readonly IRuntimeState _runtime;
private readonly IMigrationEntryService _migrationEntryService;
private readonly ILogger _logger;
private DatabaseSchemaResult _databaseSchemaValidationResult;
public DatabaseBuilder(IDatabaseFactory databaseFactory, IRuntimeState runtime, IMigrationEntryService migrationEntryService, ILogger logger)
public DatabaseBuilder(IUmbracoDatabaseFactory databaseFactory, IRuntimeState runtime, IMigrationEntryService migrationEntryService, ILogger logger)
{
_databaseFactory = databaseFactory;
_runtime = runtime;
@@ -37,7 +37,7 @@ namespace Umbraco.Core
_logger = logger;
}
public UmbracoDatabase Database => _databaseFactory.GetDatabase();
public IUmbracoDatabase Database => _databaseFactory.GetDatabase();
public ISqlSyntaxProvider SqlSyntax => _databaseFactory.SqlSyntax;
@@ -103,7 +103,7 @@ namespace Umbraco.Core
ConfigureEmbeddedDatabaseConnection(_databaseFactory, _logger);
}
private static void ConfigureEmbeddedDatabaseConnection(IDatabaseFactory factory, ILogger logger)
private static void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, ILogger logger)
{
SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe, logger);
@@ -329,7 +329,7 @@ namespace Umbraco.Core
#region Utils
internal static void GiveLegacyAChance(IDatabaseFactory factory, ILogger logger)
internal static void GiveLegacyAChance(IUmbracoDatabaseFactory factory, ILogger logger)
{
// look for the legacy appSettings key
var legacyConnString = ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName];

View File

@@ -17,7 +17,7 @@ namespace Umbraco.Core
/// </remarks>
public class DatabaseContext
{
private readonly IDatabaseFactory _databaseFactory;
private readonly IUmbracoDatabaseFactory _databaseFactory;
/// <summary>
/// Initializes a new instance of the <see cref="DatabaseContext"/> class.
@@ -27,21 +27,13 @@ namespace Umbraco.Core
/// Umbraco connection string is not available because we are installing. In which case this
/// database builder must sort things out and configure the database factory before it can be
/// used.</remarks>
public DatabaseContext(IDatabaseFactory databaseFactory)
public DatabaseContext(IUmbracoDatabaseFactory databaseFactory)
{
if (databaseFactory == null) throw new ArgumentNullException(nameof(databaseFactory));
_databaseFactory = databaseFactory;
}
// in most cases, this should not be used, keeping it here for compatibility (temp)
// todo: get rid of it
/// <summary>
/// Gets the query factory.
/// </summary>
/// <remarks>In most cases this should not be used, better use Query{T}.</remarks>
public IQueryFactory QueryFactory => _databaseFactory.QueryFactory;
/// <summary>
/// Gets the database Sql syntax.
/// </summary>
@@ -55,18 +47,18 @@ namespace Umbraco.Core
/// <summary>
/// Creates a Sql statement.
/// </summary>
public Sql<SqlContext> Sql(string sql, params object[] args) => Sql().Append(sql, args);
public Sql<SqlContext> Sql(string sql, params object[] args) => _databaseFactory.Sql(sql, args);
/// <summary>
/// Creates a Query expression.
/// </summary>
public IQuery<T> Query<T>() => _databaseFactory.QueryFactory.Create<T>();
public IQuery<T> Query<T>() => _databaseFactory.Query<T>();
/// <summary>
/// Gets an ambient database for doing CRUD operations against custom tables that resides in the Umbraco database.
/// </summary>
/// <remarks>Should not be used for operation against standard Umbraco tables; as services should be used instead.</remarks>
public UmbracoDatabase Database => _databaseFactory.GetDatabase();
public IUmbracoDatabase Database => _databaseFactory.GetDatabase();
/// <summary>
/// Gets an ambient database scope.
@@ -74,9 +66,7 @@ namespace Umbraco.Core
/// <returns>A disposable object representing the scope.</returns>
public IDisposable CreateDatabaseScope() // fixme - move over to factory
{
var factory = _databaseFactory as UmbracoDatabaseFactory; // fixme - though... IDatabaseFactory?
if (factory == null) throw new NotSupportedException();
return factory.CreateScope();
return _databaseFactory.CreateScope();
}
#if DEBUG_DATABASES

View File

@@ -12,11 +12,11 @@ namespace Umbraco.Core.Persistence
{
public class DatabaseSchemaHelper
{
private readonly UmbracoDatabase _database;
private readonly IUmbracoDatabase _database;
private readonly ILogger _logger;
private readonly BaseDataCreation _baseDataCreation;
public DatabaseSchemaHelper(UmbracoDatabase database, ILogger logger)
public DatabaseSchemaHelper(IUmbracoDatabase database, ILogger logger)
{
_database = database;
_logger = logger;

View File

@@ -3,19 +3,19 @@ using System.Threading;
namespace Umbraco.Core.Persistence
{
public class DatabaseScope : IDisposeOnRequestEnd // implies IDisposable
public class DatabaseScope : IDatabaseScope, IDisposeOnRequestEnd // implies IDisposable
{
private readonly DatabaseScope _parent;
private readonly IDatabaseScopeAccessor _accessor;
private readonly UmbracoDatabaseFactory _factory;
private UmbracoDatabase _database;
private readonly IUmbracoDatabaseFactory _factory;
private IUmbracoDatabase _database;
private bool _isParent;
private int _disposed;
private bool _disposeDatabase;
// can specify a database to create a "substitute" scope eg for deploy - oh my
internal DatabaseScope(IDatabaseScopeAccessor accessor, UmbracoDatabaseFactory factory, UmbracoDatabase database = null)
internal DatabaseScope(IDatabaseScopeAccessor accessor, IUmbracoDatabaseFactory factory, IUmbracoDatabase database = null)
{
_accessor = accessor;
_factory = factory;
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Persistence
_accessor.Scope = this;
}
public UmbracoDatabase Database
public IUmbracoDatabase Database
{
get
{

View File

@@ -8,7 +8,7 @@ namespace Umbraco.Core.Persistence
internal static class DatabaseNodeLockExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ValidateDatabase(UmbracoDatabase database)
private static void ValidateDatabase(IUmbracoDatabase database)
{
if (database == null)
throw new ArgumentNullException("database");
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence
// that record which will be kept until the transaction is ended, effectively locking
// out all other accesses to that record - thus obtaining an exclusive lock over the
// protected resources.
public static void AcquireLockNodeWriteLock(this UmbracoDatabase database, int nodeId)
public static void AcquireLockNodeWriteLock(this IUmbracoDatabase database, int nodeId)
{
ValidateDatabase(database);
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence
// that record which will be kept until the transaction is ended, effectively preventing
// other write accesses to that record - thus obtaining a shared lock over the protected
// resources.
public static void AcquireLockNodeReadLock(this UmbracoDatabase database, int nodeId)
public static void AcquireLockNodeReadLock(this IUmbracoDatabase database, int nodeId)
{
ValidateDatabase(database);

View File

@@ -0,0 +1,29 @@
using NPoco;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
public interface IDatabaseContext
{
/// <summary>
/// Gets the database Sql syntax.
/// </summary>
ISqlSyntaxProvider SqlSyntax { get; }
/// <summary>
/// Creates a new Sql expression.
/// </summary>
Sql<SqlContext> Sql();
/// <summary>
/// Creates a new Sql expression.
/// </summary>
Sql<SqlContext> Sql(string sql, params object[] args);
/// <summary>
/// Creates a new query expression.
/// </summary>
IQuery<T> Query<T>();
}
}

View File

@@ -1,31 +0,0 @@
using System;
using NPoco;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
/// <summary>
/// Creates and manages the "ambient" database.
/// </summary>
public interface IDatabaseFactory : IDisposable
{
/// <summary>
/// Gets (creates or retrieves) the "ambient" database connection.
/// </summary>
/// <returns>The "ambient" database connection.</returns>
UmbracoDatabase GetDatabase();
void Configure(string connectionString, string providerName);
bool Configured { get; }
bool CanConnect { get; }
IQueryFactory QueryFactory { get; }
ISqlSyntaxProvider SqlSyntax { get; }
Sql<SqlContext> Sql();
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace Umbraco.Core.Persistence
{
/// <summary>
/// Represents a database scope.
/// </summary>
public interface IDatabaseScope : IDisposable
{
IUmbracoDatabase Database { get; }
}
}

View File

@@ -0,0 +1,25 @@
using NPoco;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
public interface IUmbracoDatabase : IDatabase
{
/// <summary>
/// Gets the database Sql syntax.
/// </summary>
ISqlSyntaxProvider SqlSyntax { get; } // fixme - kill
/// <summary>
/// Gets the Sql context.
/// </summary>
SqlContext SqlContext { get; }
/// <summary>
/// Gets the database instance unique identifier as a string.
/// </summary>
/// <remarks>UmbracoDatabase returns the first eight digits of its unique Guid and, in some
/// debug mode, the underlying database connection identifier (if any).</remarks>
string InstanceId { get; }
}
}

View File

@@ -1,13 +0,0 @@
using NPoco;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
public interface IUmbracoDatabaseConfig : IDatabaseConfig
{
/// <summary>
/// The Umbraco SqlSyntax used to handle different syntaxes in the different database providers.
/// </summary>
ISqlSyntaxProvider SqlSyntax { get; }
}
}

View File

@@ -0,0 +1,57 @@
using System;
namespace Umbraco.Core.Persistence
{
/// <summary>
/// Creates and manages the "ambient" database.
/// </summary>
public interface IUmbracoDatabaseFactory : IDatabaseContext, IDisposable
{
/// <summary>
/// Gets (creates if needed) the ambient database.
/// </summary>
/// <exception cref="InvalidOperationException">There is no ambient database scope.</exception>
/// <remarks>The ambient database is the database owned by the ambient scope. It should not
/// be disposed, as the scope takes care of disposing it when appropriate.</remarks>
IUmbracoDatabase GetDatabase();
/// <summary>
/// Gets (creates if needed) the ambient database.
/// </summary>
/// <remarks>This is just a shortcut to GetDatabase.</remarks>
IUmbracoDatabase Database { get; } // fixme keep?
/// <summary>
/// Creates a new database.
/// </summary>
/// <remarks>The new database is not part of any scope and must be disposed after being used.</remarks>
IUmbracoDatabase CreateDatabase();
/// <summary>
/// Creates a new database scope.
/// </summary>
/// <param name="database">A database for the scope.</param>
/// <remarks>
/// <para>The new database scope becomes the ambient scope and may be nested under
/// an already existing ambient scope.</para>
/// <para>In most cases, <paramref name="database"/> should be null. It can be used to force the temporary
/// usage of another database instance. Use with care.</para>
/// </remarks>
IDatabaseScope CreateScope(IUmbracoDatabase database = null);
/// <summary>
/// Gets a value indicating whether the database factory is configured.
/// </summary>
bool Configured { get; }
/// <summary>
/// Gets a value indicating whether the database can connect.
/// </summary>
bool CanConnect { get; }
/// <summary>
/// Configures the database factory.
/// </summary>
void Configure(string connectionString, string providerName);
}
}

View File

@@ -0,0 +1,16 @@
using Umbraco.Core.Persistence.Migrations.Syntax.Alter;
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
namespace Umbraco.Core.Persistence.Migrations
{
public interface ILocalMigration
{
IExecuteBuilder Execute { get; }
IDeleteBuilder Delete { get; }
IAlterSyntaxBuilder Alter { get; }
ICreateBuilder Create { get; }
string GetSql();
}
}

View File

@@ -3,12 +3,14 @@ using Umbraco.Core.Logging;
namespace Umbraco.Core.Persistence.Migrations
{
public interface IMigrationContext
public interface IMigrationContext : IDatabaseContext
{
UmbracoDatabase Database { get; }
IUmbracoDatabase Database { get; }
ICollection<IMigrationExpression> Expressions { get; set; }
ILogger Logger { get; }
ILocalMigration GetLocalMigration();
}
}

View File

@@ -7,6 +7,6 @@ namespace Umbraco.Core.Persistence.Migrations
/// </summary>
public interface IMigrationExpression
{
string Process(UmbracoDatabase database);
string Process(IUmbracoDatabase database);
}
}

View File

@@ -11,10 +11,10 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
/// </summary>
internal class BaseDataCreation
{
private readonly Database _database;
private readonly IDatabase _database;
private readonly ILogger _logger;
public BaseDataCreation(Database database, ILogger logger)
public BaseDataCreation(IDatabase database, ILogger logger)
{
_database = database;
_logger = logger;

View File

@@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
internal class DatabaseSchemaCreation
{
private readonly DatabaseSchemaHelper _schemaHelper;
private readonly UmbracoDatabase _database;
private readonly IUmbracoDatabase _database;
private readonly ILogger _logger;
/// <summary>
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
/// </summary>
/// <param name="database"></param>
/// <param name="logger"></param>
public DatabaseSchemaCreation(UmbracoDatabase database, ILogger logger)
public DatabaseSchemaCreation(IUmbracoDatabase database, ILogger logger)
{
_database = database;
_logger = logger;

View File

@@ -8,9 +8,9 @@ using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
namespace Umbraco.Core.Persistence.Migrations
{
internal class LocalMigrationContext : MigrationContext
internal class LocalMigration : MigrationContext, ILocalMigration
{
public LocalMigrationContext(UmbracoDatabase database, ILogger logger)
public LocalMigration(IUmbracoDatabase database, ILogger logger)
: base(database, logger)
{ }

View File

@@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Migrations
{
public abstract class MigrationBase : IMigration
{
public ISqlSyntaxProvider SqlSyntax => Context.Database.SqlSyntax;
public ISqlSyntaxProvider SqlSyntax => Context.SqlSyntax;
public DatabaseType DatabaseType => Context.Database.DatabaseType;
@@ -44,7 +44,9 @@ namespace Umbraco.Core.Persistence.Migrations
public IUpdateBuilder Update => new UpdateBuilder(Context);
protected Sql<SqlContext> Sql() => Context.Database.Sql();
protected Sql<SqlContext> Sql() => Context.Sql();
protected Sql<SqlContext> Sql(string sql, params object[] args) => Context.Sql(sql, args);
public IIfDatabaseBuilder IfDatabase(params DatabaseType[] supportedDatabaseTypes)
{

View File

@@ -3,13 +3,14 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using NPoco;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations
{
internal class MigrationContext : IMigrationContext
{
public MigrationContext(UmbracoDatabase database, ILogger logger)
public MigrationContext(IUmbracoDatabase database, ILogger logger)
{
if (database == null) throw new ArgumentNullException(nameof(database));
if (logger == null) throw new ArgumentNullException(nameof(logger));
@@ -21,12 +22,20 @@ namespace Umbraco.Core.Persistence.Migrations
public ICollection<IMigrationExpression> Expressions { get; set; }
public UmbracoDatabase Database { get; }
public IUmbracoDatabase Database { get; }
public ISqlSyntaxProvider SqlSyntax => Database.SqlSyntax;
public Sql<SqlContext> Sql() => new Sql<SqlContext>(Database.SqlContext);
public Sql<SqlContext> Sql(string sql, params object[] args) => new Sql<SqlContext>(Database.SqlContext, sql, args);
public IQuery<T> Query<T>() => new Query<T>(Database.SqlContext);
public DatabaseType DatabaseType => Database.DatabaseType;
public ILogger Logger { get; }
public ILocalMigration GetLocalMigration() => new LocalMigration(Database, Logger);
}
}

View File

@@ -36,7 +36,7 @@ namespace Umbraco.Core.Persistence.Migrations
|| SupportedDatabaseTypes.Any(x => CurrentDatabaseType.GetType().Inherits(x.GetType()));
}
public virtual string Process(UmbracoDatabase database)
public virtual string Process(IUmbracoDatabase database)
{
return ToString();
}

View File

@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute
_context.Expressions.Add(expression);
}
public void Code(Func<UmbracoDatabase, string> codeStatement)
public void Code(Func<IUmbracoDatabase, string> codeStatement)
{
var expression = new ExecuteCodeStatementExpression(_context, _supportedDatabaseTypes) { CodeStatement = codeStatement };
_context.Expressions.Add(expression);

View File

@@ -9,9 +9,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute.Expressions
: base(context, supportedDatabaseTypes)
{ }
public virtual Func<UmbracoDatabase, string> CodeStatement { get; set; }
public virtual Func<IUmbracoDatabase, string> CodeStatement { get; set; }
public override string Process(UmbracoDatabase database)
public override string Process(IUmbracoDatabase database)
{
if(CodeStatement != null)
return CodeStatement(database);

View File

@@ -1,11 +1,10 @@
using System;
using NPoco;
namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute
{
public interface IExecuteBuilder : IFluentSyntax
{
void Sql(string sqlStatement);
void Code(Func<UmbracoDatabase, string> codeStatement);
void Code(Func<IUmbracoDatabase, string> codeStatement);
}
}

View File

@@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions
public virtual string OldName { get; set; }
public virtual string NewName { get; set; }
public override string Process(UmbracoDatabase database)
public override string Process(IUmbracoDatabase database)
{
if (CurrentDatabaseType.IsMySql())
{

View File

@@ -16,10 +16,10 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight
Execute.Code(MigrationCode);
}
private string MigrationCode(UmbracoDatabase database)
private string MigrationCode(IUmbracoDatabase database)
{
var umbracoRedirectUrlTableName = "umbracoRedirectUrl";
var localContext = new LocalMigrationContext(database, Logger);
var local = Context.GetLocalMigration();
var tables = SqlSyntax.GetTablesInSchema(database).ToArray();
@@ -28,17 +28,17 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight
var columns = SqlSyntax.GetColumnsInSchema(database).ToArray();
if (columns.Any(x => x.TableName.InvariantEquals(umbracoRedirectUrlTableName) && x.ColumnName.InvariantEquals("id") && x.DataType == "uniqueidentifier"))
return null;
localContext.Delete.Table(umbracoRedirectUrlTableName);
local.Delete.Table(umbracoRedirectUrlTableName);
}
localContext.Create.Table(umbracoRedirectUrlTableName)
local.Create.Table(umbracoRedirectUrlTableName)
.WithColumn("id").AsGuid().NotNullable().PrimaryKey("PK_" + umbracoRedirectUrlTableName)
.WithColumn("createDateUtc").AsDateTime().NotNullable()
.WithColumn("url").AsString(2048).NotNullable()
.WithColumn("contentKey").AsGuid().NotNullable()
.WithColumn("urlHash").AsString(40).NotNullable();
localContext.Create.Index("IX_" + umbracoRedirectUrlTableName).OnTable(umbracoRedirectUrlTableName)
local.Create.Index("IX_" + umbracoRedirectUrlTableName).OnTable(umbracoRedirectUrlTableName)
.OnColumn("urlHash")
.Ascending()
.OnColumn("contentKey")
@@ -47,11 +47,11 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight
.Descending()
.WithOptions().NonClustered();
localContext.Create.ForeignKey("FK_" + umbracoRedirectUrlTableName)
local.Create.ForeignKey("FK_" + umbracoRedirectUrlTableName)
.FromTable(umbracoRedirectUrlTableName).ForeignColumn("contentKey")
.ToTable("umbracoNode").PrimaryColumn("uniqueID");
return localContext.GetSql();
return local.GetSql();
}
public override void Down()

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
//If we are on SQLServer, we need to delete default constraints by name, older versions of umbraco did not name these default constraints
// consistently so we need to look up the constraint name to delete, this only pertains to SQL Server and this issue:
// http://issues.umbraco.org/issue/U4-4133
var sqlServerSyntaxProvider = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null));
var sqlServerSyntaxProvider = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null));
var defaultConstraints = sqlServerSyntaxProvider.GetDefaultConstraintsPerColumn(Context.Database).Distinct();
//lookup the constraint we want to delete, normally would be called "DF_cmsMacroProperty_macroPropertyHidden" but

View File

@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
Execute.Code(UpdateRelatedLinksDataDo);
}
public string UpdateRelatedLinksDataDo(Database database)
public string UpdateRelatedLinksDataDo(IDatabase database)
{
if (database != null)
{
@@ -133,7 +133,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
throw new DataLossException("Cannot downgrade from a version 7 database to a prior version, the database schema has already been modified");
}
private static void UpdateXmlTable(List<PropertyTypeDto> propertyTypes, dynamic data, List<ContentXmlDto> cmsContentXmlEntries, Database database)
private static void UpdateXmlTable(List<PropertyTypeDto> propertyTypes, dynamic data, List<ContentXmlDto> cmsContentXmlEntries, IDatabase database)
{
//now we need to update the cmsContentXml table
var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.propertytypeid);

View File

@@ -23,32 +23,31 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZer
Execute.Code(MigrationCode);
}
private string MigrationCode(UmbracoDatabase database)
private string MigrationCode(IUmbracoDatabase database)
{
var localContext = new LocalMigrationContext(database, Logger);
var local = Context.GetLocalMigration();
//Clear all stylesheet data if the tables exist
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
if (tables.InvariantContains("cmsStylesheetProperty"))
{
localContext.Delete.FromTable("cmsStylesheetProperty").AllRows();
localContext.Delete.FromTable("umbracoNode").Row(new { nodeObjectType = new Guid(Constants.ObjectTypes.StylesheetProperty) });
local.Delete.FromTable("cmsStylesheetProperty").AllRows();
local.Delete.FromTable("umbracoNode").Row(new { nodeObjectType = new Guid(Constants.ObjectTypes.StylesheetProperty) });
localContext.Delete.Table("cmsStylesheetProperty");
local.Delete.Table("cmsStylesheetProperty");
}
if (tables.InvariantContains("cmsStylesheet"))
{
localContext.Delete.FromTable("cmsStylesheet").AllRows();
localContext.Delete.FromTable("umbracoNode").Row(new { nodeObjectType = new Guid(Constants.ObjectTypes.Stylesheet) });
local.Delete.FromTable("cmsStylesheet").AllRows();
local.Delete.FromTable("umbracoNode").Row(new { nodeObjectType = new Guid(Constants.ObjectTypes.Stylesheet) });
localContext.Delete.Table("cmsStylesheet");
local.Delete.Table("cmsStylesheet");
}
return localContext.GetSql();
return local.GetSql();
}
public override void Down()
{
}
{ }
}
}

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZer
var delPropQry = SqlSyntax.GetDeleteSubquery(
"cmsPropertyData",
"id",
Context.Database.Sql("SELECT MIN(id) FROM cmsPropertyData GROUP BY contentNodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL"),
Sql("SELECT MIN(id) FROM cmsPropertyData GROUP BY contentNodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL"),
WhereInType.NotIn);
Execute.Sql(delPropQry.SQL);
}

View File

@@ -39,7 +39,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer
}
}
private static string UpdateGuids(Database database)
private static string UpdateGuids(IDatabase database)
{
var updates = new List<Tuple<Guid, int>>();

View File

@@ -28,7 +28,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer
Constants.ObjectTypes.MemberTypeGuid,
};
var sql = Context.Database.Sql()
var sql = Context.Sql()
.Select("umbracoNode.id,cmsContentType.alias,umbracoNode.nodeObjectType")
.From<NodeDto>()
.InnerJoin<ContentTypeDto>()

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
Execute.Code(UndoChangeDocumentTypePermissionDo);
}
private static string AddChangeDocumentTypePermissionDo(Database database)
private static string AddChangeDocumentTypePermissionDo(IDatabase database)
{
var adminUserType = database.Fetch<UserTypeDto>("WHERE Id = 1").FirstOrDefault();
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
return string.Empty;
}
private static string UndoChangeDocumentTypePermissionDo(Database database)
private static string UndoChangeDocumentTypePermissionDo(IDatabase database)
{
var adminUserType = database.Fetch<UserTypeDto>("WHERE Id = 1").FirstOrDefault();

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
Execute.Code(Update);
}
internal string Update(Database database)
internal string Update(IDatabase database)
{
if (database != null)
{

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
}
public static string UpdatePropertyTypesAndGroupsDo(Database database)
public static string UpdatePropertyTypesAndGroupsDo(IDatabase database)
{
if (database != null)
{

View File

@@ -73,7 +73,7 @@ namespace Umbraco.Core.Persistence
/// <para>Note that with proper transactions, if T2 begins after T1 then we are sure that the database will contain T2's value
/// once T1 and T2 have completed. Whereas here, it could contain T1's value.</para>
/// </remarks>
internal static RecordPersistenceType InsertOrUpdate<T>(this IDatabase db, T poco)
internal static RecordPersistenceType InsertOrUpdate<T>(this IUmbracoDatabase db, T poco)
where T : class
{
return db.InsertOrUpdate(poco, null, null);
@@ -96,7 +96,7 @@ namespace Umbraco.Core.Persistence
/// <para>Note that with proper transactions, if T2 begins after T1 then we are sure that the database will contain T2's value
/// once T1 and T2 have completed. Whereas here, it could contain T1's value.</para>
/// </remarks>
internal static RecordPersistenceType InsertOrUpdate<T>(this IDatabase db,
internal static RecordPersistenceType InsertOrUpdate<T>(this IUmbracoDatabase db,
T poco,
string updateCommand,
object updateArgs)
@@ -168,7 +168,7 @@ namespace Umbraco.Core.Persistence
/// <param name="database">The database.</param>
/// <param name="records">The records.</param>
/// <param name="useNativeBulkInsert">Whether to use native bulk insert when available.</param>
public static void BulkInsertRecordsWithTransaction<T>(this Database database, IEnumerable<T> records, bool useNativeBulkInsert = true)
public static void BulkInsertRecordsWithTransaction<T>(this IUmbracoDatabase database, IEnumerable<T> records, bool useNativeBulkInsert = true)
{
var recordsA = records.ToArray();
if (recordsA.Length == 0)
@@ -190,7 +190,7 @@ namespace Umbraco.Core.Persistence
/// <param name="records">The records.</param>
/// <param name="useNativeBulkInsert">Whether to use native bulk insert when available.</param>
/// <returns>The number of records that were inserted.</returns>
public static int BulkInsertRecords<T>(this Database database, IEnumerable<T> records, bool useNativeBulkInsert = true)
public static int BulkInsertRecords<T>(this IUmbracoDatabase database, IEnumerable<T> records, bool useNativeBulkInsert = true)
{
var recordsA = records.ToArray();
if (recordsA.Length == 0) return 0;
@@ -227,7 +227,7 @@ namespace Umbraco.Core.Persistence
/// <param name="database">The database.</param>
/// <param name="records">The records.</param>
/// <returns>The number of records that were inserted.</returns>
private static int BulkInsertRecordsWithCommands<T>(Database database, T[] records)
private static int BulkInsertRecordsWithCommands<T>(IUmbracoDatabase database, T[] records)
{
foreach (var command in database.GenerateBulkInsertCommands(records))
command.ExecuteNonQuery();
@@ -242,7 +242,7 @@ namespace Umbraco.Core.Persistence
/// <param name="database">The database.</param>
/// <param name="records">The records.</param>
/// <returns>The sql commands to execute.</returns>
internal static IDbCommand[] GenerateBulkInsertCommands<T>(this Database database, T[] records)
internal static IDbCommand[] GenerateBulkInsertCommands<T>(this IUmbracoDatabase database, T[] records)
{
var pocoData = database.PocoDataFactory.ForType(typeof(T));
@@ -313,7 +313,7 @@ namespace Umbraco.Core.Persistence
/// <param name="pocoData">The PocoData object corresponding to the record's type.</param>
/// <param name="records">The records.</param>
/// <returns>The number of records that were inserted.</returns>
internal static int BulkInsertRecordsSqlCe<T>(Database database, PocoData pocoData, IEnumerable<T> records)
internal static int BulkInsertRecordsSqlCe<T>(IUmbracoDatabase database, PocoData pocoData, IEnumerable<T> records)
{
var columns = pocoData.Columns.ToArray();
@@ -363,7 +363,7 @@ namespace Umbraco.Core.Persistence
/// <param name="pocoData">The PocoData object corresponding to the record's type.</param>
/// <param name="records">The records.</param>
/// <returns>The number of records that were inserted.</returns>
internal static int BulkInsertRecordsSqlServer<T>(Database database, PocoData pocoData, IEnumerable<T> records)
internal static int BulkInsertRecordsSqlServer<T>(IUmbracoDatabase database, PocoData pocoData, IEnumerable<T> records)
{
// create command against the original database.Connection
using (var command = database.CreateCommand(database.Connection, CommandType.Text, string.Empty))
@@ -373,9 +373,7 @@ namespace Umbraco.Core.Persistence
var tTransaction = GetTypedTransaction<SqlTransaction>(command.Transaction);
var tableName = pocoData.TableInfo.TableName;
var umbracoDatabase = database as UmbracoDatabase;
if (umbracoDatabase == null) throw new NotSupportedException("Database must be UmbracoDatabase.");
var syntax = umbracoDatabase.SqlSyntax as SqlServerSyntaxProvider;
var syntax = database.SqlSyntax as SqlServerSyntaxProvider;
if (syntax == null) throw new NotSupportedException("SqlSyntax must be SqlServerSyntaxProvider.");
using (var copy = new SqlBulkCopy(tConnection, SqlBulkCopyOptions.Default, tTransaction) { BulkCopyTimeout = 10000, DestinationTableName = tableName })

View File

@@ -1,12 +0,0 @@
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Querying
{
public interface IQueryFactory
{
IMapperCollection Mappers { get; }
ISqlSyntaxProvider SqlSyntax { get; }
IQuery<T> Create<T>();
}
}

View File

@@ -23,6 +23,12 @@ namespace Umbraco.Core.Persistence.Querying
_mappers = mappers;
}
public Query(SqlContext sqlContext)
{
_sqlSyntax = sqlContext.SqlSyntax;
_mappers = sqlContext.Mappers;
}
/// <summary>
/// Adds a where clause to the query
/// </summary>

View File

@@ -1,22 +0,0 @@
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Querying
{
public class QueryFactory : IQueryFactory
{
public ISqlSyntaxProvider SqlSyntax { get; }
public IMapperCollection Mappers { get; }
public QueryFactory(ISqlSyntaxProvider sqlSyntax, IMapperCollection mappers)
{
SqlSyntax = sqlSyntax;
Mappers = mappers;
}
public IQuery<T> Create<T>()
{
return new Query<T>(SqlSyntax, Mappers);
}
}
}

View File

@@ -43,7 +43,7 @@ namespace Umbraco.Core.Persistence.Repositories
_tagRepository = tagRepository;
_cacheHelper = cacheHelper;
_publishedQuery = work.DatabaseContext.Query<IContent>().Where(x => x.Published);
_publishedQuery = work.Query<IContent>().Where(x => x.Published);
EnsureUniqueNaming = true;
}

View File

@@ -15,7 +15,6 @@ 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;
@@ -630,7 +629,7 @@ AND umbracoNode.id <> @id",
}
public static IEnumerable<IMediaType> GetMediaTypes<TRepo>(
Database db, ISqlSyntaxProvider sqlSyntax,
IDatabase db, ISqlSyntaxProvider sqlSyntax,
TRepo contentTypeRepository)
where TRepo : IReadRepository<int, TEntity>
{
@@ -644,7 +643,7 @@ AND umbracoNode.id <> @id",
}
public static IEnumerable<IContentType> GetContentTypes<TRepo>(
Database db, ISqlSyntaxProvider sqlSyntax,
IDatabase db, ISqlSyntaxProvider sqlSyntax,
TRepo contentTypeRepository,
ITemplateRepository templateRepository)
where TRepo : IReadRepository<int, TEntity>
@@ -667,7 +666,7 @@ AND umbracoNode.id <> @id",
}
internal static void MapContentTypeChildren<TRepo>(IContentTypeComposition[] contentTypes,
Database db, ISqlSyntaxProvider sqlSyntax,
IDatabase db, ISqlSyntaxProvider sqlSyntax,
TRepo contentTypeRepository,
IDictionary<int, List<int>> allParentContentTypeIds)
where TRepo : IReadRepository<int, TEntity>
@@ -721,7 +720,7 @@ AND umbracoNode.id <> @id",
}
internal static void MapContentTypeTemplates<TRepo>(IContentType[] contentTypes,
Database db,
IDatabase db,
TRepo contentTypeRepository,
ITemplateRepository templateRepository,
IDictionary<int, List<AssociatedTemplate>> associatedTemplates)
@@ -756,7 +755,7 @@ AND umbracoNode.id <> @id",
}
internal static IEnumerable<IMediaType> MapMediaTypes(Database db, ISqlSyntaxProvider sqlSyntax,
internal static IEnumerable<IMediaType> MapMediaTypes(IDatabase db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<int, List<int>> parentMediaTypeIds)
{
Mandate.ParameterNotNull(db, "db");
@@ -894,7 +893,7 @@ AND umbracoNode.id <> @id",
return mediaType;
}
internal static IEnumerable<IContentType> MapContentTypes(Database db, ISqlSyntaxProvider sqlSyntax,
internal static IEnumerable<IContentType> MapContentTypes(IDatabase db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<int, List<AssociatedTemplate>> associatedTemplates,
out IDictionary<int, List<int>> parentContentTypeIds)
{
@@ -1081,7 +1080,7 @@ AND umbracoNode.id <> @id",
return contentType;
}
internal static void MapGroupsAndProperties(int[] contentTypeIds, Database db, ISqlSyntaxProvider sqlSyntax,
internal static void MapGroupsAndProperties(int[] contentTypeIds, IDatabase db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<int, PropertyTypeCollection> allPropertyTypeCollection,
out IDictionary<int, PropertyGroupCollection> allPropertyGroupCollection)
{

View File

@@ -31,9 +31,9 @@ namespace Umbraco.Core.Persistence.Repositories
#region Query Methods
public IQuery<IUmbracoEntity> Query => UnitOfWork.DatabaseContext.Query<IUmbracoEntity>();
public IQuery<IUmbracoEntity> Query => UnitOfWork.Query<IUmbracoEntity>();
public Sql<SqlContext> Sql() { return UnitOfWork.Database.Sql();}
public Sql<SqlContext> Sql() => UnitOfWork.Sql();
public IUmbracoEntity GetByKey(Guid key)
{

View File

@@ -36,23 +36,23 @@ namespace Umbraco.Core.Persistence.Repositories
/// <summary>
/// Gets the repository's database.
/// </summary>
protected UmbracoDatabase Database => UnitOfWork.Database;
protected IUmbracoDatabase Database => UnitOfWork.Database;
/// <summary>
/// Gets the repository's database sql syntax.
/// </summary>
public ISqlSyntaxProvider SqlSyntax => UnitOfWork.DatabaseContext.SqlSyntax;
public ISqlSyntaxProvider SqlSyntax => UnitOfWork.SqlSyntax;
/// <summary>
/// Creates a new query.
/// </summary>
public override IQuery<T> Query<T>() => UnitOfWork.DatabaseContext.Query<T>();
public override IQuery<T> Query<T>() => UnitOfWork.Query<T>();
/// <summary>
/// Creates a new Sql statement.
/// </summary>
/// <returns>A new Sql statement.</returns>
protected Sql<SqlContext> Sql() => UnitOfWork.DatabaseContext.Sql();
protected Sql<SqlContext> Sql() => UnitOfWork.Sql();
#region Abstract Methods

View File

@@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Repositories
public IEnumerable<Notification> GetUsersNotifications(IEnumerable<int> userIds, string action, IEnumerable<int> nodeIds, Guid objectType)
{
var nodeIdsA = nodeIds.ToArray();
var sql = _unitOfWork.Database.Sql()
var sql = _unitOfWork.Sql()
.Select("DISTINCT umbracoNode.id nodeId, umbracoUser.id userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action")
.From<User2NodeNotifyDto>()
.InnerJoin<NodeDto>().On<User2NodeNotifyDto, NodeDto>(left => left.NodeId, right => right.NodeId)
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Persistence.Repositories
public IEnumerable<Notification> GetUserNotifications(IUser user)
{
var sql = _unitOfWork.Database.Sql()
var sql = _unitOfWork.Sql()
.Select("DISTINCT umbracoNode.id, umbracoUser2NodeNotify.userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action")
.From<User2NodeNotifyDto>()
.InnerJoin<NodeDto>()
@@ -63,7 +63,7 @@ namespace Umbraco.Core.Persistence.Repositories
public IEnumerable<Notification> GetEntityNotifications(IEntity entity)
{
var sql = _unitOfWork.Database.Sql()
var sql = _unitOfWork.Sql()
.Select("DISTINCT umbracoNode.id, umbracoUser2NodeNotify.userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action")
.From<User2NodeNotifyDto>()
.InnerJoin<NodeDto>()
@@ -94,7 +94,7 @@ namespace Umbraco.Core.Persistence.Repositories
public Notification CreateNotification(IUser user, IEntity entity, string action)
{
var sql = _unitOfWork.Database.Sql()
var sql = _unitOfWork.Sql()
.Select("DISTINCT nodeObjectType")
.From<NodeDto>()
.Where<NodeDto>(nodeDto => nodeDto.NodeId == entity.Id);

View File

@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Repositories
_runtimeCache = cache.IsolatedRuntimeCache.GetOrCreateCache<EntityPermission>();
}
private ISqlSyntaxProvider SqlSyntax => _unitOfWork.Database.SqlSyntax;
private ISqlSyntaxProvider SqlSyntax => _unitOfWork.SqlSyntax;
/// <summary>
/// Returns permissions for a given user for any number of nodes
@@ -75,7 +75,7 @@ namespace Umbraco.Core.Persistence.Repositories
whereBuilder.Append(")");
}
var sql = _unitOfWork.Database.Sql()
var sql = _unitOfWork.Sql()
.SelectAll()
.From<User2NodePermissionDto>()
.Where(whereBuilder.ToString());
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <returns></returns>
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
{
var sql = _unitOfWork.Database.Sql()
var sql = _unitOfWork.Sql()
.SelectAll()
.From<User2NodePermissionDto>()
.Where<User2NodePermissionDto>(dto => dto.NodeId == entityId)

View File

@@ -5,6 +5,7 @@ using System.Linq.Expressions;
using NPoco;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.DI;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
@@ -26,12 +27,14 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IUserTypeRepository _userTypeRepository;
private readonly CacheHelper _cacheHelper;
private readonly IMapperCollection _mapperCollection;
private PermissionRepository<IContent> _permissionRepository;
public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository)
public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository, IMapperCollection mapperCollection)
: base(work, cacheHelper, logger)
{
_userTypeRepository = userTypeRepository;
_mapperCollection = mapperCollection;
_cacheHelper = cacheHelper;
}
@@ -332,9 +335,8 @@ namespace Umbraco.Core.Persistence.Repositories
if (orderBy == null) throw new ArgumentNullException(nameof(orderBy));
// get the referenced column name and find the corresp mapped column name
var queryFactory = UnitOfWork.DatabaseContext.QueryFactory;
var expressionMember = ExpressionHelper.GetMemberInfo(orderBy);
var mapper = queryFactory.Mappers[typeof(IUser)];
var mapper = _mapperCollection[typeof(IUser)];
var mappedField = mapper.Map(SqlSyntax, expressionMember.Name);
if (mappedField.IsNullOrWhiteSpace())

View File

@@ -1,28 +1,26 @@
using System;
using System.Linq;
using NPoco;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
public class SqlContext
{
public SqlContext(ISqlSyntaxProvider sqlSyntax, IPocoDataFactory pocoDataFactory, DatabaseType databaseType)
public SqlContext(ISqlSyntaxProvider sqlSyntax, IPocoDataFactory pocoDataFactory, DatabaseType databaseType, IMapperCollection mappers = null)
{
if (sqlSyntax == null) throw new ArgumentNullException(nameof(sqlSyntax));
if (pocoDataFactory == null) throw new ArgumentNullException(nameof(pocoDataFactory));
if (databaseType == null) throw new ArgumentNullException(nameof(databaseType));
// for tests
if (mappers == null) mappers = new Mappers.MapperCollection(Enumerable.Empty<BaseMapper>());
SqlSyntax = sqlSyntax;
PocoDataFactory = pocoDataFactory;
DatabaseType = databaseType;
}
public SqlContext(IUmbracoDatabaseConfig database)
{
if (database == null) throw new ArgumentNullException(nameof(database));
SqlSyntax = database.SqlSyntax;
PocoDataFactory = database.PocoDataFactory;
DatabaseType = database.DatabaseType;
Mappers = mappers;
}
public ISqlSyntaxProvider SqlSyntax { get; }
@@ -30,5 +28,7 @@ namespace Umbraco.Core.Persistence
public IPocoDataFactory PocoDataFactory { get; }
public DatabaseType DatabaseType { get; }
public IMapperCollection Mappers { get; }
}
}

View File

@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
string GetQuotedTableName(string tableName);
string GetQuotedColumnName(string columnName);
string GetQuotedName(string name);
bool DoesTableExist(Database db, string tableName);
bool DoesTableExist(IDatabase db, string tableName);
string GetIndexType(IndexTypes indexTypes);
string GetSpecialDbType(SpecialDbTypes dbTypes);
string CreateTable { get; }
@@ -68,20 +68,21 @@ namespace Umbraco.Core.Persistence.SqlSyntax
string Format(ForeignKeyDefinition foreignKey);
string FormatColumnRename(string tableName, string oldName, string newName);
string FormatTableRename(string oldName, string newName);
Sql<SqlContext> SelectTop(Sql<SqlContext> sql, int top);
bool SupportsClustered();
bool SupportsIdentityInsert();
bool? SupportsCaseInsensitiveQueries(Database db);
bool? SupportsCaseInsensitiveQueries(IDatabase db);
string ConvertIntegerToOrderableString { get; }
string ConvertDateToOrderableString { get; }
string ConvertDecimalToOrderableString { get; }
IEnumerable<string> GetTablesInSchema(Database db);
IEnumerable<ColumnInfo> GetColumnsInSchema(Database db);
IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db);
IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db);
IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db);
IEnumerable<string> GetTablesInSchema(IDatabase db);
IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db);
IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db);
IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db);
IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db);
}
}

View File

@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
InitColumnTypeMap();
}
public override IEnumerable<string> GetTablesInSchema(Database db)
public override IEnumerable<string> GetTablesInSchema(IDatabase db)
{
List<string> list;
try
@@ -54,7 +54,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return list;
}
public override IEnumerable<ColumnInfo> GetColumnsInSchema(Database db)
public override IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db)
{
List<ColumnInfo> list;
try
@@ -79,7 +79,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return list;
}
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
{
List<Tuple<string, string>> list;
try
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return list;
}
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
{
List<Tuple<string, string, string>> list;
try
@@ -127,7 +127,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return list;
}
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db)
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
{
List<Tuple<string, string, string, bool>> list;
try
@@ -156,7 +156,7 @@ ORDER BY TABLE_NAME, INDEX_NAME",
return list;
}
public override bool DoesTableExist(Database db, string tableName)
public override bool DoesTableExist(IDatabase db, string tableName)
{
long result;
try
@@ -370,7 +370,7 @@ ORDER BY TABLE_NAME, INDEX_NAME",
public override string ConvertDateToOrderableString { get { return "DATE_FORMAT({0}, '%Y%m%d')"; } }
public override string ConvertDecimalToOrderableString { get { return "LPAD(FORMAT({0}, 9), 20, '0')"; } }
public override bool? SupportsCaseInsensitiveQueries(Database db)
public override bool? SupportsCaseInsensitiveQueries(IDatabase db)
{
bool? supportsCaseInsensitiveQueries = null;

View File

@@ -106,13 +106,13 @@ namespace Umbraco.Core.Persistence.SqlSyntax
columns);
}
public override IEnumerable<string> GetTablesInSchema(Database db)
public override IEnumerable<string> GetTablesInSchema(IDatabase db)
{
var items = db.Fetch<dynamic>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
return items.Select(x => x.TABLE_NAME).Cast<string>().ToList();
}
public override IEnumerable<ColumnInfo> GetColumnsInSchema(Database db)
public override IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db)
{
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS");
return
@@ -122,7 +122,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
}
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
{
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS");
var indexItems = db.Fetch<dynamic>("SELECT TABLE_NAME, INDEX_NAME FROM INFORMATION_SCHEMA.INDEXES");
@@ -134,7 +134,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
.ToList();
}
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
{
var items =
db.Fetch<dynamic>(
@@ -150,7 +150,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
indexItem.INDEX_NAME))).ToList();
}
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db)
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
{
var items =
db.Fetch<dynamic>(
@@ -162,7 +162,7 @@ ORDER BY TABLE_NAME, INDEX_NAME");
item => new Tuple<string, string, string, bool>(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE));
}
public override bool DoesTableExist(Database db, string tableName)
public override bool DoesTableExist(IDatabase db, string tableName)
{
var result =
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName",

View File

@@ -12,8 +12,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
[SqlSyntaxProvider(Constants.DbProviderNames.SqlServer)]
public class SqlServerSyntaxProvider : MicrosoftSqlSyntaxProviderBase<SqlServerSyntaxProvider>
{
// IDatabaseFactory to be lazily injected
public SqlServerSyntaxProvider(Lazy<IDatabaseFactory> lazyFactory)
// IUmbracoDatabaseFactory to be lazily injected
public SqlServerSyntaxProvider(Lazy<IUmbracoDatabaseFactory> lazyFactory)
{
_serverVersion = new Lazy<ServerVersionInfo>(() =>
{
@@ -99,7 +99,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
}
}
private static ServerVersionInfo DetermineVersion(IDatabaseFactory factory)
private static ServerVersionInfo DetermineVersion(IUmbracoDatabaseFactory factory)
{
// Edition: "Express Edition", "Windows Azure SQL Database..."
// EngineEdition: 1/Desktop 2/Standard 3/Enterprise 4/Express 5/Azure
@@ -136,19 +136,19 @@ namespace Umbraco.Core.Persistence.SqlSyntax
/// server type that does this, therefore this method doesn't exist on any other syntax provider
/// </summary>
/// <returns></returns>
public IEnumerable<Tuple<string, string, string, string>> GetDefaultConstraintsPerColumn(Database db)
public IEnumerable<Tuple<string, string, string, string>> GetDefaultConstraintsPerColumn(IDatabase db)
{
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)
public override IEnumerable<string> GetTablesInSchema(IDatabase db)
{
var items = db.Fetch<dynamic>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
return items.Select(x => x.TABLE_NAME).Cast<string>().ToList();
}
public override IEnumerable<ColumnInfo> GetColumnsInSchema(Database db)
public override IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db)
{
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS");
return
@@ -158,7 +158,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
}
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
{
var items =
db.Fetch<dynamic>(
@@ -166,7 +166,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
}
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
{
var items =
db.Fetch<dynamic>(
@@ -174,7 +174,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return items.Select(item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList();
}
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db)
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
{
var items =
db.Fetch<dynamic>(
@@ -190,7 +190,7 @@ order by T.name, I.name");
}
public override bool DoesTableExist(Database db, string tableName)
public override bool DoesTableExist(IDatabase db, string tableName)
{
var result =
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName",

View File

@@ -226,34 +226,34 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return "NVARCHAR";
}
public virtual bool? SupportsCaseInsensitiveQueries(Database db)
public virtual bool? SupportsCaseInsensitiveQueries(IDatabase db)
{
return true;
}
public virtual IEnumerable<string> GetTablesInSchema(Database db)
public virtual IEnumerable<string> GetTablesInSchema(IDatabase db)
{
return new List<string>();
}
public virtual IEnumerable<ColumnInfo> GetColumnsInSchema(Database db)
public virtual IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db)
{
return new List<ColumnInfo>();
}
public virtual IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
public virtual IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
{
return new List<Tuple<string, string>>();
}
public virtual IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
public virtual IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
{
return new List<Tuple<string, string, string>>();
}
public abstract IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db);
public abstract IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db);
public virtual bool DoesTableExist(Database db, string tableName)
public virtual bool DoesTableExist(IDatabase db, string tableName)
{
return false;
}

View File

@@ -6,6 +6,7 @@ using NPoco;
using StackExchange.Profiling;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.FaultHandling;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
@@ -17,18 +18,16 @@ namespace Umbraco.Core.Persistence
/// <para>Is used everywhere in place of the original NPoco Database object, and provides additional features
/// such as profiling, retry policies, logging, etc.</para>
/// <para>Is never created directly but obtained from the <see cref="UmbracoDatabaseFactory"/>.</para>
/// <para>It implements IDisposeOnRequestEnd which means it will be disposed when the request ends, which
/// automatically closes the connection - as implemented by NPoco Database.Dispose().</para>
/// </remarks>
public class UmbracoDatabase : Database, IDisposeOnRequestEnd, IUmbracoDatabaseConfig
public class UmbracoDatabase : Database, IUmbracoDatabase
{
// Umbraco's default isolation level is RepeatableRead
private const IsolationLevel DefaultIsolationLevel = IsolationLevel.RepeatableRead;
private readonly ILogger _logger;
private readonly SqlContext _sqlContext;
private readonly ILogger _logger;
private readonly RetryPolicy _connectionRetryPolicy;
private readonly RetryPolicy _commandRetryPolicy;
private readonly Guid _instanceGuid = Guid.NewGuid();
#region Ctor
@@ -42,7 +41,7 @@ namespace Umbraco.Core.Persistence
public UmbracoDatabase(string connectionString, SqlContext sqlContext, DbProviderFactory provider, ILogger logger, RetryPolicy connectionRetryPolicy = null, RetryPolicy commandRetryPolicy = null)
: base(connectionString, sqlContext.DatabaseType, provider, DefaultIsolationLevel)
{
_sqlContext = sqlContext;
SqlContext = sqlContext;
_logger = logger;
_connectionRetryPolicy = connectionRetryPolicy;
@@ -58,7 +57,7 @@ namespace Umbraco.Core.Persistence
internal UmbracoDatabase(DbConnection connection, SqlContext sqlContext, ILogger logger)
: base(connection, sqlContext.DatabaseType, DefaultIsolationLevel)
{
_sqlContext = sqlContext;
SqlContext = sqlContext;
_logger = logger;
EnableSqlTrace = EnableSqlTraceDefault;
@@ -66,26 +65,17 @@ namespace Umbraco.Core.Persistence
#endregion
/// <summary>
/// Gets the database Sql syntax.
/// </summary>
public ISqlSyntaxProvider SqlSyntax => _sqlContext.SqlSyntax;
/// <inheritdoc />
public SqlContext SqlContext { get; }
/// <summary>
/// Creates a Sql statement.
/// </summary>
public Sql<SqlContext> Sql()
{
return NPoco.Sql.BuilderFor(_sqlContext);
}
/// <inheritdoc />
public ISqlSyntaxProvider SqlSyntax => SqlContext.SqlSyntax;
public Sql<SqlContext> Sql() => new Sql<SqlContext>(SqlContext);
/// <summary>
/// Creates a Sql statement.
/// </summary>
public Sql<SqlContext> Sql(string sql, params object[] args)
{
return Sql().Append(sql, args);
}
public Sql<SqlContext> Sql(string sql, params object[] args) => Sql().Append(sql, args);
public IQuery<T> Query<T>() => new Query<T>(SqlContext);
#region Testing, Debugging and Troubleshooting
@@ -95,25 +85,19 @@ namespace Umbraco.Core.Persistence
private int _spid = -1;
private const bool EnableSqlTraceDefault = true;
#else
private string _sid;
private string _instanceId;
private const bool EnableSqlTraceDefault = false;
#endif
/// <summary>
/// Gets this instance's unique identifier.
/// </summary>
public Guid InstanceId { get; } = Guid.NewGuid();
/// <summary>
/// Gets this instance's string identifier.
/// </summary>
public string InstanceSid {
/// <inheritdoc />
public string InstanceId
{
get
{
#if DEBUG_DATABASES
return InstanceId.ToString("N").Substring(0, 8) + ':' + _spid;
return _instanceGuid.ToString("N").Substring(0, 8) + ':' + _spid;
#else
return _sid ?? (_sid = InstanceId.ToString("N").Substring(0, 8));
return _instanceId ?? (_instanceId = _instanceGuid.ToString("N").Substring(0, 8));
#endif
}
}
@@ -196,7 +180,7 @@ namespace Umbraco.Core.Persistence
protected override void OnException(Exception x)
{
_logger.Error<UmbracoDatabase>("Exception (" + InstanceSid + ").", x);
_logger.Error<UmbracoDatabase>("Exception (" + InstanceId + ").", x);
base.OnException(x);
}
@@ -210,7 +194,7 @@ namespace Umbraco.Core.Persistence
{
var sb = new StringBuilder();
#if DEBUG_DATABASES
sb.Append(InstanceSid);
sb.Append(InstanceId);
sb.Append(": ");
#endif
sb.Append(cmd.CommandText);
@@ -225,7 +209,7 @@ namespace Umbraco.Core.Persistence
#if DEBUG_DATABASES
// detects whether the command is already in use (eg still has an open reader...)
DatabaseDebugHelper.SetCommand(cmd, InstanceSid + " [T" + Thread.CurrentThread.ManagedThreadId + "]");
DatabaseDebugHelper.SetCommand(cmd, InstanceId + " [T" + Thread.CurrentThread.ManagedThreadId + "]");
var refsobj = DatabaseDebugHelper.GetReferencedObjects(cmd.Connection);
if (refsobj != null) _logger.Debug<UmbracoDatabase>("Oops!" + Environment.NewLine + refsobj);
#endif
@@ -242,16 +226,5 @@ namespace Umbraco.Core.Persistence
}
#endregion
// at the moment, NPoco does not support overriding Dispose
/*
public override void Dispose(bool disposing)
{
#if DEBUG_DATABASES
LogHelper.Debug<UmbracoDatabase>("Dispose (" + InstanceSid + ").");
#endif
base.Dispose();
}
*/
}
}

View File

@@ -0,0 +1,14 @@
using System;
namespace Umbraco.Core.Persistence
{
internal static class UmbracoDatabaseExtensions
{
public static UmbracoDatabase AsUmbracoDatabase(this IUmbracoDatabase database)
{
var asDatabase = database as UmbracoDatabase;
if (asDatabase == null) throw new Exception("oops: database.");
return asDatabase;
}
}
}

View File

@@ -17,18 +17,17 @@ using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
/// <summary>
/// Default implementation of <see cref="IDatabaseFactory"/>.
/// Default implementation of <see cref="IUmbracoDatabaseFactory"/>.
/// </summary>
/// <remarks>
/// <para>This factory implementation creates and manages an "ambient" database connection. When running
/// within an Http context, "ambient" means "associated with that context". Otherwise, it means "static to
/// the current thread". In this latter case, note that the database connection object is not thread safe.</para>
/// <para>It wraps an NPoco DatabaseFactory which is initializes with a proper IPocoDataFactory to ensure
/// <para>It wraps an NPoco UmbracoDatabaseFactory which is initializes with a proper IPocoDataFactory to ensure
/// that NPoco's plumbing is cached appropriately for the whole application.</para>
/// </remarks>
internal class UmbracoDatabaseFactory : DisposableObject, IDatabaseFactory
internal class UmbracoDatabaseFactory : DisposableObject, IUmbracoDatabaseFactory
{
//private readonly IUmbracoDatabaseAccessor _umbracoDatabaseAccessor;
private readonly IDatabaseScopeAccessor _databaseScopeAccessor;
private readonly ISqlSyntaxProvider[] _sqlSyntaxProviders;
private readonly IMapperCollection _mappers;
@@ -41,7 +40,6 @@ namespace Umbraco.Core.Persistence
private DbProviderFactory _dbProviderFactory;
private DatabaseType _databaseType;
private ISqlSyntaxProvider _sqlSyntax;
private IQueryFactory _queryFactory;
private SqlContext _sqlContext;
private RetryPolicy _connectionRetryPolicy;
private RetryPolicy _commandRetryPolicy;
@@ -121,20 +119,15 @@ namespace Umbraco.Core.Persistence
#endregion
/// <summary>
/// Gets a value indicating whether the database is configured (no connect test).
/// </summary>
/// <remarks></remarks>
/// <inheritdoc />
public bool Configured { get; private set; }
/// <summary>
/// Gets a value indicating whether it is possible to connect to the database.
/// </summary>
/// <inheritdoc />
public bool CanConnect => Configured && DbConnectionExtensions.IsConnectionAvailable(_connectionString, _providerName);
/// <summary>
/// Gets the database sql syntax provider.
/// </summary>
#region IDatabaseContext
/// <inheritdoc />
public ISqlSyntaxProvider SqlSyntax
{
get
@@ -144,20 +137,28 @@ namespace Umbraco.Core.Persistence
}
}
/// <summary>
/// Gets the database query factory.
/// </summary>
public IQueryFactory QueryFactory {
get
{
EnsureConfigured();
return _queryFactory;
}
public IQuery<T> Query<T>()
{
EnsureConfigured();
return new Query<T>(_sqlSyntax, _mappers);
}
public Sql<SqlContext> Sql() => NPoco.Sql.BuilderFor(_sqlContext);
/// <inheritdoc />
public Sql<SqlContext> Sql()
{
EnsureConfigured();
return NPoco.Sql.BuilderFor(_sqlContext);
}
// will be configured by the database context
/// <inheritdoc />
public Sql<SqlContext> Sql(string sql, params object[] args)
{
return Sql().Append(sql, args);
}
#endregion
/// <inheritdoc />
public void Configure(string connectionString, string providerName)
{
using (new WriteLock(_lock))
@@ -194,23 +195,47 @@ namespace Umbraco.Core.Persistence
var config = new FluentConfig(xmappers => factory);
// create the database factory
_npocoDatabaseFactory = DatabaseFactory.Config(x => x
_npocoDatabaseFactory = NPoco.DatabaseFactory.Config(x => x
.UsingDatabase(CreateDatabaseInstance) // creating UmbracoDatabase instances
.WithFluentConfig(config)); // with proper configuration
if (_npocoDatabaseFactory == null) throw new NullReferenceException("The call to DatabaseFactory.Config yielded a null DatabaseFactory instance.");
if (_npocoDatabaseFactory == null) throw new NullReferenceException("The call to UmbracoDatabaseFactory.Config yielded a null UmbracoDatabaseFactory instance.");
// these are created here because it is the UmbracoDatabaseFactory that determines
// the sql syntax, poco data factory, and database type - so it "owns" the context
// and the query factory
_sqlContext = new SqlContext(_sqlSyntax, _pocoDataFactory, _databaseType);
_queryFactory = new QueryFactory(_sqlSyntax, _mappers);
_sqlContext = new SqlContext(_sqlSyntax, _pocoDataFactory, _databaseType, _mappers);
_logger.Debug<UmbracoDatabaseFactory>("Configured.");
Configured = true;
}
}
/// <inheritdoc />
public IUmbracoDatabase Database => GetDatabase();
/// <inheritdoc />
public IUmbracoDatabase GetDatabase()
{
EnsureConfigured();
var scope = _databaseScopeAccessor.Scope;
if (scope == null) throw new InvalidOperationException("Out of scope.");
return scope.Database;
}
/// <inheritdoc />
public IUmbracoDatabase CreateDatabase()
{
return (IUmbracoDatabase) _npocoDatabaseFactory.GetDatabase();
}
/// <inheritdoc />
public IDatabaseScope CreateScope(IUmbracoDatabase database = null)
{
return new DatabaseScope(_databaseScopeAccessor, this, database);
}
// gets the sql syntax provider that corresponds, from attribute
private ISqlSyntaxProvider GetSqlSyntaxProvider(string providerName)
{
@@ -227,6 +252,7 @@ namespace Umbraco.Core.Persistence
//provider = _syntaxProviders.FirstOrDefault(x => x.GetType() == typeof(SqlServerSyntaxProvider));
}
// ensures that the database is configured, else throws
private void EnsureConfigured()
{
using (new ReadLock(_lock))
@@ -236,44 +262,12 @@ namespace Umbraco.Core.Persistence
}
}
// method used by NPoco's DatabaseFactory to actually create the database instance
// method used by NPoco's UmbracoDatabaseFactory to actually create the database instance
private UmbracoDatabase CreateDatabaseInstance()
{
return new UmbracoDatabase(_connectionString, _sqlContext, _dbProviderFactory, _logger, _connectionRetryPolicy, _commandRetryPolicy);
}
// fixme temp?
public UmbracoDatabase Database => GetDatabase();
/// <summary>
/// Gets (creates or retrieves) the ambient database connection.
/// </summary>
/// <returns>The ambient database connection.</returns>
public UmbracoDatabase GetDatabase()
{
EnsureConfigured();
var scope = _databaseScopeAccessor.Scope;
if (scope == null) throw new InvalidOperationException("Out of scope.");
return scope.Database;
//// check if it's in scope
//var db = _umbracoDatabaseAccessor.UmbracoDatabase;
//if (db != null) return db;
//db = (UmbracoDatabase) _npocoDatabaseFactory.GetDatabase();
//_umbracoDatabaseAccessor.UmbracoDatabase = db;
//return db;
}
/// <summary>
/// Creates a new database instance.
/// </summary>
/// <remarks>The database instance is not part of any scope and must be disposed after being used.</remarks>
public UmbracoDatabase CreateDatabase()
{
return (UmbracoDatabase) _npocoDatabaseFactory.GetDatabase();
}
protected override void DisposeResources()
{
// this is weird, because hybrid accessors store different databases per
@@ -297,84 +291,5 @@ namespace Umbraco.Core.Persistence
//db?.Dispose();
_databaseScopeAccessor.Scope = null;
}
//public bool HasAmbient => _umbracoDatabaseAccessor.UmbracoDatabase != null;
//public UmbracoDatabase DetachAmbient()
//{
// var database = _umbracoDatabaseAccessor.UmbracoDatabase;
// _umbracoDatabaseAccessor.UmbracoDatabase = null;
// return database;
//}
//public void AttachAmbient(UmbracoDatabase database)
//{
// var tmp = _umbracoDatabaseAccessor.UmbracoDatabase;
// _umbracoDatabaseAccessor.UmbracoDatabase = database;
// tmp?.Dispose();
// // fixme - what shall we do with tmp?
// // fixme - what about using "disposing" of the database to remove it from "ambient"?!
//}
//public IDisposable CreateScope(bool force = false) // fixme - why would we ever force?
//{
// if (HasAmbient)
// {
// return force
// ? new DatabaseScope(this, DetachAmbient(), GetDatabase())
// : new DatabaseScope(this, null, null);
// }
// // create a new, temp, database (will be disposed with DatabaseScope)
// return new DatabaseScope(this, null, GetDatabase());
//}
public IDisposable CreateScope()
{
return new DatabaseScope(_databaseScopeAccessor, this);
}
/*
private class DatabaseScope : IDisposable
{
private readonly UmbracoDatabaseFactory _factory;
private readonly UmbracoDatabase _orig;
private readonly UmbracoDatabase _temp;
// orig is the original database that was ambient when the scope was created
// if not null, it has been detached in order to be replaced by temp, which cannot be null
// if null, either there was no ambient database, or we don't want to replace it
// temp is the scope database that is created for the scope
// if not null, it has been attached and is not the ambient database,
// and when the scope is disposed it will be detached, disposed, and replaced by orig
// if null, the scope is nested and reusing the ambient database, without touching anything
public DatabaseScope(UmbracoDatabaseFactory factory, UmbracoDatabase orig, UmbracoDatabase temp)
{
if (factory == null) throw new ArgumentNullException(nameof(factory));
_factory = factory;
_orig = orig;
_temp = temp;
}
public void Dispose()
{
if (_temp != null) // if the scope had its own database
{
// detach and ensure consistency, then dispose
var temp = _factory.DetachAmbient();
if (temp != _temp) throw new Exception("bam!");
temp.Dispose();
// re-instate original database if any
if (_orig != null)
_factory.AttachAmbient(_orig);
}
GC.SuppressFinalize(this);
}
}
*/
}
}

View File

@@ -1,19 +1,16 @@
using NPoco;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Represents a persistence unit of work for working with a database.
/// </summary>
public interface IDatabaseUnitOfWork : IUnitOfWork
public interface IDatabaseUnitOfWork : IUnitOfWork, IDatabaseContext
{
/// <summary>
/// Gets the database context.
/// Gets the database.
/// </summary>
DatabaseContext DatabaseContext { get; }
/// <summary>
/// Gets the current database instance.
/// </summary>
UmbracoDatabase Database { get; }
IUmbracoDatabase Database { get; }
/// <summary>
/// Read-locks some lock objects.

View File

@@ -6,9 +6,9 @@ namespace Umbraco.Core.Persistence.UnitOfWork
public interface IDatabaseUnitOfWorkProvider
{
/// <summary>
/// Gets the database context.
/// Gets the database factory.
/// </summary>
DatabaseContext DatabaseContext { get; }
IUmbracoDatabaseFactory DatabaseFactory { get; }
/// <summary>
/// Creates a unit of work.

View File

@@ -1,6 +1,8 @@
using System;
using System.Data;
using NPoco;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.UnitOfWork
{
@@ -14,20 +16,33 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// <summary>
/// Initializes a new instance of the <see cref="NPocoUnitOfWork"/> class with a database and a repository factory.
/// </summary>
/// <param name="databaseContext">The database context.</param>
/// <param name="database">The database.</param>
/// <param name="repositoryFactory">A repository factory.</param>
/// <remarks>This should be used by the NPocoUnitOfWorkProvider exclusively.</remarks>
internal NPocoUnitOfWork(DatabaseContext databaseContext, RepositoryFactory repositoryFactory)
internal NPocoUnitOfWork(IUmbracoDatabase database, RepositoryFactory repositoryFactory)
: base(repositoryFactory)
{
DatabaseContext = databaseContext;
Database = database;
}
/// <inheritdoc />
public DatabaseContext DatabaseContext { get; }
public IUmbracoDatabase Database { get; }
#region IDatabaseContext
/// <inheritdoc />
public UmbracoDatabase Database => DatabaseContext.Database;
public ISqlSyntaxProvider SqlSyntax => Database.SqlSyntax;
/// <inheritdoc />
public Sql<SqlContext> Sql() => new Sql<SqlContext>(Database.SqlContext);
/// <inheritdoc />
public Sql<SqlContext> Sql(string sql, params object[] args) => new Sql<SqlContext>(Database.SqlContext, sql, args);
/// <inheritdoc />
public IQuery<T> Query<T>() => new Query<T>(Database.SqlContext);
#endregion
/// <inheritdoc />
public override TRepository CreateRepository<TRepository>(string name = null)

View File

@@ -6,30 +6,30 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// Represents a <see cref="IDatabaseUnitOfWork"/> provider that creates <see cref="NPocoUnitOfWork"/> instances.
/// </summary>
public class NPocoUnitOfWorkProvider : IDatabaseUnitOfWorkProvider
{
{
private readonly RepositoryFactory _repositoryFactory;
/// <summary>
/// Initializes a new instance of the <see cref="NPocoUnitOfWorkProvider"/> class with a database factory and a repository factory.
/// </summary>
/// <param name="databaseContext">A database context.</param>
/// <param name="databaseFactory">A database factory.</param>
/// <param name="repositoryFactory">A repository factory.</param>
public NPocoUnitOfWorkProvider(DatabaseContext databaseContext, RepositoryFactory repositoryFactory)
public NPocoUnitOfWorkProvider(IUmbracoDatabaseFactory databaseFactory, RepositoryFactory repositoryFactory)
{
if (databaseContext == null) throw new ArgumentNullException(nameof(databaseContext));
if (databaseFactory == null) throw new ArgumentNullException(nameof(databaseFactory));
if (repositoryFactory == null) throw new ArgumentNullException(nameof(repositoryFactory));
DatabaseContext = databaseContext;
DatabaseFactory = databaseFactory;
_repositoryFactory = repositoryFactory;
}
/// <inheritdoc />
public DatabaseContext DatabaseContext { get; }
public IUmbracoDatabaseFactory DatabaseFactory { get; }
/// <inheritdoc />
public IDatabaseUnitOfWork CreateUnitOfWork()
{
return new NPocoUnitOfWork(DatabaseContext, _repositoryFactory);
return new NPocoUnitOfWork(DatabaseFactory.Database, _repositoryFactory);
}
}
}

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Core.Services
// lazy-constructed because when the ctor runs, the query factory may not be ready
private IQuery<IContent> QueryNotTrashed => _queryNotTrashed ?? (_queryNotTrashed = UowProvider.DatabaseContext.Query<IContent>().Where(x => x.Trashed == false));
private IQuery<IContent> QueryNotTrashed => _queryNotTrashed ?? (_queryNotTrashed = UowProvider.DatabaseFactory.Query<IContent>().Where(x => x.Trashed == false));
#endregion

View File

@@ -70,7 +70,7 @@ namespace Umbraco.Core.Services
// lazy-constructed because when the ctor runs, the query factory may not be ready
private IQuery<IUmbracoEntity> QueryRootEntity => _queryRootEntity ?? (_queryRootEntity = UowProvider.DatabaseContext.Query<IUmbracoEntity>().Where(x => x.ParentId == -1));
private IQuery<IUmbracoEntity> QueryRootEntity => _queryRootEntity ?? (_queryRootEntity = UowProvider.DatabaseFactory.Query<IUmbracoEntity>().Where(x => x.ParentId == -1));
#endregion
@@ -99,7 +99,7 @@ namespace Umbraco.Core.Services
case UmbracoObjectTypes.DataType:
case UmbracoObjectTypes.DocumentTypeContainer:
id = uow.Database.ExecuteScalar<int?>(
uow.DatabaseContext.Sql()
uow.Sql()
.Select("id")
.From<NodeDto>()
.Where<NodeDto>(dto => dto.UniqueId == key));
@@ -145,7 +145,7 @@ namespace Umbraco.Core.Services
case UmbracoObjectTypes.Member:
case UmbracoObjectTypes.DataType:
guid = uow.Database.ExecuteScalar<Guid?>(
uow.DatabaseContext.Sql()
uow.Sql()
.Select("uniqueID")
.From<NodeDto>()
.Where<NodeDto>(dto => dto.NodeId == id));
@@ -548,7 +548,7 @@ namespace Umbraco.Core.Services
{
using (var uow = UowProvider.CreateUnitOfWork())
{
var sql = uow.DatabaseContext.Sql()
var sql = uow.Sql()
.Select("nodeObjectType")
.From<NodeDto>()
.Where<NodeDto>(x => x.NodeId == id);
@@ -569,7 +569,7 @@ namespace Umbraco.Core.Services
{
using (var uow = UowProvider.CreateUnitOfWork())
{
var sql = uow.DatabaseContext.Sql()
var sql = uow.Sql()
.Select("nodeObjectType")
.From<NodeDto>()
.Where<NodeDto>(x => x.UniqueId == key);

View File

@@ -25,6 +25,6 @@ namespace Umbraco.Core.Services
UowProvider = provider;
}
protected IQuery<T> Query<T>() => UowProvider.DatabaseContext.Query<T>();
protected IQuery<T> Query<T>() => UowProvider.DatabaseFactory.Query<T>();
}
}

View File

@@ -64,7 +64,7 @@ namespace Umbraco.Core.Sync
protected DatabaseContext DatabaseContext { get; }
protected UmbracoDatabase Database => DatabaseContext.Database;
protected IUmbracoDatabase Database => DatabaseContext.Database;
protected Sql<SqlContext> Sql() => DatabaseContext.Sql();

View File

@@ -297,10 +297,13 @@
<Compile Include="Models\PublishedContent\PropertyResultType.cs" />
<Compile Include="Models\Rdbms\ContentNuDto.cs" />
<Compile Include="Persistence\DbCommandExtensions.cs" />
<Compile Include="Persistence\IDatabaseScope.cs" />
<Compile Include="Persistence\IDatabaseScopeAccessor.cs" />
<Compile Include="Persistence\IDatabaseContext.cs" />
<Compile Include="Persistence\Mappers\IMapperCollection.cs" />
<Compile Include="Persistence\Mappers\MapperCollection.cs" />
<Compile Include="Persistence\Mappers\MapperCollectionBuilder.cs" />
<Compile Include="Persistence\Migrations\ILocalMigration.cs" />
<Compile Include="Persistence\Migrations\IMigrationCollectionBuilder.cs" />
<Compile Include="Persistence\Migrations\MigrationCollection.cs" />
<Compile Include="Persistence\Migrations\MigrationCollectionBuilder.cs" />
@@ -308,6 +311,7 @@
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\RefactorXmlColumns.cs" />
<Compile Include="Persistence\DatabaseScope.cs" />
<Compile Include="Persistence\ThreadStaticDatabaseScopeAccessor.cs" />
<Compile Include="Persistence\UmbracoDatabaseExtensions.cs" />
<Compile Include="Plugins\HideFromTypeFinderAttribute.cs" />
<Compile Include="HttpContextExtensions.cs" />
<Compile Include="ICompletable.cs" />
@@ -356,14 +360,12 @@
<Compile Include="Persistence\FaultHandling\RetryDbConnection.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Persistence\IUmbracoDatabaseConfig.cs" />
<Compile Include="Persistence\IUmbracoDatabase.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\AddLockObjects.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\AddLockTable.cs" />
<Compile Include="Persistence\UnitOfWorkExtensions.cs" />
<Compile Include="Persistence\Mappers\AuditItemMapper.cs" />
<Compile Include="Persistence\NPocoDatabaseTypeExtensions.cs" />
<Compile Include="Persistence\Querying\IQueryFactory.cs" />
<Compile Include="Persistence\Querying\QueryFactory.cs" />
<Compile Include="Media\Exif\BitConverterEx.cs" />
<Compile Include="Media\Exif\ExifBitConverter.cs" />
<Compile Include="Media\Exif\ExifEnums.cs" />
@@ -401,7 +403,7 @@
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
<Compile Include="Persistence\Migrations\LocalMigrationContext.cs" />
<Compile Include="Persistence\Migrations\LocalMigration.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" />
@@ -842,7 +844,7 @@
<Compile Include="Persistence\Factories\TemplateFactory.cs" />
<Compile Include="Persistence\Factories\UserFactory.cs" />
<Compile Include="Persistence\Factories\UserTypeFactory.cs" />
<Compile Include="Persistence\IDatabaseFactory.cs" />
<Compile Include="Persistence\IUmbracoDatabaseFactory.cs" />
<Compile Include="Persistence\Mappers\BaseMapper.cs" />
<Compile Include="Persistence\Mappers\ContentMapper.cs" />
<Compile Include="Persistence\Mappers\ContentTypeMapper.cs" />

View File

@@ -44,10 +44,10 @@ namespace Umbraco.Tests.Benchmarks
// fixme - should run on LocalDb same as NPoco tests!
private UmbracoDatabase GetSqlServerDatabase(ILogger logger)
private IUmbracoDatabase GetSqlServerDatabase(ILogger logger)
{
IDatabaseFactory f = null;
var l = new Lazy<IDatabaseFactory>(() => f);
IUmbracoDatabaseFactory f = null;
var l = new Lazy<IUmbracoDatabaseFactory>(() => f);
var p = new SqlServerSyntaxProvider(l);
f = new UmbracoDatabaseFactory(
"server=.\\SQLExpress;database=YOURDB;user id=YOURUSER;password=YOURPASS",
@@ -59,7 +59,7 @@ namespace Umbraco.Tests.Benchmarks
return f.GetDatabase();
}
private UmbracoDatabase GetSqlCeDatabase(string cstr, ILogger logger)
private IUmbracoDatabase GetSqlCeDatabase(string cstr, ILogger logger)
{
var f = new UmbracoDatabaseFactory(
cstr,
@@ -167,8 +167,8 @@ namespace Umbraco.Tests.Benchmarks
}
private string _dbFile;
private UmbracoDatabase _dbSqlCe;
private UmbracoDatabase _dbSqlServer;
private IUmbracoDatabase _dbSqlCe;
private IUmbracoDatabase _dbSqlServer;
/// <summary>
/// Tests updating the existing XML way

View File

@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Components
private static IServiceContainer MockContainer(Action<Mock<IServiceContainer>> setup = null)
{
// fixme use IDatabaseFactory vs UmbracoDatabaseFactory, clean it all up!
// fixme use IUmbracoDatabaseFactory vs UmbracoDatabaseFactory, clean it all up!
var testObjects = new TestObjects(null);
var logger = Mock.Of<ILogger>();

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Migrations
{
private ILogger _logger;
private ISqlSyntaxProvider _sqlSyntax;
private UmbracoDatabase _database;
private IUmbracoDatabase _database;
[SetUp]
public void Setup()

View File

@@ -20,7 +20,7 @@ namespace Umbraco.Tests.Migrations
{
private ILogger _logger;
private ISqlSyntaxProvider _sqlSyntax;
private UmbracoDatabase _database;
private IUmbracoDatabase _database;
private MigrationContext _migrationContext;
[SetUp]

View File

@@ -110,7 +110,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
public string Path { get; set; }
public abstract void DatabaseSpecificSetUp();
public abstract void DatabaseSpecificTearDown();
public abstract UmbracoDatabase GetConfiguredDatabase();
public abstract IUmbracoDatabase GetConfiguredDatabase();
public abstract string GetDatabaseSpecificSqlScript();
}
}

View File

@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
//TODO Remove created database here
}
public override UmbracoDatabase GetConfiguredDatabase()
public override IUmbracoDatabase GetConfiguredDatabase()
{
var dbProviderFactory = DbProviderFactories.GetFactory(Constants.DbProviderNames.MySql);
var sqlContext = new SqlContext(new MySqlSyntaxProvider(Mock.Of<ILogger>()), Mock.Of<IPocoDataFactory>(), DatabaseType.MySQL);

View File

@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
SqlCeContextGuardian.CloseBackgroundConnection();
}
public override UmbracoDatabase GetConfiguredDatabase()
public override IUmbracoDatabase GetConfiguredDatabase()
{
var dbProviderFactory = DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe);
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), Mock.Of<IPocoDataFactory>(), DatabaseType.SQLCe);

View File

@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
TestHelper.ClearDatabase();
}
public override UmbracoDatabase GetConfiguredDatabase()
public override IUmbracoDatabase GetConfiguredDatabase()
{
var dbProviderFactory = DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe);
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), Mock.Of<IPocoDataFactory>(), DatabaseType.SQLCe);

View File

@@ -21,10 +21,10 @@ namespace Umbraco.Tests.Migrations.Upgrades
{
}
public override UmbracoDatabase GetConfiguredDatabase()
public override IUmbracoDatabase GetConfiguredDatabase()
{
var dbProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
var sqlContext = new SqlContext(new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null)), Mock.Of<IPocoDataFactory>(), DatabaseType.SqlServer2008);
var sqlContext = new SqlContext(new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null)), Mock.Of<IPocoDataFactory>(), DatabaseType.SqlServer2008);
return new UmbracoDatabase(@"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco", sqlContext, dbProviderFactory, Mock.Of<ILogger>());
}

View File

@@ -97,7 +97,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
public string Path { get; set; }
public UmbracoDatabase GetConfiguredDatabase()
public IUmbracoDatabase GetConfiguredDatabase()
{
var dbProviderFactory = DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe);
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), Mock.Of<IPocoDataFactory>(), DatabaseType.SQLCe);

View File

@@ -17,7 +17,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
{
private ILogger _logger;
private ISqlSyntaxProvider _sqlSyntax;
private UmbracoDatabase _database;
private IUmbracoDatabase _database;
[SetUp]
public void Setup()

View File

@@ -62,7 +62,7 @@ namespace Umbraco.Tests.Persistence
[Test]
public void SingleDatabaseInstancePerScope()
{
UmbracoDatabase db1, db2;
IUmbracoDatabase db1, db2;
using (_dbContext.CreateDatabaseScope())
{
@@ -76,7 +76,7 @@ namespace Umbraco.Tests.Persistence
[Test]
public void DifferentDatabaseInstancePerScope()
{
UmbracoDatabase db1, db2;
IUmbracoDatabase db1, db2;
using (_dbContext.CreateDatabaseScope())
{

View File

@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling
// Arrange
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 sqlSyntax = new[] { new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null)) };
var factory = new UmbracoDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), new TestDatabaseScopeAccessor(), Mock.Of<IMapperCollection>());
var database = factory.GetDatabase();
@@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling
// Arrange
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 sqlSyntax = new[] { new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null)) };
var factory = new UmbracoDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), new TestDatabaseScopeAccessor(), Mock.Of<IMapperCollection>());
var database = factory.GetDatabase();

View File

@@ -28,7 +28,7 @@ namespace Umbraco.Tests.Persistence
// cannot use the default TestUmbracoDatabaseAccessor which only handles one instance at a time
// works with...
//Container.RegisterSingleton<IDatabaseFactory, ThreadSafetyServiceTest.PerThreadSqlCeDatabaseFactory>();
//Container.RegisterSingleton<IUmbracoDatabaseFactory, ThreadSafetyServiceTest.PerThreadSqlCeDatabaseFactory>();
// but it should work with...
Container.RegisterSingleton<IDatabaseScopeAccessor, HybridDatabaseScopeAccessor>();
@@ -109,7 +109,7 @@ namespace Umbraco.Tests.Persistence
// in a thread, must create a scope
using (DatabaseContext.CreateDatabaseScope())
{
UmbracoDatabase database;
IUmbracoDatabase database;
try
{
database = DatabaseContext.Database;
@@ -175,7 +175,7 @@ namespace Umbraco.Tests.Persistence
// in a thread, must create a scope
using (DatabaseContext.CreateDatabaseScope())
{
UmbracoDatabase database;
IUmbracoDatabase database;
try
{
database = DatabaseContext.Database;
@@ -242,7 +242,7 @@ namespace Umbraco.Tests.Persistence
// in a thread, must create a scope
using (DatabaseContext.CreateDatabaseScope())
{
UmbracoDatabase database;
IUmbracoDatabase database;
try
{
database = DatabaseContext.Database;

View File

@@ -456,7 +456,7 @@ namespace Umbraco.Tests.Persistence.Repositories
[Test]
public void RegexAliasTest()
{
var regex = VersionableRepositoryBaseAliasRegex.For(new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null)));
var regex = VersionableRepositoryBaseAliasRegex.For(new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null)));
Assert.AreEqual(@"(\[\w+]\.\[\w+])\s+AS\s+(\[\w+])", regex.ToString());
const string sql = "SELECT [table].[column1] AS [alias1], [table].[column2] AS [alias2] FROM [table];";
var matches = regex.Matches(sql);
@@ -482,8 +482,8 @@ namespace Umbraco.Tests.Persistence.Repositories
try
{
DatabaseContext.Database.EnableSqlTrace = true;
DatabaseContext.Database.EnableSqlCount = true;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlTrace = true;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlCount = true;
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "title", Direction.Ascending, false);
@@ -496,8 +496,8 @@ namespace Umbraco.Tests.Persistence.Repositories
}
finally
{
DatabaseContext.Database.EnableSqlTrace = false;
DatabaseContext.Database.EnableSqlCount = false;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlTrace = false;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlCount = false;
}
}
}
@@ -517,8 +517,8 @@ namespace Umbraco.Tests.Persistence.Repositories
try
{
DatabaseContext.Database.EnableSqlTrace = true;
DatabaseContext.Database.EnableSqlCount = true;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlTrace = true;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlCount = true;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true);
// Assert
@@ -528,8 +528,8 @@ namespace Umbraco.Tests.Persistence.Repositories
}
finally
{
DatabaseContext.Database.EnableSqlTrace = false;
DatabaseContext.Database.EnableSqlCount = false;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlTrace = false;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlCount = false;
}
}
}
@@ -611,7 +611,7 @@ namespace Umbraco.Tests.Persistence.Repositories
long totalRecords;
var filterQuery = QueryFactory.Create<IContent>().Where(x => x.Name.Contains("Page 2"));
var filterQuery = unitOfWork.Query<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 +635,7 @@ namespace Umbraco.Tests.Persistence.Repositories
long totalRecords;
var filterQuery = QueryFactory.Create<IContent>().Where(x => x.Name.Contains("text"));
var filterQuery = unitOfWork.Query<IContent>().Where(x => x.Name.Contains("text"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true, filterQuery);
// Assert

View File

@@ -310,7 +310,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<IDataTypeDefinition>().Where(x => x.PropertyEditorAlias == Constants.PropertyEditors.RadioButtonListAlias);
var query = unitOfWork.Query<IDataTypeDefinition>().Where(x => x.PropertyEditorAlias == Constants.PropertyEditors.RadioButtonListAlias);
var result = repository.GetByQuery(query);
// Assert
@@ -330,7 +330,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<IDataTypeDefinition>().Where(x => x.Name.StartsWith("D"));
var query = unitOfWork.Query<IDataTypeDefinition>().Where(x => x.Name.StartsWith("D"));
int count = repository.Count(query);
// Assert

View File

@@ -206,7 +206,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<IDictionaryItem>().Where(x => x.ItemKey == "Article");
var query = unitOfWork.Query<IDictionaryItem>().Where(x => x.ItemKey == "Article");
var result = repository.GetByQuery(query);
// Assert
@@ -226,7 +226,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<IDictionaryItem>().Where(x => x.ItemKey.StartsWith("Read"));
var query = unitOfWork.Query<IDictionaryItem>().Where(x => x.ItemKey.StartsWith("Read"));
var result = repository.Count(query);
// Assert

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
unitOfWork.Database.EnableSqlTrace = true;
unitOfWork.Database.AsUmbracoDatabase().EnableSqlTrace = true;
var repository = CreateRepository(unitOfWork);
// Act
@@ -176,7 +176,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<ILanguage>().Where(x => x.IsoCode == "da-DK");
var query = unitOfWork.Query<ILanguage>().Where(x => x.IsoCode == "da-DK");
var result = repository.GetByQuery(query);
// Assert
@@ -196,7 +196,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<ILanguage>().Where(x => x.IsoCode.StartsWith("D"));
var query = unitOfWork.Query<ILanguage>().Where(x => x.IsoCode.StartsWith("D"));
int count = repository.Count(query);
// Assert

View File

@@ -134,7 +134,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>());
// Act
var query = QueryFactory.Create<IMacro>().Where(x => x.Alias.ToUpper() == "TEST1");
var query = unitOfWork.Query<IMacro>().Where(x => x.Alias.ToUpper() == "TEST1");
var result = repository.GetByQuery(query);
// Assert
@@ -152,7 +152,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = new MacroRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>());
// Act
var query = QueryFactory.Create<IMacro>().Where(x => x.Name.StartsWith("Test"));
var query = unitOfWork.Query<IMacro>().Where(x => x.Name.StartsWith("Test"));
int count = repository.Count(query);
// Assert

View File

@@ -233,7 +233,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
var result = repository.GetByQuery(query);
// Assert
@@ -252,7 +252,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true);
@@ -274,7 +274,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 1, 1, out totalRecords, "SortOrder", Direction.Ascending, true);
@@ -296,7 +296,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "SortOrder", Direction.Ascending, true);
@@ -318,7 +318,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Descending, true);
@@ -340,7 +340,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true);
@@ -362,10 +362,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var filter = QueryFactory.Create<IMedia>().Where(x => x.Name.Contains("File"));
var filter = unitOfWork.Query<IMedia>().Where(x => x.Name.Contains("File"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true,
filter);
@@ -387,10 +387,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out mediaTypeRepository);
// Act
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == 2);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == 2);
long totalRecords;
var filter = QueryFactory.Create<IMedia>().Where(x => x.Name.Contains("Test"));
var filter = unitOfWork.Query<IMedia>().Where(x => x.Name.Contains("Test"));
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true,
filter);
@@ -475,7 +475,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
int level = 2;
var query = QueryFactory.Create<IMedia>().Where(x => x.Level == level);
var query = unitOfWork.Query<IMedia>().Where(x => x.Level == level);
var result = repository.Count(query);
// Assert

View File

@@ -116,7 +116,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var member = CreateTestMember(key: key);
// Act
var query = QueryFactory.Create<IMember>().Where(x => x.Key == key);
var query = unitOfWork.Query<IMember>().Where(x => x.Key == key);
var result = repository.GetByQuery(query);
// Assert
@@ -249,7 +249,9 @@ namespace Umbraco.Tests.Persistence.Repositories
[Test]
public void Can_Create_Correct_Subquery()
{
var query = QueryFactory.Create<IMember>().Where(x =>
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
var query = provider.DatabaseFactory.Query<IMember>().Where(x =>
((Member) x).LongStringPropertyValue.Contains("1095") &&
((Member) x).PropertyTypeAlias == "headshot");
@@ -309,7 +311,7 @@ namespace Umbraco.Tests.Persistence.Repositories
{
if (isCount)
{
var sqlCount = DatabaseContext.Database.Sql()
var sqlCount = DatabaseContext.Sql()
.SelectCount()
.From<NodeDto>()
.InnerJoin<ContentDto>().On<ContentDto, NodeDto>(left => left.NodeId, right => right.NodeId)
@@ -320,7 +322,7 @@ namespace Umbraco.Tests.Persistence.Repositories
return sqlCount;
}
var sql = DatabaseContext.Database.Sql();
var sql = DatabaseContext.Sql();
sql.Select("umbracoNode.*", "cmsContent.contentType", "cmsContentType.alias AS ContentTypeAlias", "cmsContentVersion.VersionId",
"cmsContentVersion.VersionDate", "cmsMember.Email",
"cmsMember.LoginName", "cmsMember.Password", "cmsPropertyData.id AS PropertyDataId", "cmsPropertyData.propertytypeid",
@@ -344,7 +346,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private Sql<SqlContext> GetSubquery()
{
var sql = DatabaseContext.Database.Sql();
var sql = DatabaseContext.Sql();
sql.Select("umbracoNode.id")
.From<NodeDto>()
.InnerJoin<ContentDto>().On<ContentDto, NodeDto>(left => left.NodeId, right => right.NodeId)

View File

@@ -8,6 +8,7 @@ using NUnit.Framework;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Tests.TestHelpers;
@@ -58,7 +59,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
unitOfWork.Database.EnableSqlTrace = true;
unitOfWork.Database.AsUmbracoDatabase().EnableSqlTrace = true;
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]
@@ -98,7 +99,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var provider = TestObjects.GetDatabaseUnitOfWorkProvider(Logger);
using (var unitOfWork = provider.CreateUnitOfWork())
{
unitOfWork.Database.EnableSqlTrace = true;
unitOfWork.Database.AsUmbracoDatabase().EnableSqlTrace = true;
var repo = new PublicAccessRepository(unitOfWork, CacheHelper, Logger);
var entry = new PublicAccessEntry(content[0], content[1], content[2], new[]

View File

@@ -200,7 +200,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out repositoryType);
// Act
var query = QueryFactory.Create<IRelation>().Where(x => x.ParentId == NodeDto.NodeIdSeed + 1);
var query = unitOfWork.Query<IRelation>().Where(x => x.ParentId == NodeDto.NodeIdSeed + 1);
int count = repository.Count(query);
// Assert
@@ -219,7 +219,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork, out repositoryType);
// Act
var query = QueryFactory.Create<IRelation>().Where(x => x.RelationTypeId == RelationTypeDto.NodeIdSeed);
var query = unitOfWork.Query<IRelation>().Where(x => x.RelationTypeId == RelationTypeDto.NodeIdSeed);
var relations = repository.GetByQuery(query);
// Assert

View File

@@ -193,7 +193,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var repository = CreateRepository(unitOfWork);
// Act
var query = QueryFactory.Create<IRelationType>().Where(x => x.Alias.StartsWith("relate"));
var query = unitOfWork.Query<IRelationType>().Where(x => x.Alias.StartsWith("relate"));
int count = repository.Count(query);
// Assert
@@ -212,7 +212,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var childObjType = new Guid(Constants.ObjectTypes.DocumentType);
var query = QueryFactory.Create<IRelationType>().Where(x => x.ChildObjectType == childObjType);
var query = unitOfWork.Query<IRelationType>().Where(x => x.ChildObjectType == childObjType);
var result = repository.GetByQuery(query);
// Assert

View File

@@ -8,7 +8,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -25,7 +25,7 @@ namespace Umbraco.Tests.Persistence.Repositories
private UserRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out UserTypeRepository userTypeRepository)
{
userTypeRepository = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>());
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), userTypeRepository);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), userTypeRepository, Mock.Of<IMapperCollection>());
return repository;
}
@@ -168,7 +168,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var id = user.Id;
var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger);
var repository2 = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo);
var repository2 = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo, Mock.Of<IMapperCollection>());
repository2.Delete(user);
unitOfWork.Flush();
@@ -245,7 +245,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateAndCommitMultipleUsers(repository, unitOfWork);
// Act
var query = QueryFactory.Create<IUser>().Where(x => x.Username == "TestUser1");
var query = unitOfWork.Query<IUser>().Where(x => x.Username == "TestUser1");
var result = repository.GetByQuery(query);
// Assert
@@ -330,7 +330,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var users = CreateAndCommitMultipleUsers(repository, unitOfWork);
// Act
var query = QueryFactory.Create<IUser>().Where(x => x.Username == "TestUser1" || x.Username == "TestUser2");
var query = unitOfWork.Query<IUser>().Where(x => x.Username == "TestUser1" || x.Username == "TestUser2");
var result = repository.Count(query);
// Assert
@@ -486,7 +486,7 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var unitOfWork = provider.CreateUnitOfWork())
{
var utRepo = new UserTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo);
var repository = new UserRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, utRepo, Mock.Of<IMapperCollection>());
// Act
var user1 = MockedUser.CreateUser(CreateAndCommitUserType(), "1", "test", "media");

View File

@@ -184,7 +184,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateAndCommitMultipleUserTypes(repository, unitOfWork);
// Act
var query = QueryFactory.Create<IUserType>().Where(x => x.Alias == "testUserType1");
var query = unitOfWork.Query<IUserType>().Where(x => x.Alias == "testUserType1");
var result = repository.GetByQuery(query);
// Assert
@@ -265,7 +265,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var userTypes = CreateAndCommitMultipleUserTypes(repository, unitOfWork);
// Act
var query = QueryFactory.Create<IUserType>().Where(x => x.Alias == "testUserType1" || x.Alias == "testUserType2");
var query = unitOfWork.Query<IUserType>().Where(x => x.Alias == "testUserType1" || x.Alias == "testUserType2");
var result = repository.Count(query);
// Assert

View File

@@ -75,7 +75,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
[Test]
public void Format_SqlServer_NonClusteredIndexDefinition_AddsNonClusteredDirective()
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null));
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null));
var indexDefinition = CreateIndexDefinition();
indexDefinition.IndexType = IndexTypes.NonClustered;
@@ -87,7 +87,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
[Test]
public void Format_SqlServer_NonClusteredIndexDefinition_UsingIsClusteredFalse_AddsClusteredDirective()
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null));
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null));
var indexDefinition = CreateIndexDefinition();
indexDefinition.IsClustered = false;
@@ -99,7 +99,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
[Test]
public void CreateIndexBuilder_SqlServer_NonClustered_CreatesNonClusteredIndex()
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null));
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null));
var logger = Mock.Of<ILogger>();
var db = TestObjects.GetUmbracoSqlServerDatabase(logger);
var context = new MigrationContext(db, logger);
@@ -115,7 +115,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
[Test]
public void CreateIndexBuilder_SqlServer_Unique_CreatesUniqueNonClusteredIndex()
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null));
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null));
var logger = Mock.Of<ILogger>();
var db = TestObjects.GetUmbracoSqlServerDatabase(logger);
var context = new MigrationContext(db, logger);
@@ -131,7 +131,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
[Test]
public void CreateIndexBuilder_SqlServer_Clustered_CreatesClusteredIndex()
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null));
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null));
var logger = Mock.Of<ILogger>();
var db = TestObjects.GetUmbracoSqlServerDatabase(logger);
var context = new MigrationContext(db, logger);

View File

@@ -17,7 +17,7 @@ using UmbracoExamine;
namespace Umbraco.Tests.Runtimes
{
[TestFixture]
[Ignore("cannot work until we refactor IDatabaseFactory vs UmbracoDatabaseFactory")]
[Ignore("cannot work until we refactor IUmbracoDatabaseFactory vs UmbracoDatabaseFactory")]
public class CoreRuntimeTests
{
[SetUp]
@@ -98,17 +98,17 @@ namespace Umbraco.Tests.Runtimes
// must override the database factory
// else BootFailedException because U cannot connect to the configured db
private static IDatabaseFactory GetDatabaseFactory()
private static IUmbracoDatabaseFactory GetDatabaseFactory()
{
var mock = new Mock<IDatabaseFactory>();
var mock = new Mock<IUmbracoDatabaseFactory>();
mock.Setup(x => x.Configured).Returns(true);
mock.Setup(x => x.CanConnect).Returns(true);
return mock.Object;
}
// pretend we have the proper migration
// else BootFailedException because our mock IDatabaseFactory does not provide databases
protected override bool EnsureMigration(IDatabaseFactory databaseFactory, SemVersion codeVersion)
// else BootFailedException because our mock IUmbracoDatabaseFactory does not provide databases
protected override bool EnsureMigration(IUmbracoDatabaseFactory databaseFactory, SemVersion codeVersion)
{
return true;
}
@@ -163,7 +163,7 @@ namespace Umbraco.Tests.Runtimes
base.Compose(composition);
composition.Container.Register(factory => SettingsForTests.GetDefault());
composition.Container.Register(factory => new DatabaseContext(factory.GetInstance<IDatabaseFactory>()), new PerContainerLifetime());
composition.Container.Register(factory => new DatabaseContext(factory.GetInstance<IUmbracoDatabaseFactory>()), new PerContainerLifetime());
composition.Container.RegisterSingleton<IExamineIndexCollectionAccessor, TestIndexCollectionAccessor>();
Composed = true;

View File

@@ -1468,8 +1468,7 @@ namespace Umbraco.Tests.Services
new TestDatabaseScopeAccessor(),
Mappers);
var repositoryFactory = MockRepositoryFactory();
var databaseContext = new DatabaseContext(databaseFactory);
var provider = new NPocoUnitOfWorkProvider(databaseContext, repositoryFactory);
var provider = new NPocoUnitOfWorkProvider(databaseFactory, repositoryFactory);
var contentType = ServiceContext.ContentTypeService.Get("umbTextpage");
var root = ServiceContext.ContentService.GetById(NodeDto.NodeIdSeed + 1);
@@ -1477,7 +1476,7 @@ namespace Umbraco.Tests.Services
var c2 = new Lazy<IContent>(() => MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Subpage", c.Value.Id));
var list = new List<Lazy<IContent>> {c, c2};
using (databaseContext.CreateDatabaseScope())
using (databaseFactory.CreateScope())
using (var unitOfWork = provider.CreateUnitOfWork())
{
ContentTypeRepository contentTypeRepository;

View File

@@ -7,6 +7,7 @@ using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
using Umbraco.Core.Persistence;
namespace Umbraco.Tests.Services
{
@@ -129,22 +130,22 @@ namespace Umbraco.Tests.Services
currParentId = desc1.Key;
}
DatabaseContext.Database.EnableSqlTrace = true;
DatabaseContext.Database.EnableSqlCount = true;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlTrace = true;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlCount = true;
var items = ServiceContext.LocalizationService.GetDictionaryItemDescendants(_parentItemGuidId)
.ToArray();
Debug.WriteLine("SQL CALLS: " + DatabaseContext.Database.SqlCount);
Debug.WriteLine("SQL CALLS: " + DatabaseContext.Database.AsUmbracoDatabase().SqlCount);
Assert.AreEqual(51, items.Length);
//there's a call or two to get languages, so apart from that there should only be one call per level
Assert.Less(DatabaseContext.Database.SqlCount, 30);
Assert.Less(DatabaseContext.Database.AsUmbracoDatabase().SqlCount, 30);
}
finally
{
DatabaseContext.Database.EnableSqlTrace = false;
DatabaseContext.Database.EnableSqlCount = false;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlTrace = false;
DatabaseContext.Database.AsUmbracoDatabase().EnableSqlCount = false;
}
}

View File

@@ -1036,7 +1036,7 @@ namespace Umbraco.Tests.Services
result.LastLoginDate.TruncateTo(DateTimeExtensions.DateTruncate.Second));
//now ensure the col is correct
var sql = DatabaseContext.Database.Sql().Select("cmsPropertyData.*")
var sql = DatabaseContext.Sql().Select("cmsPropertyData.*")
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyDataDto, PropertyTypeDto>(dto => dto.PropertyTypeId, dto => dto.Id)

View File

@@ -294,7 +294,7 @@ namespace Umbraco.Tests.Services
DatabaseContext.Database.BulkInsertRecordsWithTransaction(nodes);
//re-get the nodes with ids
var sql = DatabaseContext.Database.Sql();
var sql = DatabaseContext.Sql();
sql.SelectAll().From<NodeDto>().Where<NodeDto>(x => x.NodeObjectType == customObjectType);
nodes = DatabaseContext.Database.Fetch<NodeDto>(sql);

View File

@@ -186,11 +186,11 @@ namespace Umbraco.Tests.Services
}
/// <summary>
/// A special implementation of <see cref="IDatabaseFactory"/> that mimics the UmbracoDatabaseFactory
/// A special implementation of <see cref="IUmbracoDatabaseFactory"/> that mimics the UmbracoDatabaseFactory
/// (one db per HttpContext) by providing one db per thread, as required for multi-threaded
/// tests.
/// </summary>
internal class PerThreadSqlCeDatabaseFactory : DisposableObject, IDatabaseFactory
internal class PerThreadSqlCeDatabaseFactory : DisposableObject, IUmbracoDatabaseFactory
{
// the UmbracoDatabaseFactory uses thread-static databases where there is no http context,
// so it would need to be disposed in each thread in order for each database to be disposed,
@@ -199,7 +199,6 @@ namespace Umbraco.Tests.Services
private readonly ILogger _logger;
private readonly IMapperCollection _mappers;
private IQueryFactory _queryFactory;
private readonly DbProviderFactory _dbProviderFactory =
DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe);
@@ -219,9 +218,14 @@ namespace Umbraco.Tests.Services
throw new NotImplementedException();
}
public IQueryFactory QueryFactory => _queryFactory ?? (_queryFactory = new QueryFactory(SqlSyntax, _mappers));
public Sql<SqlContext> Sql(string sql, params object[] args)
{
throw new NotImplementedException();
}
public DatabaseType DatabaseType => DatabaseType.SQLCe;
public IQuery<T> Query<T>() => new Query<T>(SqlSyntax, _mappers);
public DatabaseType DatabaseType => DatabaseType.SQLCe;
public PerThreadSqlCeDatabaseFactory(ILogger logger, IMapperCollection mappers)
{
@@ -229,9 +233,11 @@ namespace Umbraco.Tests.Services
_mappers = mappers;
}
private readonly ConcurrentDictionary<int, UmbracoDatabase> _databases = new ConcurrentDictionary<int, UmbracoDatabase>();
private readonly ConcurrentDictionary<int, IUmbracoDatabase> _databases = new ConcurrentDictionary<int, IUmbracoDatabase>();
public UmbracoDatabase GetDatabase()
public IUmbracoDatabase Database => GetDatabase();
public IUmbracoDatabase GetDatabase()
{
var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName];
var sqlContext = new SqlContext(SqlSyntax, Mock.Of<IPocoDataFactory>(), DatabaseType);
@@ -239,6 +245,16 @@ namespace Umbraco.Tests.Services
i => new UmbracoDatabase(settings.ConnectionString, sqlContext, _dbProviderFactory, _logger));
}
public IUmbracoDatabase CreateDatabase()
{
throw new NotImplementedException();
}
public IDatabaseScope CreateScope(IUmbracoDatabase database = null)
{
throw new NotImplementedException();
}
protected override void DisposeResources()
{
// dispose the databases

View File

@@ -34,11 +34,6 @@ namespace Umbraco.Tests.Templates
var database = TestObjects.GetUmbracoSqlCeDatabase(logger);
unitOfWorkMock.Setup(x => x.Database).Returns(database);
var databaseFactoryMock = new Mock<IDatabaseFactory>();
databaseFactoryMock.Setup(x => x.QueryFactory).Returns(Mock.Of<IQueryFactory>());
var databaseContext = new DatabaseContext(databaseFactoryMock.Object);
unitOfWorkMock.Setup(x => x.DatabaseContext).Returns(databaseContext);
_templateRepository = new TemplateRepository(unitOfWorkMock.Object, _cacheMock.Object, logger, _masterpageFileSystemMock.Object, _viewFileSystemMock.Object, _templateConfigMock.Object);
}

View File

@@ -23,15 +23,15 @@ namespace Umbraco.Tests.TestHelpers
internal partial class TestObjects
{
/// <summary>
/// Gets a mocked IDatabaseFactory.
/// Gets a mocked IUmbracoDatabaseFactory.
/// </summary>
/// <returns>An IDatabaseFactory.</returns>
/// <returns>An IUmbracoDatabaseFactory.</returns>
/// <param name="configured">A value indicating whether the factory is configured.</param>
/// <param name="canConnect">A value indicating whether the factory can connect to the database.</param>
/// <remarks>This is just a void factory that has no actual database.</remarks>
public IDatabaseFactory GetDatabaseFactoryMock(bool configured = true, bool canConnect = true)
public IUmbracoDatabaseFactory GetDatabaseFactoryMock(bool configured = true, bool canConnect = true)
{
var databaseFactoryMock = new Mock<IDatabaseFactory>();
var databaseFactoryMock = new Mock<IUmbracoDatabaseFactory>();
databaseFactoryMock.Setup(x => x.Configured).Returns(configured);
databaseFactoryMock.Setup(x => x.CanConnect).Returns(canConnect);

View File

@@ -42,13 +42,13 @@ namespace Umbraco.Tests.TestHelpers
/// <param name="logger">A logger.</param>
/// <param name="lazyFactory">A (lazy) database factory.</param>
/// <returns>The default ISqlSyntaxProvider objects.</returns>
public IEnumerable<ISqlSyntaxProvider> GetDefaultSqlSyntaxProviders(ILogger logger, Lazy<IDatabaseFactory> lazyFactory = null)
public IEnumerable<ISqlSyntaxProvider> GetDefaultSqlSyntaxProviders(ILogger logger, Lazy<IUmbracoDatabaseFactory> lazyFactory = null)
{
return new ISqlSyntaxProvider[]
{
new MySqlSyntaxProvider(logger),
new SqlCeSyntaxProvider(),
new SqlServerSyntaxProvider(lazyFactory ?? new Lazy<IDatabaseFactory>(() => null))
new SqlServerSyntaxProvider(lazyFactory ?? new Lazy<IUmbracoDatabaseFactory>(() => null))
};
}
@@ -76,7 +76,7 @@ namespace Umbraco.Tests.TestHelpers
/// that can begin a transaction.</remarks>
public UmbracoDatabase GetUmbracoSqlServerDatabase(ILogger logger)
{
var syntax = new SqlServerSyntaxProvider(new Lazy<IDatabaseFactory>(() => null)); // do NOT try to get the server's version!
var syntax = new SqlServerSyntaxProvider(new Lazy<IUmbracoDatabaseFactory>(() => null)); // do NOT try to get the server's version!
var connection = GetDbConnection();
var sqlContext = new SqlContext(syntax, Mock.Of<IPocoDataFactory>(), DatabaseType.SqlServer2008);
return new UmbracoDatabase(connection, sqlContext, logger);
@@ -105,7 +105,6 @@ namespace Umbraco.Tests.TestHelpers
CacheHelper cache,
ILogger logger,
IEventMessagesFactory eventMessagesFactory,
IQueryFactory queryFactory,
IEnumerable<IUrlSegmentProvider> urlSegmentProviders,
IServiceFactory container = null)
{
@@ -224,7 +223,7 @@ namespace Umbraco.Tests.TestHelpers
return new Lazy<T>(() => container?.TryGetInstance<T>() ?? ctor());
}
public IDatabaseUnitOfWorkProvider GetDatabaseUnitOfWorkProvider(ILogger logger, IDatabaseFactory databaseFactory = null, RepositoryFactory repositoryFactory = null)
public IDatabaseUnitOfWorkProvider GetDatabaseUnitOfWorkProvider(ILogger logger, IUmbracoDatabaseFactory databaseFactory = null, RepositoryFactory repositoryFactory = null)
{
if (databaseFactory == null)
{
@@ -236,7 +235,7 @@ namespace Umbraco.Tests.TestHelpers
databaseFactory = new UmbracoDatabaseFactory(GlobalSettings.UmbracoConnectionName, GetDefaultSqlSyntaxProviders(logger), logger, accessor, mappers);
}
repositoryFactory = repositoryFactory ?? new RepositoryFactory(Mock.Of<IServiceContainer>());
return new NPocoUnitOfWorkProvider(new DatabaseContext(databaseFactory), repositoryFactory);
return new NPocoUnitOfWorkProvider(databaseFactory, repositoryFactory);
}
}
}

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