Merge branch 'v8/dev' into v8/bugfix/5190-invariant-property-validation
This commit is contained in:
@@ -52,7 +52,7 @@
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.dll" target="lib\net472\Umbraco.Core.dll" />
|
||||
|
||||
<!-- docs -->
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\net472\Umbraco.Core.xml" />
|
||||
|
||||
<!-- symbols -->
|
||||
<file src="$BuildTmp$\bin\Umbraco.Core.pdb" target="lib" />
|
||||
|
||||
@@ -53,9 +53,9 @@
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.dll" target="lib\net472\Umbraco.Examine.dll" />
|
||||
|
||||
<!-- docs -->
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.xml" target="lib\Umbraco.Web.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.xml" target="lib\Umbraco.Examine.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.xml" target="lib\net472\Umbraco.Web.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\net472\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.xml" target="lib\net472\Umbraco.Examine.xml" />
|
||||
|
||||
<!-- symbols -->
|
||||
<file src="$BuildTmp$\bin\Umbraco.Web.pdb" target="lib" />
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private DatabaseSchemaResult ValidateSchema(IScope scope)
|
||||
{
|
||||
if (_databaseFactory.Configured == false)
|
||||
if (_databaseFactory.Initialized == false)
|
||||
return new DatabaseSchemaResult(_databaseFactory.SqlContext.SqlSyntax);
|
||||
|
||||
if (_databaseSchemaValidationResult != null)
|
||||
@@ -513,7 +513,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private Attempt<Result> CheckReadyForInstall()
|
||||
{
|
||||
if (_databaseFactory.Configured == false)
|
||||
if (_databaseFactory.CanConnect == false)
|
||||
{
|
||||
return Attempt.Fail(new Result
|
||||
{
|
||||
|
||||
@@ -10,22 +10,35 @@ namespace Umbraco.Core.Persistence
|
||||
/// <summary>
|
||||
/// Creates a new database.
|
||||
/// </summary>
|
||||
/// <remarks>The new database must be disposed after being used.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>The new database must be disposed after being used.</para>
|
||||
/// <para>Creating a database causes the factory to initialize if it is not already initialized.</para>
|
||||
/// </remarks>
|
||||
IUmbracoDatabase CreateDatabase();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the database factory is configured.
|
||||
/// Gets a value indicating whether the database factory is configured, i.e. whether
|
||||
/// its connection string and provider name have been set. The factory may however not
|
||||
/// be initialized (see <see cref="Initialized"/>).
|
||||
/// </summary>
|
||||
bool Configured { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the database factory is initialized, i.e. whether
|
||||
/// its internal state is ready and it has been possible to connect to the database.
|
||||
/// </summary>
|
||||
bool Initialized { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connection string.
|
||||
/// </summary>
|
||||
/// <remarks>Throws if the factory is not configured.</remarks>
|
||||
/// <remarks>May return <c>null</c> if the database factory is not configured.</remarks>
|
||||
string ConnectionString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the database can connect.
|
||||
/// Gets a value indicating whether the database factory is configured (see <see cref="Configured"/>),
|
||||
/// and it is possible to connect to the database. The factory may however not be initialized (see
|
||||
/// <see cref="Initialized"/>).
|
||||
/// </summary>
|
||||
bool CanConnect { get; }
|
||||
|
||||
@@ -37,6 +50,9 @@ namespace Umbraco.Core.Persistence
|
||||
/// <summary>
|
||||
/// Gets the Sql context.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Getting the Sql context causes the factory to initialize if it is not already initialized.</para>
|
||||
/// </remarks>
|
||||
ISqlContext SqlContext { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -232,6 +232,14 @@ namespace Umbraco.Core.Persistence
|
||||
using (var copy = new SqlBulkCopy(tConnection, SqlBulkCopyOptions.Default, tTransaction) { BulkCopyTimeout = 10000, DestinationTableName = tableName })
|
||||
using (var bulkReader = new PocoDataDataReader<T, SqlServerSyntaxProvider>(records, pocoData, syntax))
|
||||
{
|
||||
//we need to add column mappings here because otherwise columns will be matched by their order and if the order of them are different in the DB compared
|
||||
//to the order in which they are declared in the model then this will not work, so instead we will add column mappings by name so that this explicitly uses
|
||||
//the names instead of their ordering.
|
||||
foreach(var col in bulkReader.ColumnMappings)
|
||||
{
|
||||
copy.ColumnMappings.Add(col.DestinationColumn, col.DestinationColumn);
|
||||
}
|
||||
|
||||
copy.WriteToServer(bulkReader);
|
||||
return bulkReader.RecordsAffected;
|
||||
}
|
||||
|
||||
@@ -140,10 +140,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
while (templateDtoIx < templateDtos.Count && templateDtos[templateDtoIx].ContentTypeNodeId == contentType.Id)
|
||||
{
|
||||
var allowedDto = templateDtos[templateDtoIx];
|
||||
templateDtoIx++;
|
||||
if (!templates.TryGetValue(allowedDto.TemplateNodeId, out var template)) continue;
|
||||
allowedTemplates.Add(template);
|
||||
templateDtoIx++;
|
||||
|
||||
|
||||
if (allowedDto.IsDefault)
|
||||
defaultTemplateId = template.Id;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
private readonly Lazy<IMapperCollection> _mappers;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
|
||||
private object _lock = new object();
|
||||
|
||||
private DatabaseFactory _npocoDatabaseFactory;
|
||||
private IPocoDataFactory _pocoDataFactory;
|
||||
@@ -36,12 +37,13 @@ namespace Umbraco.Core.Persistence
|
||||
private string _providerName;
|
||||
private DbProviderFactory _dbProviderFactory;
|
||||
private DatabaseType _databaseType;
|
||||
private bool _serverVersionDetected;
|
||||
private ISqlSyntaxProvider _sqlSyntax;
|
||||
private RetryPolicy _connectionRetryPolicy;
|
||||
private RetryPolicy _commandRetryPolicy;
|
||||
private NPoco.MapperCollection _pocoMappers;
|
||||
private SqlContext _sqlContext;
|
||||
private bool _upgrading;
|
||||
private bool _initialized;
|
||||
|
||||
#region Constructors
|
||||
|
||||
@@ -106,36 +108,30 @@ namespace Umbraco.Core.Persistence
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Configured { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ConnectionString
|
||||
public bool Configured
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureConfigured();
|
||||
return _connectionString;
|
||||
lock (_lock)
|
||||
{
|
||||
return !_connectionString.IsNullOrWhiteSpace() && !_providerName.IsNullOrWhiteSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanConnect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Configured || !DbConnectionExtensions.IsConnectionAvailable(_connectionString, _providerName)) return false;
|
||||
public bool Initialized => Volatile.Read(ref _initialized);
|
||||
|
||||
if (_serverVersionDetected) return true;
|
||||
/// <inheritdoc />
|
||||
public string ConnectionString => _connectionString;
|
||||
|
||||
if (_databaseType.IsSqlServer())
|
||||
DetectSqlServerVersion();
|
||||
_serverVersionDetected = true;
|
||||
/// <inheritdoc />
|
||||
public bool CanConnect =>
|
||||
// actually tries to connect to the database (regardless of configured/initialized)
|
||||
!_connectionString.IsNullOrWhiteSpace() && !_providerName.IsNullOrWhiteSpace() &&
|
||||
DbConnectionExtensions.IsConnectionAvailable(_connectionString, _providerName);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void DetectSqlServerVersion()
|
||||
private void UpdateSqlServerDatabaseType()
|
||||
{
|
||||
// replace NPoco database type by a more efficient one
|
||||
|
||||
@@ -171,7 +167,15 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISqlContext SqlContext { get; private set; }
|
||||
public ISqlContext SqlContext
|
||||
{
|
||||
get
|
||||
{
|
||||
// must be initialized to have a context
|
||||
EnsureInitialized();
|
||||
return _sqlContext;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureForUpgrade()
|
||||
@@ -182,63 +186,79 @@ namespace Umbraco.Core.Persistence
|
||||
/// <inheritdoc />
|
||||
public void Configure(string connectionString, string providerName)
|
||||
{
|
||||
try
|
||||
if (connectionString.IsNullOrWhiteSpace()) throw new ArgumentNullException(nameof(connectionString));
|
||||
if (providerName.IsNullOrWhiteSpace()) throw new ArgumentNullException(nameof(providerName));
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
|
||||
_logger.Debug<UmbracoDatabaseFactory>("Configuring.");
|
||||
|
||||
if (Configured) throw new InvalidOperationException("Already configured.");
|
||||
|
||||
if (connectionString.IsNullOrWhiteSpace()) throw new ArgumentNullException(nameof(connectionString));
|
||||
if (providerName.IsNullOrWhiteSpace()) throw new ArgumentNullException(nameof(providerName));
|
||||
if (Volatile.Read(ref _initialized))
|
||||
throw new InvalidOperationException("Already initialized.");
|
||||
|
||||
_connectionString = connectionString;
|
||||
_providerName = providerName;
|
||||
|
||||
_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}\".");
|
||||
|
||||
_sqlSyntax = GetSqlSyntaxProvider(_providerName);
|
||||
if (_sqlSyntax == null)
|
||||
throw new Exception($"Can't find a sql syntax provider for provider name \"{_providerName}\".");
|
||||
|
||||
// ensure we have only 1 set of mappers, and 1 PocoDataFactory, for all database
|
||||
// so that everything NPoco is properly cached for the lifetime of the application
|
||||
_pocoMappers = new NPoco.MapperCollection { new PocoMapper() };
|
||||
var factory = new FluentPocoDataFactory(GetPocoDataFactoryResolver);
|
||||
_pocoDataFactory = factory;
|
||||
var config = new FluentConfig(xmappers => factory);
|
||||
|
||||
// create the database factory
|
||||
_npocoDatabaseFactory = DatabaseFactory.Config(x => x
|
||||
.UsingDatabase(CreateDatabaseInstance) // creating UmbracoDatabase instances
|
||||
.WithFluentConfig(config)); // with proper configuration
|
||||
|
||||
if (_npocoDatabaseFactory == null) throw new NullReferenceException("The call to UmbracoDatabaseFactory.Config yielded a null UmbracoDatabaseFactory instance.");
|
||||
|
||||
SqlContext = new SqlContext(_sqlSyntax, _databaseType, _pocoDataFactory, _mappers);
|
||||
|
||||
_logger.Debug<UmbracoDatabaseFactory>("Configured.");
|
||||
Configured = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_lock.IsWriteLockHeld)
|
||||
_lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
// rest to be lazy-initialized
|
||||
}
|
||||
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
LazyInitializer.EnsureInitialized(ref _sqlContext, ref _initialized, ref _lock, Initialize);
|
||||
}
|
||||
|
||||
private SqlContext Initialize()
|
||||
{
|
||||
_logger.Debug<UmbracoDatabaseFactory>("Initializing.");
|
||||
|
||||
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.");
|
||||
|
||||
// cannot initialize without being able to talk to the database
|
||||
if (!DbConnectionExtensions.IsConnectionAvailable(_connectionString, _providerName))
|
||||
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}\".");
|
||||
|
||||
_sqlSyntax = GetSqlSyntaxProvider(_providerName);
|
||||
if (_sqlSyntax == null)
|
||||
throw new Exception($"Can't find a sql syntax provider for provider name \"{_providerName}\".");
|
||||
|
||||
if (_databaseType.IsSqlServer())
|
||||
UpdateSqlServerDatabaseType();
|
||||
|
||||
// ensure we have only 1 set of mappers, and 1 PocoDataFactory, for all database
|
||||
// so that everything NPoco is properly cached for the lifetime of the application
|
||||
_pocoMappers = new NPoco.MapperCollection { new PocoMapper() };
|
||||
var factory = new FluentPocoDataFactory(GetPocoDataFactoryResolver);
|
||||
_pocoDataFactory = factory;
|
||||
var config = new FluentConfig(xmappers => factory);
|
||||
|
||||
// create the database factory
|
||||
_npocoDatabaseFactory = DatabaseFactory.Config(x => x
|
||||
.UsingDatabase(CreateDatabaseInstance) // creating UmbracoDatabase instances
|
||||
.WithFluentConfig(config)); // with proper configuration
|
||||
|
||||
if (_npocoDatabaseFactory == null)
|
||||
throw new NullReferenceException("The call to UmbracoDatabaseFactory.Config yielded a null UmbracoDatabaseFactory instance.");
|
||||
|
||||
_logger.Debug<UmbracoDatabaseFactory>("Initialized.");
|
||||
|
||||
return new SqlContext(_sqlSyntax, _databaseType, _pocoDataFactory, _mappers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IUmbracoDatabase CreateDatabase()
|
||||
{
|
||||
// must be initialized to create a database
|
||||
EnsureInitialized();
|
||||
return (IUmbracoDatabase) _npocoDatabaseFactory.GetDatabase();
|
||||
}
|
||||
|
||||
@@ -260,22 +280,6 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
}
|
||||
|
||||
// ensures that the database is configured, else throws
|
||||
private void EnsureConfigured()
|
||||
{
|
||||
_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
if (Configured == false)
|
||||
throw new InvalidOperationException("Not configured.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_lock.IsReadLockHeld)
|
||||
_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
// method used by NPoco's UmbracoDatabaseFactory to actually create the database instance
|
||||
private UmbracoDatabase CreateDatabaseInstance()
|
||||
{
|
||||
@@ -292,7 +296,7 @@ namespace Umbraco.Core.Persistence
|
||||
//var db = _umbracoDatabaseAccessor.UmbracoDatabase;
|
||||
//_umbracoDatabaseAccessor.UmbracoDatabase = null;
|
||||
//db?.Dispose();
|
||||
Configured = false;
|
||||
Volatile.Write(ref _initialized, false);
|
||||
}
|
||||
|
||||
// during tests, the thread static var can leak between tests
|
||||
|
||||
@@ -43,16 +43,6 @@ namespace Umbraco.Tests.Persistence
|
||||
_databaseFactory = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDatabaseType()
|
||||
{
|
||||
using (var database = _databaseFactory.CreateDatabase())
|
||||
{
|
||||
var databaseType = database.DatabaseType;
|
||||
Assert.AreEqual(DatabaseType.SQLCe, databaseType);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateDatabase() // FIXME: move to DatabaseBuilderTest!
|
||||
{
|
||||
@@ -79,6 +69,13 @@ namespace Umbraco.Tests.Persistence
|
||||
// re-create the database factory and database context with proper connection string
|
||||
_databaseFactory = new UmbracoDatabaseFactory(connString, Constants.DbProviderNames.SqlCe, _logger, new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()));
|
||||
|
||||
// test get database type (requires an actual database)
|
||||
using (var database = _databaseFactory.CreateDatabase())
|
||||
{
|
||||
var databaseType = database.DatabaseType;
|
||||
Assert.AreEqual(DatabaseType.SQLCe, databaseType);
|
||||
}
|
||||
|
||||
// create application context
|
||||
//var appCtx = new ApplicationContext(
|
||||
// _databaseFactory,
|
||||
|
||||
@@ -505,6 +505,7 @@
|
||||
property.showOnMemberProfile = propertyModel.showOnMemberProfile;
|
||||
property.memberCanEdit = propertyModel.memberCanEdit;
|
||||
property.isSensitiveValue = propertyModel.isSensitiveValue;
|
||||
property.allowCultureVariant = propertyModel.allowCultureVariant;
|
||||
|
||||
// update existing data types
|
||||
if(model.updateSameDataTypes) {
|
||||
|
||||
@@ -20,6 +20,13 @@ angular.module("umbraco")
|
||||
editorConfig.maxImageSize = tinyMceService.defaultPrevalues().maxImageSize;
|
||||
}
|
||||
|
||||
var width = editorConfig.dimensions ? parseInt(editorConfig.dimensions.width, 10) || null : null;
|
||||
var height = editorConfig.dimensions ? parseInt(editorConfig.dimensions.height, 10) || null : null;
|
||||
|
||||
$scope.containerWidth = editorConfig.mode === "distraction-free" ? (width ? width : "auto") : "auto";
|
||||
$scope.containerHeight = editorConfig.mode === "distraction-free" ? (height ? height : "auto") : "auto";
|
||||
$scope.containerOverflow = editorConfig.mode === "distraction-free" ? (height ? "auto" : "inherit") : "inherit";
|
||||
|
||||
var promises = [];
|
||||
|
||||
//queue file loading
|
||||
@@ -41,10 +48,16 @@ angular.module("umbraco")
|
||||
$q.all(promises).then(function (result) {
|
||||
|
||||
var standardConfig = result[promises.length - 1];
|
||||
|
||||
|
||||
if (height !== null) {
|
||||
standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1);
|
||||
}
|
||||
|
||||
//create a baseline Config to extend upon
|
||||
var baseLineConfigObj = {
|
||||
maxImageSize: editorConfig.maxImageSize
|
||||
maxImageSize: editorConfig.maxImageSize,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
|
||||
angular.extend(baseLineConfigObj, standardConfig);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.RTEController" class="umb-property-editor umb-rte">
|
||||
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
|
||||
|
||||
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible'}"
|
||||
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible', width :containerWidth, height: containerHeight, overflow: containerOverflow}"
|
||||
id="{{textAreaHtmlId}}" class="umb-rte-editor"></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user