Moved scope and persistence

This commit is contained in:
Bjarke Berg
2019-12-12 08:11:23 +01:00
parent 9e5494cc14
commit c94b65d76b
110 changed files with 250 additions and 272 deletions

View File

@@ -24,7 +24,8 @@ namespace Umbraco.Core
IRuntimeState state,
ITypeFinder typeFinder,
IIOHelper ioHelper,
IUmbracoVersion umbracoVersion)
IUmbracoVersion umbracoVersion,
IDbProviderFactoryCreator dbProviderFactoryCreator)
{
composition.RegisterUnique(logger);
composition.RegisterUnique(profiler);
@@ -39,6 +40,7 @@ namespace Umbraco.Core
composition.RegisterUnique(typeFinder);
composition.RegisterUnique(ioHelper);
composition.RegisterUnique(umbracoVersion);
composition.RegisterUnique(dbProviderFactoryCreator);
}
}
}

View File

@@ -29,6 +29,7 @@ namespace Umbraco.Core.Migrations.Install
private readonly ILogger _logger;
private readonly IIOHelper _ioHelper;
private readonly IUmbracoVersion _umbracoVersion;
private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator;
private DatabaseSchemaResult _databaseSchemaValidationResult;
@@ -44,7 +45,8 @@ namespace Umbraco.Core.Migrations.Install
IMigrationBuilder migrationBuilder,
IKeyValueService keyValueService,
IIOHelper ioHelper,
IUmbracoVersion umbracoVersion)
IUmbracoVersion umbracoVersion,
IDbProviderFactoryCreator dbProviderFactoryCreator)
{
_scopeProvider = scopeProvider;
_globalSettings = globalSettings;
@@ -55,6 +57,7 @@ namespace Umbraco.Core.Migrations.Install
_keyValueService = keyValueService;
_ioHelper = ioHelper;
_umbracoVersion = umbracoVersion;
_dbProviderFactoryCreator = dbProviderFactoryCreator;
}
#region Status
@@ -99,7 +102,8 @@ namespace Umbraco.Core.Migrations.Install
databaseType, out providerName);
}
return DbConnectionExtensions.IsConnectionAvailable(connectionString, providerName);
var factory = _dbProviderFactoryCreator.CreateFactory(providerName);
return DbConnectionExtensions.IsConnectionAvailable(connectionString, factory);
}
internal bool HasSomeNonDefaultUser()

View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using NPoco;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence
{
/// <summary>
/// Provides extension methods to NPoco Database class.
/// </summary>
public static class NPocoDatabaseExtensionsSqlCe
{
/// <summary>
/// Bulk-insert records using SqlCE TableDirect method.
/// </summary>
/// <typeparam name="T">The type of the records.</typeparam>
/// <param name="database">The database.</param>
/// <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>(IUmbracoDatabase database, PocoData pocoData, IEnumerable<T> records)
{
var columns = pocoData.Columns.ToArray();
// create command against the original database.Connection
using (var command = database.CreateCommand(database.Connection, CommandType.TableDirect, string.Empty))
{
command.CommandText = pocoData.TableInfo.TableName;
command.CommandType = CommandType.TableDirect; // TODO: why repeat?
// TODO: not supporting transactions?
//cmd.Transaction = GetTypedTransaction<SqlCeTransaction>(db.Connection.);
var count = 0;
var tCommand = NPocoDatabaseExtensions.GetTypedCommand<SqlCeCommand>(command); // execute on the real command
// seems to cause problems, I think this is primarily used for retrieval, not inserting.
// see: https://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlcecommand.indexname%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396
//tCommand.IndexName = pd.TableInfo.PrimaryKey;
using (var resultSet = tCommand.ExecuteResultSet(ResultSetOptions.Updatable))
{
var updatableRecord = resultSet.CreateRecord();
foreach (var record in records)
{
for (var i = 0; i < columns.Length; i++)
{
// skip the index if this shouldn't be included (i.e. PK)
if (NPocoDatabaseExtensions.IncludeColumn(pocoData, columns[i]))
{
var val = columns[i].Value.GetValue(record);
updatableRecord.SetValue(i, val);
}
}
resultSet.Insert(updatableRecord);
count++;
}
}
return count;
}
}
}
}

View File

@@ -28,7 +28,7 @@ namespace Umbraco.Core.Runtime
private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker;
public CoreRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IUmbracoBootPermissionChecker umbracoBootPermissionChecker, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
public CoreRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IUmbracoBootPermissionChecker umbracoBootPermissionChecker, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo, IDbProviderFactoryCreator dbProviderFactoryCreator)
{
IOHelper = ioHelper;
Configs = configs;
@@ -36,6 +36,7 @@ namespace Umbraco.Core.Runtime
Profiler = profiler;
HostingEnvironment = hostingEnvironment;
BackOfficeInfo = backOfficeInfo;
DbProviderFactoryCreator = dbProviderFactoryCreator;
_umbracoBootPermissionChecker = umbracoBootPermissionChecker;
@@ -59,6 +60,7 @@ namespace Umbraco.Core.Runtime
protected ILogger Logger { get; }
protected IBackOfficeInfo BackOfficeInfo { get; }
public IDbProviderFactoryCreator DbProviderFactoryCreator { get; }
/// <summary>
/// Gets the profiler.
@@ -155,7 +157,7 @@ namespace Umbraco.Core.Runtime
// create the composition
composition = new Composition(register, typeLoader, ProfilingLogger, _state, Configs, IOHelper, appCaches);
composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, mainDom, appCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion);
composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, mainDom, appCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion, DbProviderFactoryCreator);
// run handlers
RuntimeOptions.DoRuntimeEssentials(composition, appCaches, typeLoader, databaseFactory);
@@ -363,7 +365,7 @@ namespace Umbraco.Core.Runtime
/// </summary>
/// <remarks>This is strictly internal, for tests only.</remarks>
protected internal virtual IUmbracoDatabaseFactory GetDatabaseFactory()
=> new UmbracoDatabaseFactory(Logger, new Lazy<IMapperCollection>(() => _factory.GetInstance<IMapperCollection>()), Configs);
=> new UmbracoDatabaseFactory(Logger, new Lazy<IMapperCollection>(() => _factory.GetInstance<IMapperCollection>()), Configs, DbProviderFactoryCreator);
#endregion

View File

@@ -91,7 +91,7 @@
</PackageReference>
<PackageReference Include="MiniProfiler" Version="4.0.138" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="NPoco" Version="3.9.4" />
<PackageReference Include="NPoco" Version="4.0.2" />
<PackageReference Include="Serilog">
<Version>2.9.0</Version>
</PackageReference>
@@ -200,7 +200,10 @@
<Compile Include="Models\UserExtensions.cs" />
<Compile Include="Packaging\PackageDataInstallation.cs" />
<Compile Include="Packaging\PackageInstallation.cs" />
<Compile Include="Persistence\Mappers\MapperCollectionBuilder.cs" />
<Compile Include="Persistence\Mappers\SimpleContentTypeMapper.cs" />
<Compile Include="Persistence\NPocoDatabaseExtensionsSqlCe.cs" />
<Compile Include="Persistence\SqlSyntax\SqlCeSyntaxProvider.cs" />
<Compile Include="PropertyEditors\DataValueReferenceFactoryCollection.cs" />
<Compile Include="PropertyEditors\DataValueReferenceFactoryCollectionBuilder.cs" />
<Compile Include="PropertyEditors\IDataValueReference.cs" />
@@ -212,6 +215,12 @@
<Compile Include="Persistence\Repositories\Implement\LanguageRepositoryExtensions.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\RenameLabelAndRichTextPropertyEditorAliases.cs" />
<Compile Include="PublishedContentExtensions.cs" />
<Compile Include="Scoping\IScopeAccessor.cs" />
<Compile Include="Scoping\Scope.cs" />
<Compile Include="Scoping\ScopeContext.cs" />
<Compile Include="Scoping\ScopeContextualBase.cs" />
<Compile Include="Scoping\ScopeProvider.cs" />
<Compile Include="Scoping\ScopeReference.cs" />
<Compile Include="Security\PasswordSecurity.cs" />
<Compile Include="Services\Implement\PropertyValidationService.cs" />
<Compile Include="StringExtensions.cs" />
@@ -287,9 +296,6 @@
<Compile Include="Persistence\Mappers\ConsentMapper.cs" />
<Compile Include="Persistence\Repositories\Implement\AuditEntryRepository.cs" />
<Compile Include="Persistence\Repositories\Implement\ConsentRepository.cs" />
<Compile Include="Persistence\SqlContextExtensions.cs" />
<Compile Include="Persistence\SqlSyntaxExtensions.cs" />
<Compile Include="Persistence\UmbracoPocoDataBuilder.cs" />
<Compile Include="RuntimeOptions.cs" />
<Compile Include="Runtime\CoreRuntime.cs" />
<Compile Include="Runtime\CoreInitialComponent.cs" />
@@ -340,7 +346,6 @@
<Compile Include="Persistence\Dtos\Member2MemberGroupDto.cs" />
<Compile Include="Persistence\Dtos\MemberDto.cs" />
<Compile Include="Persistence\Dtos\MemberPropertyTypeDto.cs" />
<Compile Include="Persistence\Dtos\NodeDto.cs" />
<Compile Include="Persistence\Dtos\PropertyDataDto.cs" />
<Compile Include="Persistence\Dtos\PropertyTypeDto.cs" />
<Compile Include="Persistence\Dtos\PropertyTypeGroupDto.cs" />
@@ -355,39 +360,9 @@
<Compile Include="Persistence\Dtos\TemplateDto.cs" />
<Compile Include="Persistence\Dtos\User2NodeNotifyDto.cs" />
<Compile Include="Persistence\Dtos\User2UserGroupDto.cs" />
<Compile Include="Persistence\Dtos\UserDto.cs" />
<Compile Include="Persistence\Dtos\UserGroup2AppDto.cs" />
<Compile Include="Persistence\Dtos\UserGroup2NodePermissionDto.cs" />
<Compile Include="Persistence\Dtos\UserGroupDto.cs" />
<Compile Include="Persistence\Dtos\UserStartNodeDto.cs" />
<Compile Include="Persistence\BulkDataReader.cs" />
<Compile Include="Persistence\DatabaseAnnotations\ConstraintAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\ForeignKeyAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\IndexAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\IndexTypes.cs" />
<Compile Include="Persistence\DatabaseAnnotations\LengthAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\NullSettingAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\NullSettings.cs" />
<Compile Include="Persistence\DatabaseAnnotations\PrimaryKeyColumnAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\ReferencesAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\SpecialDbTypeAttribute.cs" />
<Compile Include="Persistence\DatabaseAnnotations\SpecialDbTypes.cs" />
<Compile Include="Persistence\DatabaseDebugHelper.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\ColumnDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\ConstraintDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\ConstraintType.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\DbIndexDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\DefinitionFactory.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\DeletionDataDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\ForeignKeyDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\IndexColumnDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\IndexDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\InsertionDataDefinition.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\ModificationType.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\SystemMethods.cs" />
<Compile Include="Persistence\DatabaseModelDefinitions\TableDefinition.cs" />
<Compile Include="Persistence\DbCommandExtensions.cs" />
<Compile Include="Persistence\DbConnectionExtensions.cs" />
<Compile Include="Persistence\EntityNotFoundException.cs" />
<Compile Include="Persistence\Factories\ContentTypeFactory.cs" />
<Compile Include="Persistence\Factories\DataTypeFactory.cs" />
@@ -407,24 +382,8 @@
<Compile Include="Persistence\Factories\TemplateFactory.cs" />
<Compile Include="Persistence\Factories\UserFactory.cs" />
<Compile Include="Persistence\Factories\UserGroupFactory.cs" />
<Compile Include="Persistence\FaultHandling\ITransientErrorDetectionStrategy.cs" />
<Compile Include="Persistence\FaultHandling\RetryingEventArgs.cs" />
<Compile Include="Persistence\FaultHandling\RetryLimitExceededException.cs" />
<Compile Include="Persistence\FaultHandling\RetryPolicy.cs" />
<Compile Include="Persistence\FaultHandling\RetryPolicyFactory.cs" />
<Compile Include="Persistence\FaultHandling\RetryStrategy.cs" />
<Compile Include="Persistence\FaultHandling\Strategies\ExponentialBackoff.cs" />
<Compile Include="Persistence\FaultHandling\Strategies\FixedInterval.cs" />
<Compile Include="Persistence\FaultHandling\Strategies\Incremental.cs" />
<Compile Include="Persistence\FaultHandling\Strategies\NetworkConnectivityErrorDetectionStrategy.cs" />
<Compile Include="Persistence\FaultHandling\Strategies\SqlAzureTransientErrorDetectionStrategy.cs" />
<Compile Include="Persistence\FaultHandling\ThrottlingCondition.cs" />
<Compile Include="Persistence\ISqlContext.cs" />
<Compile Include="Persistence\IUmbracoDatabase.cs" />
<Compile Include="Persistence\IUmbracoDatabaseFactory.cs" />
<Compile Include="Persistence\LocalDb.cs" />
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
<Compile Include="Persistence\Mappers\BaseMapper.cs" />
<Compile Include="Persistence\Mappers\ContentMapper.cs" />
<Compile Include="Persistence\Mappers\ContentTypeMapper.cs" />
<Compile Include="Persistence\Mappers\DataTypeMapper.cs" />
@@ -432,18 +391,13 @@
<Compile Include="Persistence\Mappers\DictionaryTranslationMapper.cs" />
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
<Compile Include="Persistence\Mappers\ExternalLoginMapper.cs" />
<Compile Include="Persistence\Mappers\IMapperCollection.cs" />
<Compile Include="Persistence\Mappers\LanguageMapper.cs" />
<Compile Include="Persistence\Mappers\MacroMapper.cs" />
<Compile Include="Persistence\Mappers\MapperCollection.cs" />
<Compile Include="Persistence\Mappers\MapperCollectionBuilder.cs" />
<Compile Include="Persistence\Mappers\MapperForAttribute.cs" />
<Compile Include="Persistence\Mappers\MediaMapper.cs" />
<Compile Include="Persistence\Mappers\MediaTypeMapper.cs" />
<Compile Include="Persistence\Mappers\MemberGroupMapper.cs" />
<Compile Include="Persistence\Mappers\MemberMapper.cs" />
<Compile Include="Persistence\Mappers\MemberTypeMapper.cs" />
<Compile Include="Persistence\Mappers\PocoMapper.cs" />
<Compile Include="Persistence\Mappers\PropertyGroupMapper.cs" />
<Compile Include="Persistence\Mappers\PropertyMapper.cs" />
<Compile Include="Persistence\Mappers\PropertyTypeMapper.cs" />
@@ -565,21 +519,6 @@
<Compile Include="Migrations\Upgrade\V_8_0_0\AddLockObjects.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\VariantsMigration.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\ContentVariationMigration.cs" />
<Compile Include="Persistence\NPocoDatabaseExtensions-Bulk.cs" />
<Compile Include="Persistence\NPocoDatabaseExtensions.cs" />
<Compile Include="Persistence\NPocoDatabaseTypeExtensions.cs" />
<Compile Include="Persistence\NPocoSqlExtensions.cs" />
<Compile Include="Persistence\PocoDataDataReader.cs" />
<Compile Include="Persistence\Querying\CachedExpression.cs" />
<Compile Include="Persistence\Querying\ExpressionVisitorBase.cs" />
<Compile Include="Persistence\Querying\ModelToSqlExpressionVisitor.cs" />
<Compile Include="Persistence\Querying\PocoToSqlExpressionVisitor.cs" />
<Compile Include="Persistence\Querying\Query.cs" />
<Compile Include="Persistence\Querying\QueryExtensions.cs" />
<Compile Include="Persistence\Querying\SqlExpressionExtensions.cs" />
<Compile Include="Persistence\Querying\SqlTranslator.cs" />
<Compile Include="Persistence\Querying\TextColumnType.cs" />
<Compile Include="Persistence\RecordPersistenceType.cs" />
<Compile Include="Persistence\Repositories\Implement\AuditRepository.cs" />
<Compile Include="Persistence\Repositories\Implement\DocumentBlueprintRepository.cs" />
<Compile Include="Persistence\Repositories\Implement\DocumentRepository.cs" />
@@ -637,33 +576,10 @@
<Compile Include="Persistence\Repositories\Implement\UserGroupRepository.cs" />
<Compile Include="Persistence\Repositories\Implement\UserRepository.cs" />
<Compile Include="Persistence\Repositories\Implement\ContentRepositoryBase.cs" />
<Compile Include="Persistence\SqlContext.cs" />
<Compile Include="Persistence\SqlSyntax\ColumnInfo.cs" />
<Compile Include="Persistence\SqlSyntax\DbTypes.cs" />
<Compile Include="Persistence\SqlSyntax\ISqlSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\MicrosoftSqlSyntaxProviderBase.cs" />
<Compile Include="Persistence\SqlSyntax\SqlCeSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlServerSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlServerVersionName.cs" />
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderBase.cs" />
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderExtensions.cs" />
<Compile Include="Persistence\SqlTemplate.cs" />
<Compile Include="Persistence\SqlTemplates.cs" />
<Compile Include="Persistence\UmbracoDatabase.cs" />
<Compile Include="Persistence\UmbracoDatabaseExtensions.cs" />
<Compile Include="Persistence\UmbracoDatabaseFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RuntimeState.cs" />
<Compile Include="Runtime\CoreInitialComposer.cs" />
<Compile Include="Scoping\IScope.cs" />
<Compile Include="Scoping\IScopeAccessor.cs" />
<Compile Include="Scoping\IScopeProvider.cs" />
<Compile Include="Scoping\RepositoryCacheMode.cs" />
<Compile Include="Scoping\Scope.cs" />
<Compile Include="Scoping\ScopeContext.cs" />
<Compile Include="Scoping\ScopeContextualBase.cs" />
<Compile Include="Scoping\ScopeProvider.cs" />
<Compile Include="Scoping\ScopeReference.cs" />
<Compile Include="Security\AuthenticationExtensions.cs" />
<Compile Include="Security\BackOfficeUserStore.cs" />
<Compile Include="Security\BackOfficeUserValidator.cs" />
@@ -718,9 +634,6 @@
<Compile Include="Sync\ServerMessengerBase.cs" />
<Compile Include="TypeExtensions.cs" />
<Compile Include="UriExtensions.cs" />
<Compile Include="Persistence\FaultHandling\RetryDbConnection.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="..\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link>
</Compile>
@@ -741,5 +654,11 @@
<Name>Umbraco.Infrastructure</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Persistence\DatabaseAnnotations" />
<Folder Include="Persistence\DatabaseModelDefinitions" />
<Folder Include="Persistence\FaultHandling" />
<Folder Include="Persistence\Querying" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -56,7 +56,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="NPoco" Version="3.9.4" />
<PackageReference Include="NPoco" Version="4.0.2" />
<PackageReference Include="SecurityCodeScan">
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

View File

@@ -2,10 +2,9 @@
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using StackExchange.Profiling.Data;
using Umbraco.Core.Composing;
using Umbraco.Composing;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.FaultHandling;
@@ -28,17 +27,13 @@ namespace Umbraco.Core.Persistence
return Constants.DbProviderNames.SqlServer;
}
public static bool IsConnectionAvailable(string connectionString, string providerName)
public static bool IsConnectionAvailable(string connectionString, DbProviderFactory factory)
{
if (providerName != Constants.DbProviderNames.SqlCe
&& providerName != Constants.DbProviderNames.SqlServer)
throw new NotSupportedException($"Provider \"{providerName}\" is not supported.");
var factory = DbProviderFactories.GetFactory(providerName);
var connection = factory.CreateConnection();
if (connection == null)
throw new InvalidOperationException($"Could not create a connection for provider \"{providerName}\".");
throw new InvalidOperationException($"Could not create a connection for provider \"{factory}\".");
connection.ConnectionString = connectionString;
using (connection)
@@ -47,6 +42,7 @@ namespace Umbraco.Core.Persistence
}
}
public static bool IsAvailable(this IDbConnection connection)
{
try
@@ -95,11 +91,13 @@ namespace Umbraco.Core.Persistence
var builder = new SqlConnectionStringBuilder(connection.ConnectionString);
return $"DataSource: {builder.DataSource}, InitialCatalog: {builder.InitialCatalog}";
}
case SqlCeConnection _:
{
var builder = new SqlCeConnectionStringBuilder(connection.ConnectionString);
return $"DataSource: {builder.DataSource}";
}
// case SqlCeConnection _:
// {
// var builder = new SqlCeConnectionStringBuilder(connection.ConnectionString);
// return $"DataSource: {builder.DataSource}";
// }
default:
throw new NotSupportedException("TODO"); //TODO fix SqlCeConnection
}
}
catch (Exception ex)

View File

@@ -8,7 +8,7 @@ namespace Umbraco.Core.Persistence.Dtos
[TableName(TableName)]
[PrimaryKey("id")]
[ExplicitColumns]
internal class NodeDto
public class NodeDto
{
public const string TableName = Constants.DatabaseSchema.Tables.Node;
public const int NodeIdSeed = 1060;

View File

@@ -143,14 +143,14 @@ namespace Umbraco.Core.Persistence.FaultHandling.Strategies
{
return true;
}
else
{
EntityException entityException;
if ((entityException = ex as EntityException) != null)
{
return this.IsTransient(entityException.InnerException);
}
}
// else
// {
// EntityException entityException;
// if ((entityException = ex as EntityException) != null)
// {
// return this.IsTransient(entityException.InnerException);
// }
// }
}
return false;

View File

@@ -0,0 +1,11 @@
using System.Data.Common;
using StackExchange.Profiling.Internal;
namespace Umbraco.Core.Persistence
{
public interface IDbProviderFactoryCreator
{
DbProviderFactory CreateFactory();
DbProviderFactory CreateFactory(string providerName);
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using NPoco;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -26,6 +25,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static void ConfigureNPocoBulkExtensions()
{
SqlBulkCopyHelper.SqlConnectionResolver = dbConn => GetTypedConnection<SqlConnection>(dbConn);
SqlBulkCopyHelper.SqlTransactionResolver = dbTran => GetTypedTransaction<SqlTransaction>(dbTran);
}
@@ -67,14 +67,15 @@ namespace Umbraco.Core.Persistence
var pocoData = database.PocoDataFactory.ForType(typeof(T));
if (pocoData == null) throw new InvalidOperationException("Could not find PocoData for " + typeof(T));
if (database.DatabaseType.IsSqlCe())
{
if (useNativeBulkInsert) return BulkInsertRecordsSqlCe(database, pocoData, recordsA);
// else, no other choice
foreach (var record in recordsA)
database.Insert(record);
return recordsA.Length;
}
// if (database.DatabaseType.IsSqlCe())
// {
// if (useNativeBulkInsert) return BulkInsertRecordsSqlCe(database, pocoData, recordsA);
// // else, no other choice
// foreach (var record in recordsA)
// database.Insert(record);
// return recordsA.Length;
// }
//TODO FIX Sql CE
if (database.DatabaseType.IsSqlServer())
{
@@ -166,61 +167,12 @@ namespace Umbraco.Core.Persistence
/// <param name="column">The column.</param>
/// <returns>A value indicating whether the column should be part of the bulk-insert.</returns>
/// <remarks>Columns that are primary keys and auto-incremental, or result columns, are excluded from bulk-inserts.</remarks>
private static bool IncludeColumn(PocoData pocoData, KeyValuePair<string, PocoColumn> column)
public static bool IncludeColumn(PocoData pocoData, KeyValuePair<string, PocoColumn> column)
{
return column.Value.ResultColumn == false
&& (pocoData.TableInfo.AutoIncrement == false || column.Key != pocoData.TableInfo.PrimaryKey);
}
/// <summary>
/// Bulk-insert records using SqlCE TableDirect method.
/// </summary>
/// <typeparam name="T">The type of the records.</typeparam>
/// <param name="database">The database.</param>
/// <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>(IUmbracoDatabase database, PocoData pocoData, IEnumerable<T> records)
{
var columns = pocoData.Columns.ToArray();
// create command against the original database.Connection
using (var command = database.CreateCommand(database.Connection, CommandType.TableDirect, string.Empty))
{
command.CommandText = pocoData.TableInfo.TableName;
command.CommandType = CommandType.TableDirect; // TODO: why repeat?
// TODO: not supporting transactions?
//cmd.Transaction = GetTypedTransaction<SqlCeTransaction>(db.Connection.);
var count = 0;
var tCommand = GetTypedCommand<SqlCeCommand>(command); // execute on the real command
// seems to cause problems, I think this is primarily used for retrieval, not inserting.
// see: https://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlcecommand.indexname%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396
//tCommand.IndexName = pd.TableInfo.PrimaryKey;
using (var resultSet = tCommand.ExecuteResultSet(ResultSetOptions.Updatable))
{
var updatableRecord = resultSet.CreateRecord();
foreach (var record in records)
{
for (var i = 0; i < columns.Length; i++)
{
// skip the index if this shouldn't be included (i.e. PK)
if (IncludeColumn(pocoData, columns[i]))
{
var val = columns[i].Value.GetValue(record);
updatableRecord.SetValue(i, val);
}
}
resultSet.Insert(updatableRecord);
count++;
}
}
return count;
}
}
/// <summary>
/// Bulk-insert records using SqlServer BulkCopy method.

View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using System.Text.RegularExpressions;
using NPoco;
using StackExchange.Profiling.Data;
@@ -49,7 +46,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 IUmbracoDatabase db, T poco)
public static RecordPersistenceType InsertOrUpdate<T>(this IUmbracoDatabase db, T poco)
where T : class
{
return db.InsertOrUpdate(poco, null, null);
@@ -72,7 +69,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 IUmbracoDatabase db,
public static RecordPersistenceType InsertOrUpdate<T>(this IUmbracoDatabase db,
T poco,
string updateCommand,
object updateArgs)
@@ -197,7 +194,7 @@ namespace Umbraco.Core.Persistence
/// <typeparam name="TCommand"></typeparam>
/// <param name="command"></param>
/// <returns></returns>
private static TCommand GetTypedCommand<TCommand>(IDbCommand command)
public static TCommand GetTypedCommand<TCommand>(IDbCommand command)
where TCommand : class, IDbCommand
{
var c = command;

View File

@@ -1165,19 +1165,19 @@ namespace Umbraco.Core.Persistence
return string.IsNullOrWhiteSpace(attr?.Name) ? column.Name : attr.Name;
}
internal static string ToText(this Sql sql)
public static string ToText(this Sql sql)
{
var text = new StringBuilder();
sql.ToText(text);
return text.ToString();
}
internal static void ToText(this Sql sql, StringBuilder text)
public static void ToText(this Sql sql, StringBuilder text)
{
ToText(sql.SQL, sql.Arguments, text);
}
internal static void ToText(string sql, object[] arguments, StringBuilder text)
public static void ToText(string sql, object[] arguments, StringBuilder text)
{
text.AppendLine(sql);

View File

@@ -1,6 +1,6 @@
namespace Umbraco.Core.Persistence
{
internal enum RecordPersistenceType
public enum RecordPersistenceType
{
Insert,
Update,

View File

@@ -16,9 +16,9 @@ namespace Umbraco.Core.Persistence.SqlSyntax
/// </summary>
public class SqlServerSyntaxProvider : MicrosoftSqlSyntaxProviderBase<SqlServerSyntaxProvider>
{
internal ServerVersionInfo ServerVersion { get; private set; }
public ServerVersionInfo ServerVersion { get; private set; }
internal enum VersionName
public enum VersionName
{
Invalid = -1,
Unknown = 0,
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
Other = 99
}
internal enum EngineEdition
public enum EngineEdition
{
Unknown = 0,
Desktop = 1,
@@ -43,7 +43,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
Azure = 5
}
internal class ServerVersionInfo
public class ServerVersionInfo
{
public ServerVersionInfo()
{
@@ -102,7 +102,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
internal ServerVersionInfo GetSetVersion(string connectionString, string providerName, ILogger logger)
{
var factory = DbProviderFactories.GetFactory(providerName);
//var factory = DbProviderFactories.GetFactory(providerName);
var factory = SqlClientFactory.Instance;
var connection = factory.CreateConnection();
if (connection == null)

View File

@@ -1,5 +1,6 @@
using System;
using System.Data.Common;
using System.Data.SqlClient;
using System.Threading;
using NPoco;
using NPoco.FluentMappings;
@@ -26,6 +27,8 @@ namespace Umbraco.Core.Persistence
// TODO: this class needs not be disposable!
internal class UmbracoDatabaseFactory : DisposableObjectSlim, IUmbracoDatabaseFactory
{
private readonly Configs _configs;
private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator;
private readonly Lazy<IMapperCollection> _mappers;
private readonly ILogger _logger;
@@ -51,20 +54,24 @@ namespace Umbraco.Core.Persistence
/// Initializes a new instance of the <see cref="UmbracoDatabaseFactory"/>.
/// </summary>
/// <remarks>Used by core runtime.</remarks>
public UmbracoDatabaseFactory(ILogger logger, Lazy<IMapperCollection> mappers, Configs configs)
: this(Constants.System.UmbracoConnectionName, logger, mappers, configs)
{ }
public UmbracoDatabaseFactory(ILogger logger, Lazy<IMapperCollection> mappers, Configs configs, IDbProviderFactoryCreator dbProviderFactoryCreator)
: this(Constants.System.UmbracoConnectionName, logger, mappers, configs, dbProviderFactoryCreator)
{
_configs = configs;
}
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoDatabaseFactory"/>.
/// </summary>
/// <remarks>Used by the other ctor and in tests.</remarks>
public UmbracoDatabaseFactory(string connectionStringName, ILogger logger, Lazy<IMapperCollection> mappers, Configs configs)
public UmbracoDatabaseFactory(string connectionStringName, ILogger logger, Lazy<IMapperCollection> mappers, Configs configs, IDbProviderFactoryCreator dbProviderFactoryCreator)
{
if (connectionStringName == null) throw new ArgumentNullException(nameof(connectionStringName));
if (string.IsNullOrWhiteSpace(connectionStringName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(connectionStringName));
_mappers = mappers ?? throw new ArgumentNullException(nameof(mappers));
_configs = configs;
_dbProviderFactoryCreator = dbProviderFactoryCreator ?? throw new ArgumentNullException(nameof(dbProviderFactoryCreator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
var settings = configs.ConnectionStrings()[connectionStringName];
@@ -130,13 +137,13 @@ namespace Umbraco.Core.Persistence
public bool CanConnect =>
// actually tries to connect to the database (regardless of configured/initialized)
!_connectionString.IsNullOrWhiteSpace() && !_providerName.IsNullOrWhiteSpace() &&
DbConnectionExtensions.IsConnectionAvailable(_connectionString, _providerName);
DbConnectionExtensions.IsConnectionAvailable(_connectionString, _dbProviderFactory);
private void UpdateSqlServerDatabaseType()
{
// replace NPoco database type by a more efficient one
var setting = Current.Configs.Global().DatabaseFactoryServerVersion;
var setting = _configs.Global().DatabaseFactoryServerVersion;
var fromSettings = false;
if (setting.IsNullOrWhiteSpace() || !setting.StartsWith("SqlServer.")
@@ -214,16 +221,18 @@ namespace Umbraco.Core.Persistence
if (_connectionString.IsNullOrWhiteSpace()) throw new InvalidOperationException("The factory has not been configured with a proper connection string.");
if (_providerName.IsNullOrWhiteSpace()) throw new InvalidOperationException("The factory has not been configured with a proper provider name.");
_dbProviderFactory = _dbProviderFactoryCreator.CreateFactory(_providerName);
if (_dbProviderFactory == null)
throw new Exception($"Can't find a provider factory for provider name \"{_providerName}\".");
// cannot initialize without being able to talk to the database
if (!DbConnectionExtensions.IsConnectionAvailable(_connectionString, _providerName))
if (!DbConnectionExtensions.IsConnectionAvailable(_connectionString, _dbProviderFactory))
throw new Exception("Cannot connect to the database.");
_connectionRetryPolicy = RetryPolicyFactory.GetDefaultSqlConnectionRetryPolicyByConnectionString(_connectionString);
_commandRetryPolicy = RetryPolicyFactory.GetDefaultSqlCommandRetryPolicyByConnectionString(_connectionString);
_dbProviderFactory = DbProviderFactories.GetFactory(_providerName);
if (_dbProviderFactory == null)
throw new Exception($"Can't find a provider factory for provider name \"{_providerName}\".");
_databaseType = DatabaseType.Resolve(_dbProviderFactory.GetType().Name, _providerName);
if (_databaseType == null)
throw new Exception($"Can't find an NPoco database type for provider name \"{_providerName}\".");
@@ -272,8 +281,8 @@ namespace Umbraco.Core.Persistence
{
switch (providerName)
{
case Constants.DbProviderNames.SqlCe:
return new SqlCeSyntaxProvider();
// case Constants.DbProviderNames.SqlCe:
// return new SqlCeSyntaxProvider();
case Constants.DbProviderNames.SqlServer:
return new SqlServerSyntaxProvider();
default:

View File

@@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="LightInject" Version="6.2.0" />
<PackageReference Include="LightInject.Annotation" Version="1.1.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19554-01" />
<PackageReference Include="MiniProfiler.Shared" Version="4.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
@@ -20,6 +21,7 @@
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Map" Version="1.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.0" />
</ItemGroup>
<ItemGroup>
@@ -31,49 +33,10 @@
<Compile Remove="Scoping\ScopeReference.cs" />
<Compile Remove="Scoping\ScopeProvider.cs" />
<Compile Remove="Scoping\ScopeContext.cs" />
<Compile Remove="Scoping\RepositoryCacheMode.cs" />
<Compile Remove="Scoping\IScopeProvider.cs" />
<Compile Remove="Scoping\IScope.cs" />
<Compile Remove="Persistence\UmbracoDatabase.cs" />
<Compile Remove="Persistence\SqlTemplates.cs" />
<Compile Remove="Persistence\SqlSyntaxExtensions.cs" />
<Compile Remove="Persistence\SqlSyntax\SqlServerSyntaxProvider.cs" />
<Compile Remove="Persistence\SqlSyntax\MicrosoftSqlSyntaxProviderBase.cs" />
<Compile Remove="Persistence\SqlSyntax\ISqlSyntaxProvider.cs" />
<Compile Remove="Persistence\RecordPersistenceType.cs" />
<Compile Remove="Persistence\Querying\TextColumnType.cs" />
<Compile Remove="Persistence\Querying\PocoToSqlExpressionVisitor.cs" />
<Compile Remove="Persistence\Querying\ModelToSqlExpressionVisitor.cs" />
<Compile Remove="Persistence\PocoDataDataReader.cs" />
<Compile Remove="Persistence\NPocoSqlExtensions.cs" />
<Compile Remove="Persistence\NPocoDatabaseTypeExtensions.cs" />
<Compile Remove="Persistence\NPocoDatabaseExtensions.cs" />
<Compile Remove="Persistence\Mappers\MapperForAttribute.cs" />
<Compile Remove="Persistence\Mappers\MapperCollection.cs" />
<Compile Remove="Persistence\Mappers\IMapperCollection.cs" />
<Compile Remove="Persistence\IUmbracoDatabase.cs" />
<Compile Remove="Persistence\ISqlContext.cs" />
<Compile Remove="Persistence\FaultHandling\ThrottlingCondition.cs" />
<Compile Remove="Persistence\FaultHandling\SqlAzureTransientErrorDetectionStrategy.cs" />
<Compile Remove="Persistence\FaultHandling\RetryStrategy.cs" />
<Compile Remove="Persistence\FaultHandling\RetryPolicyFactory.cs" />
<Compile Remove="Persistence\FaultHandling\RetryLimitExceededException.cs" />
<Compile Remove="Persistence\FaultHandling\RetryDbConnection.cs" />
<Compile Remove="Persistence\FaultHandling\NetworkConnectivityErrorDetectionStrategy.cs" />
<Compile Remove="Persistence\FaultHandling\Incremental.cs" />
<Compile Remove="Persistence\FaultHandling\FixedInterval.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\TableDefinition.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\SystemMethods.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\InsertionDataDefinition.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\IndexColumnDefinition.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\ForeignKeyDefinition.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\DbIndexDefinition.cs" />
<Compile Remove="Persistence\DatabaseModelDefinitions\ConstraintType.cs" />
<Compile Remove="Persistence\DatabaseAnnotations\ReferencesAttribute.cs" />
<Compile Remove="Persistence\DatabaseAnnotations\NullSettingAttribute.cs" />
<Compile Remove="Persistence\DatabaseAnnotations\LengthAttribute.cs" />
<Compile Remove="Persistence\DatabaseAnnotations\IndexTypes.cs" />
<Compile Remove="Persistence\BulkDataReader.cs" />
</ItemGroup>
<ItemGroup>
@@ -103,11 +66,6 @@
<ItemGroup>
<Folder Include="Events" />
<Folder Include="Models\Identity" />
<Folder Include="Persistence\DatabaseAnnotations" />
<Folder Include="Persistence\DatabaseModelDefinitions" />
<Folder Include="Persistence\FaultHandling" />
<Folder Include="Persistence\Mappers" />
<Folder Include="Persistence\Querying" />
</ItemGroup>
</Project>

View File

@@ -79,6 +79,10 @@
<Project>{07fbc26b-2927-4a22-8d96-d644c667fecc}</Project>
<Name>Umbraco.Examine</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj">
<Project>{3ae7bf57-966b-45a5-910a-954d7c554441}</Project>
<Name>Umbraco.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Tests\Umbraco.Tests.csproj">
<Project>{5d3b8245-ada6-453f-a008-50ed04bfe770}</Project>
<Name>Umbraco.Tests</Name>

View File

@@ -97,6 +97,10 @@
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Data.SqlClient" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

View File

@@ -36,7 +36,7 @@ namespace Umbraco.Tests.Components
var logger = Mock.Of<ILogger>();
var typeFinder = new TypeFinder(logger);
var f = new UmbracoDatabaseFactory(logger, new Lazy<IMapperCollection>(() => new MapperCollection(Enumerable.Empty<BaseMapper>())), TestHelper.GetConfigs());
var f = new UmbracoDatabaseFactory(logger, new Lazy<IMapperCollection>(() => new MapperCollection(Enumerable.Empty<BaseMapper>())), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator);
var fs = new FileSystems(mock.Object, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings());
var p = new ScopeProvider(f, fs, logger, typeFinder, NoAppCache.Instance);

View File

@@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence
_sqlSyntaxProviders = new[] { (ISqlSyntaxProvider) _sqlCeSyntaxProvider };
_logger = Mock.Of<ILogger>();
_umbracoVersion = TestHelper.GetUmbracoVersion();
_databaseFactory = new UmbracoDatabaseFactory(_logger, new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()), TestHelper.GetConfigs());
_databaseFactory = new UmbracoDatabaseFactory(_logger, new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator);
}
[TearDown]

View File

@@ -53,7 +53,7 @@ namespace Umbraco.Tests.Routing
public class TestRuntime : WebRuntime
{
public TestRuntime(UmbracoApplicationBase umbracoApplication, Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
: base(umbracoApplication, configs, umbracoVersion, ioHelper, Mock.Of<ILogger>(), Mock.Of<IProfiler>(), hostingEnvironment, backOfficeInfo)
: base(umbracoApplication, configs, umbracoVersion, ioHelper, Mock.Of<ILogger>(), Mock.Of<IProfiler>(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator)
{
}

View File

@@ -122,7 +122,7 @@ namespace Umbraco.Tests.Runtimes
public class TestRuntime : CoreRuntime
{
public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
:base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo)
:base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator)
{
}

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