Merge remote-tracking branch 'origin/temp8' into temp8-logviewer

# Conflicts:
#	src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs
This commit is contained in:
Bjarke Berg
2019-01-22 10:19:43 +01:00
88 changed files with 150 additions and 1843 deletions
-1
View File
@@ -28,7 +28,6 @@
<dependency id="Microsoft.AspNet.WebApi.Client" version="[5.2.6,5.999999)" />
<dependency id="Microsoft.Owin" version="[4.0.0,4.999999)" />
<dependency id="MiniProfiler" version="[3.2.0.157,3.999999)" />
<dependency id="MySql.Data" version="[6.10.7,6.999999)" />
<dependency id="Newtonsoft.Json" version="[11.0.2,11.999999)" />
<dependency id="Semver" version="[2.0.4,2.999999)" />
<dependency id="Serilog" version="[2.7.1,2.999999)" />
@@ -38,10 +38,6 @@
<DbProviderFactories xdt:Transform="InsertIfMissing">
<remove invariant="System.Data.SqlServerCe.4.0" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(invariant,description,type)" />
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="Remove" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add invariant="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(type)" />
</DbProviderFactories>
</system.data>
<clientDependency xdt:Transform="RemoveAttributes(version)" />
@@ -49,11 +45,6 @@
<system.web xdt:Transform="InsertIfMissing" />
<system.web>
<siteMap xdt:Transform="Remove" />
<siteMap xdt:Transform="InsertIfMissing">
<providers xdt:Transform="InsertIfMissing">
<remove name="MySqlSiteMapProvider" xdt:Transform="InsertIfMissing" />
</providers>
</siteMap>
<httpRuntime xdt:Transform="InsertIfMissing" />
<httpRuntime maxRequestLength="51200" fcnMode="Single" xdt:Transform="SetAttributes(fcnMode,maxRequestLength)" />
<httpRuntime targetFramework="4.5" xdt:Locator="Condition(count(@targetFramework) != 1)" xdt:Transform="SetAttributes(targetFramework)" />
-1
View File
@@ -73,7 +73,6 @@ if ($project) {
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MySql.Data.dll) { Remove-Item $umbracoBinFolder\MySql.Data.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Owin.dll) { Remove-Item $umbracoBinFolder\Owin.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Semver.dll) { Remove-Item $umbracoBinFolder\Semver.dll -Force -Confirm:$false }
@@ -6,7 +6,6 @@
{
public const string SqlCe = "System.Data.SqlServerCe.4.0";
public const string SqlServer = "System.Data.SqlClient";
public const string MySql = "MySql.Data.MySqlClient";
}
}
}
@@ -1,9 +1,7 @@
using System.Data;
using NPoco;
using Umbraco.Core.Migrations.Expressions.Alter.Expressions;
using Umbraco.Core.Migrations.Expressions.Common.Expressions;
using Umbraco.Core.Migrations.Expressions.Create.Expressions;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
@@ -43,11 +41,11 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table
if (CurrentColumn.ModificationType == ModificationType.Alter)
{
var dc = new AlterDefaultConstraintExpression(_context)
{
TableName = Expression.TableName,
ColumnName = CurrentColumn.Name,
DefaultValue = value
};
{
TableName = Expression.TableName,
ColumnName = CurrentColumn.Name,
DefaultValue = value
};
Expression.Expressions.Add(dc);
}
@@ -78,9 +76,9 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table
});
index.Index.Columns.Add(new IndexColumnDefinition
{
Name = CurrentColumn.Name
});
{
Name = CurrentColumn.Name
});
Expression.Expressions.Add(index);
@@ -91,19 +89,15 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table
{
CurrentColumn.IsPrimaryKey = true;
// see notes in CreateTableBuilder
if (Expression.DatabaseType.IsMySql() == false)
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
Constraint =
Constraint =
{
TableName = Expression.TableName,
Columns = new[] { CurrentColumn.Name }
}
};
Expression.Expressions.Add(expression);
}
};
Expression.Expressions.Add(expression);
return this;
}
@@ -113,20 +107,16 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table
CurrentColumn.IsPrimaryKey = true;
CurrentColumn.PrimaryKeyName = primaryKeyName;
// see notes in CreateTableBuilder
if (Expression.DatabaseType.IsMySql() == false)
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
Constraint =
Constraint =
{
ConstraintName = primaryKeyName,
TableName = Expression.TableName,
Columns = new[] { CurrentColumn.Name }
}
};
Expression.Expressions.Add(expression);
}
};
Expression.Expressions.Add(expression);
return this;
}
@@ -155,14 +145,14 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table
var index = new CreateIndexExpression(_context, new IndexDefinition
{
Name = indexName,
TableName = Expression.TableName,
TableName = Expression.TableName,
IndexType = IndexTypes.UniqueNonClustered
});
index.Index.Columns.Add(new IndexColumnDefinition
{
Name = CurrentColumn.Name
});
{
Name = CurrentColumn.Name
});
Expression.Expressions.Add(index);
@@ -241,10 +231,10 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table
{
var column = new ColumnDefinition { Name = name, ModificationType = ModificationType.Create };
var createColumn = new CreateColumnExpression(_context)
{
Column = column,
TableName = Expression.TableName
};
{
Column = column,
TableName = Expression.TableName
};
CurrentColumn = column;
@@ -94,25 +94,15 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table
{
CurrentColumn.IsPrimaryKey = true;
//For MySQL, the PK will be created WITH the create table expression, however for
// SQL Server, the PK get's created in a different Alter table expression afterwords.
// MySQL will choke if the same constraint is again added afterword
// TODO: This is a super hack, I'd rather not add another property like 'CreatesPkInCreateTableDefinition' to check
// for this, but I don't see another way around. MySQL doesn't support checking for a constraint before creating
// it... except in a very strange way but it doesn't actually provider error feedback if it doesn't work so we cannot use
// it. For now, this is what I'm doing
if (Expression.DatabaseType.IsMySql() == false)
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
Constraint =
Constraint =
{
TableName = CurrentColumn.TableName,
Columns = new[] { CurrentColumn.Name }
}
};
Expression.Expressions.Add(expression);
}
};
Expression.Expressions.Add(expression);
return this;
}
@@ -123,27 +113,16 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table
CurrentColumn.IsPrimaryKey = true;
CurrentColumn.PrimaryKeyName = primaryKeyName;
//For MySQL, the PK will be created WITH the create table expression, however for
// SQL Server, the PK get's created in a different Alter table expression afterwords.
// MySQL will choke if the same constraint is again added afterword
// TODO: This is a super hack, I'd rather not add another property like 'CreatesPkInCreateTableDefinition' to check
// for this, but I don't see another way around. MySQL doesn't support checking for a constraint before creating
// it... except in a very strange way but it doesn't actually provider error feedback if it doesn't work so we cannot use
// it. For now, this is what I'm doing
if (Expression.DatabaseType.IsMySql() == false)
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey)
{
Constraint =
Constraint =
{
ConstraintName = primaryKeyName,
TableName = CurrentColumn.TableName,
Columns = new[] { CurrentColumn.Name }
}
};
Expression.Expressions.Add(expression);
}
};
Expression.Expressions.Add(expression);
return this;
}
@@ -177,14 +156,14 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table
{
Name = indexName,
SchemaName = Expression.SchemaName,
TableName = Expression.TableName,
TableName = Expression.TableName,
IndexType = IndexTypes.UniqueNonClustered
});
index.Index.Columns.Add(new IndexColumnDefinition
{
Name = CurrentColumn.Name
});
{
Name = CurrentColumn.Name
});
Expression.Expressions.Add(index);
@@ -1,6 +1,4 @@
using NPoco;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
{
@@ -16,19 +14,9 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
protected override string GetSql()
{
return DatabaseType.IsMySql()
? GetMySql()
: string.Format(SqlSyntax.DeleteConstraint,
return string.Format(SqlSyntax.DeleteConstraint,
SqlSyntax.GetQuotedTableName(Constraint.TableName),
SqlSyntax.GetQuotedName(Constraint.ConstraintName));
}
private string GetMySql()
{
return string.Format(SqlSyntax.DeleteConstraint,
SqlSyntax.GetQuotedTableName(Constraint.TableName),
Constraint.IsPrimaryKeyConstraint ? "PRIMARY KEY" : "FOREIGN KEY",
"");
}
}
}
@@ -1,7 +1,5 @@
using System;
using System.Linq;
using NPoco;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
@@ -20,10 +18,7 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
{
if (ForeignKey.ForeignTable == null)
throw new ArgumentNullException("Table name not specified, ensure you have appended the OnTable extension. Format should be Delete.ForeignKey(KeyName).OnTable(TableName)");
if (DatabaseType.IsMySql())
return GetMySql();
if (string.IsNullOrEmpty(ForeignKey.Name))
{
ForeignKey.Name = $"FK_{ForeignKey.ForeignTable}_{ForeignKey.PrimaryTable}_{ForeignKey.PrimaryColumns.First()}";
@@ -33,17 +28,5 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
SqlSyntax.GetQuotedTableName(ForeignKey.ForeignTable),
SqlSyntax.GetQuotedName(ForeignKey.Name));
}
private string GetMySql()
{
// MySql naming "convention" for foreignkeys, which aren't explicitly named
if (string.IsNullOrEmpty(ForeignKey.Name))
ForeignKey.Name = $"{ForeignKey.ForeignTable.ToLower()}_ibfk_1";
return string.Format(SqlSyntax.DeleteConstraint,
SqlSyntax.GetQuotedTableName(ForeignKey.ForeignTable),
"FOREIGN KEY",
SqlSyntax.GetQuotedName(ForeignKey.Name));
}
}
}
@@ -1,8 +1,5 @@
using System.Collections.Generic;
using System.Text;
using System.Linq;
using NPoco;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Migrations.Expressions.Insert.Expressions
@@ -1,7 +1,4 @@
using NPoco;
using Umbraco.Core.Persistence;
namespace Umbraco.Core.Migrations.Expressions.Rename.Expressions
namespace Umbraco.Core.Migrations.Expressions.Rename.Expressions
{
public class RenameColumnExpression : MigrationExpressionBase
{
@@ -18,33 +15,8 @@ namespace Umbraco.Core.Migrations.Expressions.Rename.Expressions
/// <inheritdoc />
protected override string GetSql()
{
return DatabaseType.IsMySql()
? GetMySql()
: GetBaseSql();
}
private string GetBaseSql()
{
return SqlSyntax.FormatColumnRename(TableName, OldName, NewName);
}
private string GetMySql()
{
var columnDefinitionSql = $@"
SELECT CONCAT(
CAST(COLUMN_TYPE AS CHAR),
IF(ISNULL(CHARACTER_SET_NAME), '', CONCAT(' CHARACTER SET ', CHARACTER_SET_NAME)),
IF(ISNULL(COLLATION_NAME), '', CONCAT(' COLLATE ', COLLATION_NAME)),
' ',
IF(IS_NULLABLE = 'NO', 'NOT NULL ', ''),
IF(IS_NULLABLE = 'NO' AND COLUMN_DEFAULT IS NULL, '', CONCAT('DEFAULT ', QUOTE(COLUMN_DEFAULT), ' ')),
UPPER(extra))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '{TableName}' AND COLUMN_NAME = '{OldName}'";
var columnDefinition = Database.ExecuteScalar<string>(columnDefinitionSql);
return GetBaseSql() + " " + columnDefinition;
}
}
}
@@ -11,7 +11,6 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Migrations.Upgrade;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
@@ -151,13 +150,10 @@ namespace Umbraco.Core.Migrations.Install
/// Configures a connection string that has been entered manually.
/// </summary>
/// <param name="connectionString">A connection string.</param>
/// <remarks>Has to be either SQL Server or MySql</remarks>
/// <remarks>Has to be SQL Server</remarks>
public void ConfigureDatabaseConnection(string connectionString)
{
var provider = DbConnectionExtensions.DetectProviderNameFromConnectionString(connectionString);
var providerName = provider.ToString().ToLower().Contains("mysql")
? Constants.DbProviderNames.MySql
: Constants.DbProviderNames.SqlServer;
const string providerName = Constants.DbProviderNames.SqlServer;
SaveConnectionString(connectionString, providerName, _logger);
_databaseFactory.Configure(connectionString, providerName);
@@ -170,7 +166,7 @@ namespace Umbraco.Core.Migrations.Install
/// <param name="databaseName">The name of the database.</param>
/// <param name="user">The user name.</param>
/// <param name="password">The user password.</param>
/// <param name="databaseProvider">The name the provider (Sql, Sql Azure, Sql Ce, MySql).</param>
/// <param name="databaseProvider">The name of the provider (Sql, Sql Azure, Sql Ce).</param>
public void ConfigureDatabaseConnection(string server, string databaseName, string user, string password, string databaseProvider)
{
var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out var providerName);
@@ -186,22 +182,15 @@ namespace Umbraco.Core.Migrations.Install
/// <param name="databaseName">The name of the database.</param>
/// <param name="user">The user name.</param>
/// <param name="password">The user password.</param>
/// <param name="databaseProvider">The name the provider (Sql, Sql Azure, Sql Ce, MySql).</param>
/// <param name="databaseProvider">The name of the provider (Sql, Sql Azure, Sql Ce).</param>
/// <param name="providerName"></param>
/// <returns>A connection string.</returns>
public static string GetDatabaseConnectionString(string server, string databaseName, string user, string password, string databaseProvider, out string providerName)
{
providerName = Constants.DbProviderNames.SqlServer;
var test = databaseProvider.ToLower();
if (test.Contains("mysql"))
{
providerName = Constants.DbProviderNames.MySql;
return $"Server={server}; Database={databaseName};Uid={user};Pwd={password}";
}
if (test.Contains("azure"))
{
var provider = databaseProvider.ToLower();
if (provider.InvariantContains("azure"))
return GetAzureConnectionString(server, databaseName, user, password);
}
return $"server={server};database={databaseName};user id={user};password={password}";
}
@@ -433,10 +422,9 @@ namespace Umbraco.Core.Migrations.Install
_logger.Info<DatabaseBuilder>("Database configuration status: Started");
var database = scope.Database;
var message = string.Empty;
// If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks
// for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive.
var message = database.DatabaseType.IsMySql() ? ResultMessageForMySql : "";
var schemaResult = ValidateSchema();
var hasInstalledVersion = schemaResult.DetermineHasInstalledVersion();
//var installedSchemaVersion = schemaResult.DetermineInstalledVersion();
@@ -494,14 +482,12 @@ namespace Umbraco.Core.Migrations.Install
}
_logger.Info<DatabaseBuilder>("Database upgrade started");
var message = _scopeProvider.SqlContext.DatabaseType.IsMySql() ? ResultMessageForMySql : "";
// upgrade
var upgrader = new UmbracoUpgrader();
upgrader.Execute(_scopeProvider, _migrationBuilder, _keyValueService, _logger, _postMigrations);
message = message + "<p>Upgrade completed!</p>";
var message = "<p>Upgrade completed!</p>";
//now that everything is done, we need to determine the version of SQL server that is executing
@@ -515,15 +501,6 @@ namespace Umbraco.Core.Migrations.Install
}
}
private const string ResultMessageForMySql = "<p>&nbsp;</p><p>Congratulations, the database step ran successfully!</p>" +
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
"<p>However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries</p>" +
"<p>Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
private Attempt<Result> CheckReadyForInstall()
{
if (_databaseFactory.Configured == false)
@@ -166,12 +166,6 @@ namespace Umbraco.Core.Migrations.Install
/// </remarks>
private void ValidateDbConstraints(DatabaseSchemaResult result)
{
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
//TODO: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers.
// ALso note that to get the constraints for MySql we have to open a connection which we currently have not.
if (SqlSyntax is MySqlSyntaxProvider)
return;
//Check constraints in configured database against constraints in schema
var constraintsInDatabase = SqlSyntax.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("FK_")).Select(x => x.Item3).ToList();
@@ -186,8 +180,8 @@ namespace Umbraco.Core.Migrations.Install
var primaryKeysInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => y.PrimaryKeyName))
.Where(x => x.IsNullOrWhiteSpace() == false).ToList();
//Add valid and invalid foreign key differences to the result object
// We'll need to do invariant contains with case insensitivity because foreign key, primary key, and even index naming w/ MySQL is not standardized
// Add valid and invalid foreign key differences to the result object
// We'll need to do invariant contains with case insensitivity because foreign key, primary key is not standardized
// In theory you could have: FK_ or fk_ ...or really any standard that your development department (or developer) chooses to use.
foreach (var unknown in unknownConstraintsInDatabase)
{
@@ -458,7 +452,6 @@ namespace Umbraco.Core.Migrations.Install
_logger.Info<DatabaseSchemaCreator>("Create Primary Key ({CreatedPk}):\n {Sql}", createdPk, createPrimaryKeySql);
}
//Turn on identity insert if db provider is not mysql
if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
_database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} ON "));
@@ -467,16 +460,9 @@ namespace Umbraco.Core.Migrations.Install
dataCreation.InitializeBaseData(tableName);
//Turn off identity insert if db provider is not mysql
if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
_database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} OFF;"));
//Special case for MySql
if (SqlSyntax is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
{
_database.Update<UserDto>("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" });
}
//Loop through index statements and execute sql
foreach (var sql in indexSql)
{
@@ -498,7 +484,7 @@ namespace Umbraco.Core.Migrations.Install
else
{
_logger.Info<Database>("New table {TableName} was created", tableName);
}
}
@@ -12,12 +12,8 @@ namespace Umbraco.Core.Migrations.Install
/// </summary>
internal class DatabaseSchemaResult
{
private readonly bool _isMySql;
public DatabaseSchemaResult(ISqlSyntaxProvider sqlSyntax)
{
_isMySql = sqlSyntax is MySqlSyntaxProvider;
Errors = new List<Tuple<string, string>>();
TableDefinitions = new List<TableDefinition>();
ValidTables = new List<string>();
@@ -102,11 +98,6 @@ namespace Umbraco.Core.Migrations.Install
sb.AppendLine(" ");
}
if (_isMySql)
{
sb.AppendLine("Please note that the constraints could not be validated because the current data provider is MySql.");
}
return sb.ToString();
}
}
@@ -98,14 +98,12 @@ namespace Umbraco.Core.Migrations
protected bool ColumnExists(string tableName, string columnName)
{
// that's ok even on MySql
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray();
return columns.Any(x => x.TableName.InvariantEquals(tableName) && x.ColumnName.InvariantEquals(columnName));
}
protected string ColumnType(string tableName, string columnName)
{
// that's ok even on MySql
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray();
var column = columns.FirstOrDefault(x => x.TableName.InvariantEquals(tableName) && x.ColumnName.InvariantEquals(columnName));
return column?.DataType;
@@ -27,25 +27,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
if (found != null)
{
//Check for MySQL
if (DatabaseType.IsMySql())
{
//Use the special double nested sub query for MySQL since that is the only
//way delete sub queries works
var delPropQry = SqlSyntax.GetDeleteSubquery(
"cmsPropertyData",
"id",
Sql("SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL"),
WhereInType.NotIn);
Database.Execute(delPropQry.SQL);
}
else
{
//NOTE: Even though the above will work for MSSQL, we are not going to execute the
// nested delete sub query logic since it will be slower and there could be a ton of property
// data here so needs to be as fast as possible.
Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)");
}
Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)");
//we need to re create this index
Delete.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData").Do();
@@ -16,9 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
//Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
//http://issues.umbraco.org/issue/U4-9758
var colLen = SqlSyntax is MySqlSyntaxProvider
? database.ExecuteScalar<int?>("select max(LENGTH(LoginName)) from cmsMember")
: database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
var colLen = database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
if (colLen < 900 == false && colLen != null)
{
@@ -17,9 +17,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
var database = Database;
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
var colLen = (SqlSyntax is MySqlSyntaxProvider)
? database.ExecuteScalar<int?>("select max(LENGTH(LoginName)) from cmsMember")
: database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
var colLen = database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
if (colLen < 900 == false) return;
@@ -13,9 +13,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
{
var database = Database;
//Now we need to check if we can actually do this because we won't be able to if there's data in there that is too long
var colLen = (SqlSyntax is MySqlSyntaxProvider)
? database.ExecuteScalar<int?>(string.Format("select max(LENGTH({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")))
: database.ExecuteScalar<int?>(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
var colLen = database.ExecuteScalar<int?>(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
if (colLen < 900 == false && colLen != null)
{
@@ -4,7 +4,6 @@ using System.Data;
using System.Linq;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.SqlSyntax;
using ColumnInfo = Umbraco.Core.Persistence.SqlSyntax.ColumnInfo;
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
@@ -19,9 +18,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
//For some of the migration data inserts we require to use a special MSSQL collate expression since
//some databases may have a custom collation specified and if that is the case, when we compare strings
//in dynamic SQL it will try to compare strings in different collations and this will yield errors.
_collateSyntax = SqlSyntax is MySqlSyntaxProvider || SqlSyntax is SqlCeSyntaxProvider
? string.Empty
: "COLLATE DATABASE_DEFAULT";
_collateSyntax = "COLLATE DATABASE_DEFAULT";
}
public override void Migrate()
@@ -340,24 +337,16 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
if (tables.InvariantContains("umbracoUserType") && tables.InvariantContains("umbracoUser"))
{
if (DatabaseType.IsMySql())
//Delete the FK if it exists before dropping the column
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id")))
{
//In MySql, this will drop the FK according to it's special naming rules
Delete.ForeignKey().FromTable("umbracoUser").ForeignColumn("userType").ToTable("umbracoUserType").PrimaryColumn("id");
Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser").Do();
}
else
{
//Delete the FK if it exists before dropping the column
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id")))
{
Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser").Do();
}
//This is the super old constraint name of the FK for user type so check this one too
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_user_userType")))
{
Delete.ForeignKey("FK_user_userType").OnTable("umbracoUser").Do();
}
//This is the super old constraint name of the FK for user type so check this one too
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_user_userType")))
{
Delete.ForeignKey("FK_user_userType").OnTable("umbracoUser").Do();
}
Delete.Column("userType").FromTable("umbracoUser").Do();
@@ -16,9 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
var database = Database;
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
var colLen = SqlSyntax is MySqlSyntaxProvider
? database.ExecuteScalar<int?>(string.Format("select max(LENGTH({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")))
: database.ExecuteScalar<int?>(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
var colLen = database.ExecuteScalar<int?>(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
if (colLen < 900 == false) return;
@@ -20,36 +20,25 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
Alter.Table("cmsPreviewXml").AddColumn("Rv").AsInt64().NotNullable().WithDefaultValue(0).Do();
// remove the any PK_ and the FK_ to cmsContentVersion.VersionId
if (DatabaseType.IsMySql())
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
var dups = new List<string>();
foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("PK_")))
{
var keyName = c.Item3.ToLowerInvariant();
if (dups.Contains(keyName))
{
Logger.Warn<RefactorXmlColumns>("Duplicate constraint '{Constraint}'", c.Item3);
continue;
}
dups.Add(keyName);
Delete.PrimaryKey(c.Item3).FromTable(c.Item1).Do();
}
foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("FK_cmsPreviewXml_cmsContentVersion")))
{
Delete.PrimaryKey("PK_cmsPreviewXml").FromTable("cmsPreviewXml").Do();
Delete.ForeignKey().FromTable("cmsPreviewXml").ForeignColumn("VersionId")
.ToTable("cmsContentVersion").PrimaryColumn("VersionId")
.Do();
}
else
{
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
var dups = new List<string>();
foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("PK_")))
{
var keyName = c.Item3.ToLowerInvariant();
if (dups.Contains(keyName))
{
Logger.Warn<RefactorXmlColumns>("Duplicate constraint '{Constraint}'", c.Item3);
continue;
}
dups.Add(keyName);
Delete.PrimaryKey(c.Item3).FromTable(c.Item1).Do();
}
foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("FK_cmsPreviewXml_cmsContentVersion")))
{
Delete.ForeignKey().FromTable("cmsPreviewXml").ForeignColumn("VersionId")
.ToTable("cmsContentVersion").PrimaryColumn("VersionId")
.Do();
}
}
if (ColumnExists("cmsPreviewXml", "Timestamp"))
Delete.Column("Timestamp").FromTable("cmsPreviewXml").Do();
@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Umbraco.Core.Migrations.Install;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
@@ -17,7 +15,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
// notes
// do NOT use Rename.Column as it's borked on SQLCE - use ReplaceColumn instead
// not sure it all runs on MySql, needs to test
public override void Migrate()
{
@@ -195,9 +192,7 @@ JOIN {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc ON doc.nodeId=cver.n
FROM {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc
JOIN {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cver ON doc.nodeId=cver.nodeId AND doc.versionId=cver.versionId
WHERE doc.newest=1 AND doc.published=1");
var getIdentity = Database.SqlContext.DatabaseType.IsMySql()
? "LAST_INSERT_ID()"
: "@@@@IDENTITY";
var getIdentity = "@@@@IDENTITY";
foreach (var t in temp3)
{
Database.Execute($@"INSERT INTO {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} (nodeId, versionId, versionDate, userId, {SqlSyntax.GetQuotedColumnName("current")}, text)
@@ -6,7 +6,6 @@ namespace Umbraco.Core
public static class DbProviderNames
{
public const string SqlServer = "System.Data.SqlClient";
public const string MySql = "MySql.Data.MySqlClient";
public const string SqlCe = "System.Data.SqlServerCe.4.0";
}
}
@@ -109,12 +109,6 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
var constraintAttribute = propertyInfo.FirstAttribute<ConstraintAttribute>();
if (constraintAttribute != null)
{
//Special case for MySQL as it can't have multiple default DateTime values, which
//is what the umbracoServer table definition is trying to create
if (sqlSyntax is MySqlSyntaxProvider && definition.TableName == "umbracoServer" &&
definition.TableName.ToLowerInvariant() == "lastNotifiedDate".ToLowerInvariant())
return definition;
definition.ConstraintName = constraintAttribute.Name ?? string.Empty;
definition.DefaultValue = constraintAttribute.Default ?? string.Empty;
}
@@ -4,7 +4,6 @@ using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using MySql.Data.MySqlClient;
using StackExchange.Profiling.Data;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
@@ -19,12 +18,6 @@ namespace Umbraco.Core.Persistence
var builder = new DbConnectionStringBuilder { ConnectionString = connectionString };
var allKeys = builder.Keys.Cast<string>();
var mySql = new[] { "Server", "Database", "Uid", "Pwd" };
if (mySql.All(x => allKeys.InvariantContains(x)))
{
return Constants.DbProviderNames.MySql;
}
if (allKeys.InvariantContains("Data Source")
//this dictionary is case insensitive
&& builder["Data source"].ToString().InvariantContains(".sdf"))
@@ -38,7 +31,6 @@ namespace Umbraco.Core.Persistence
public static bool IsConnectionAvailable(string connectionString, string providerName)
{
if (providerName != Constants.DbProviderNames.SqlCe
&& providerName != Constants.DbProviderNames.MySql
&& providerName != Constants.DbProviderNames.SqlServer)
throw new NotSupportedException($"Provider \"{providerName}\" is not supported.");
@@ -108,11 +100,6 @@ namespace Umbraco.Core.Persistence
var builder = new SqlCeConnectionStringBuilder(connection.ConnectionString);
return $"DataSource: {builder.DataSource}";
}
case MySqlConnection _:
{
var builder = new MySqlConnectionStringBuilder(connection.ConnectionString);
return $"Server: {builder.Server}, Database: {builder.Database}";
}
}
}
catch (Exception ex)
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Persistence.Factories
property.Id = propDto.Id;
property.FactorySetValue(languageRepository.GetIsoCodeById(propDto.LanguageId), propDto.Segment, propDto.VersionId == publishedVersionId, propDto.Value);
}
}
property.ResetDirtyProperties(false);
@@ -116,6 +116,9 @@ namespace Umbraco.Core.Persistence.Factories
var entityVariesByCulture = contentVariation.VariesByCulture();
// create dtos for each property values, but only for values that do actually exist
// ie have a non-null value, everything else is just ignored and won't have a db row
foreach (var property in properties)
{
if (property.PropertyType.IsPublishing)
@@ -135,10 +138,6 @@ namespace Umbraco.Core.Persistence.Factories
if (propertyValue.EditedValue != null)
propertyDataDtos.Add(BuildDto(currentVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.EditedValue));
// deal with missing edit value (fix inconsistencies)
else if (propertyValue.PublishedValue != null)
propertyDataDtos.Add(BuildDto(currentVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.PublishedValue));
// use explicit equals here, else object comparison fails at comparing eg strings
var sameValues = propertyValue.PublishedValue == null ? propertyValue.EditedValue == null : propertyValue.PublishedValue.Equals(propertyValue.EditedValue);
edited |= !sameValues;
@@ -150,7 +149,7 @@ namespace Umbraco.Core.Persistence.Factories
editedCultures.Add(propertyValue.Culture); // report culture as edited
}
// flag culture as edited if it contains an edited invariant property
// flag culture as edited if it contains an edited invariant property
if (propertyValue.Culture == null //invariant property
&& !sameValues // and edited and published are different
&& entityVariesByCulture) //only when the entity is variant
@@ -160,7 +159,6 @@ namespace Umbraco.Core.Persistence.Factories
editedCultures.Add(defaultCulture);
}
}
}
else
@@ -71,10 +71,6 @@ namespace Umbraco.Core.Persistence
? BulkInsertRecordsSqlServer(database, pocoData, recordsA)
: BulkInsertRecordsWithCommands(database, recordsA);
}
if (database.DatabaseType.IsMySql())
return BulkInsertRecordsWithCommands(database, recordsA);
throw new NotSupportedException();
}
@@ -32,30 +32,6 @@ namespace Umbraco.Core.Persistence
//
// works in READ COMMITED, TSQL & SQLCE lock the constraint even if it does not exist, so INSERT is OK
//
// proper way to do it with MySQL
// IF EXISTS (SELECT ... FROM table WHERE ... FOR UPDATE)
// BEGIN
// UPDATE table SET ... WHERE ...
// END
// ELSE
// BEGIN
// INSERT INTO table (...) VALUES (...)
// END
//
// MySQL locks the constraint ONLY if it exists, so INSERT may fail...
// in theory, happens in READ COMMITTED but not REPEATABLE READ
// http://www.percona.com/blog/2012/08/28/differences-between-read-committed-and-repeatable-read-transaction-isolation-levels/
// but according to
// http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
// it won't work for exact index value (only ranges) so really...
//
// MySQL should do
// INSERT INTO table (...) VALUES (...) ON DUPLICATE KEY UPDATE ...
//
// also the lock is released when the transaction is committed
// not sure if that can have unexpected consequences on our code?
//
// so... for the time being, let's do with that somewhat crazy solution below...
// todo: use the proper database syntax, not this kludge
/// <summary>
@@ -66,7 +42,7 @@ namespace Umbraco.Core.Persistence
/// <returns>The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object
/// passed in will contain the updated value.</returns>
/// <remarks>
/// <para>We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE
/// <para>We cannot rely on database-specific options because SQLCE
/// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting
/// isolation levels globally. We want to keep it simple for the time being and manage it manually.</para>
/// <para>We handle it by trying to update, then insert, etc. until something works, or we get bored.</para>
@@ -89,7 +65,7 @@ namespace Umbraco.Core.Persistence
/// <returns>The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object
/// passed in will contain the updated value.</returns>
/// <remarks>
/// <para>We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE
/// <para>We cannot rely on database-specific options because SQLCE
/// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting
/// isolation levels globally. We want to keep it simple for the time being and manage it manually.</para>
/// <para>We handle it by trying to update, then insert, etc. until something works, or we get bored.</para>
@@ -4,11 +4,6 @@ namespace Umbraco.Core.Persistence
{
internal static class NPocoDatabaseTypeExtensions
{
public static bool IsMySql(this DatabaseType databaseType)
{
return databaseType is NPoco.DatabaseTypes.MySqlDatabaseType;
}
public static bool IsSqlServer(this DatabaseType databaseType)
{
// note that because SqlServerDatabaseType is the base class for
@@ -1063,17 +1063,6 @@ namespace Umbraco.Core.Persistence
/// <returns>The Sql statement.</returns>
public static Sql<ISqlContext> ForUpdate(this Sql<ISqlContext> sql)
{
// MySql wants "FOR UPDATE" at the end, and T-Sql wants "WITH (UPDLOCK)" in the FROM statement,
// and we want to implement it in the least expensive way, so parsing the entire string here is
// a no, so we use reflection to work on the Sql expression before it is built.
// TODO propose a clean way to do that type of thing in NPoco
if (sql.SqlContext.DatabaseType.IsMySql())
{
sql.Append("FOR UPDATE");
return sql;
}
// go find the first FROM clause, and append the lock hint
Sql s = sql;
var updated = false;
@@ -300,7 +300,7 @@ ORDER BY colName";
// NPoco cannot fetch 2+ references at a time
// plus it creates a combinatorial explosion
// better use extra queries
// unfortunately, SqlCe and MySql don't support multiple result sets
// unfortunately, SqlCe doesn't support multiple result sets
private void PerformGetReferencedDtos(List<UserDto> dtos)
{
if (dtos.Count == 0) return;
@@ -72,7 +72,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax
bool SupportsClustered();
bool SupportsIdentityInsert();
bool? SupportsCaseInsensitiveQueries(IDatabase db);
string ConvertIntegerToOrderableString { get; }
string ConvertDateToOrderableString { get; }
@@ -1,402 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NPoco;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Represents an SqlSyntaxProvider for MySql
/// </summary>
public class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
{
private readonly ILogger _logger;
public MySqlSyntaxProvider(ILogger logger)
{
_logger = logger;
AutoIncrementDefinition = "AUTO_INCREMENT";
IntColumnDefinition = "int(11)";
BoolColumnDefinition = "tinyint(1)";
DateTimeColumnDefinition = "TIMESTAMP";
TimeColumnDefinition = "time";
DecimalColumnDefinition = "decimal(38,6)";
GuidColumnDefinition = "char(36)";
DefaultValueFormat = "DEFAULT {0}";
InitColumnTypeMap();
}
public override IEnumerable<string> GetTablesInSchema(IDatabase db)
{
List<string> list;
try
{
//needs to be open to read the schema name
db.OpenSharedConnection();
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @TableSchema",
new { TableSchema = db.Connection.Database });
list = items.Select(x => x.TABLE_NAME).Cast<string>().ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
public override IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db)
{
List<ColumnInfo> list;
try
{
//needs to be open to read the schema name
db.OpenSharedConnection();
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @TableSchema",
new { TableSchema = db.Connection.Database });
list =
items.Select(
item =>
new ColumnInfo(item.TABLE_NAME, item.COLUMN_NAME, int.Parse(item.ORDINAL_POSITION.ToString()), item.COLUMN_DEFAULT ?? "",
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
/// <inheritdoc />
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
{
List<Tuple<string, string>> list;
try
{
//needs to be open to read the schema name
db.OpenSharedConnection();
//Does not include indexes and constraints are named differently
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = @TableSchema",
new { TableSchema = db.Connection.Database });
list = items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
/// <inheritdoc />
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
{
List<Tuple<string, string, string>> list;
try
{
//needs to be open to read the schema name
db.OpenSharedConnection();
//Does not include indexes and constraints are named differently
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = @TableSchema",
new { TableSchema = db.Connection.Database });
list =
items.Select(
item =>
new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME))
.ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
/// <inheritdoc />
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
{
List<Tuple<string, string, string, bool>> list;
try
{
//needs to be open to read the schema name
db.OpenSharedConnection();
var indexes =
db.Fetch<dynamic>(@"SELECT DISTINCT
TABLE_NAME, INDEX_NAME, COLUMN_NAME, CASE NON_UNIQUE WHEN 1 THEN 0 ELSE 1 END AS `UNIQUE`
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = @TableSchema
AND INDEX_NAME <> COLUMN_NAME AND INDEX_NAME <> 'PRIMARY'
ORDER BY TABLE_NAME, INDEX_NAME",
new { TableSchema = db.Connection.Database });
list =
indexes.Select(
item =>
new Tuple<string, string, string, bool>(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1))
.ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
public override bool DoesTableExist(IDatabase db, string tableName)
{
long result;
try
{
//needs to be open to read the schema name
db.OpenSharedConnection();
result =
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_NAME = @TableName AND " +
"TABLE_SCHEMA = @TableSchema",
new { TableName = tableName, TableSchema = db.Connection.Database });
}
finally
{
db.CloseSharedConnection();
}
return result > 0;
}
public override Sql<ISqlContext> SelectTop(Sql<ISqlContext> sql, int top)
{
return new Sql<ISqlContext>(sql.SqlContext, string.Concat(sql.SQL, " LIMIT ", top), sql.Arguments);
}
public override bool SupportsClustered()
{
return true;
}
public override bool SupportsIdentityInsert()
{
return false;
}
/// <summary>
/// This is used ONLY if we need to format datetime without using SQL parameters (i.e. during migrations)
/// </summary>
/// <param name="date"></param>
/// <param name="includeTime"></param>
/// <returns></returns>
/// <remarks>
/// MySQL has a DateTime standard that is unambiguous and works on all servers:
/// YYYYMMDDHHMMSS
/// </remarks>
public override string FormatDateTime(DateTime date, bool includeTime = true)
{
return includeTime ? date.ToString("yyyyMMddHHmmss") : date.ToString("yyyyMMdd");
}
public override string GetQuotedTableName(string tableName)
{
return string.Format("`{0}`", tableName);
}
public override string GetQuotedColumnName(string columnName)
{
return string.Format("`{0}`", columnName);
}
public override string GetQuotedName(string name)
{
return string.Format("`{0}`", name);
}
public override string GetSpecialDbType(SpecialDbTypes dbTypes)
{
if (dbTypes == SpecialDbTypes.NCHAR)
{
return "CHAR";
}
else if (dbTypes == SpecialDbTypes.NTEXT)
return "LONGTEXT";
return "NVARCHAR";
}
public override string Format(TableDefinition table)
{
string primaryKey = string.Empty;
var columnDefinition = table.Columns.FirstOrDefault(x => x.IsPrimaryKey);
if (columnDefinition != null)
{
string columns = string.IsNullOrEmpty(columnDefinition.PrimaryKeyColumns)
? GetQuotedColumnName(columnDefinition.Name)
: string.Join(", ", columnDefinition.PrimaryKeyColumns
.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(GetQuotedColumnName));
primaryKey = string.Format(", \nPRIMARY KEY {0} ({1})", columnDefinition.IsIndexed ? "CLUSTERED" : "NONCLUSTERED", columns);
}
var statement = string.Format(CreateTable, GetQuotedTableName(table.Name), Format(table.Columns), primaryKey);
return statement;
}
public override string Format(IndexDefinition index)
{
string name = string.IsNullOrEmpty(index.Name)
? string.Format("IX_{0}_{1}", index.TableName, index.ColumnName)
: index.Name;
string columns = index.Columns.Any()
? string.Join(",", index.Columns.Select(x => GetQuotedColumnName(x.Name)))
: GetQuotedColumnName(index.ColumnName);
return string.Format(CreateIndex,
GetQuotedName(name),
GetQuotedTableName(index.TableName),
columns);
}
public override string Format(ForeignKeyDefinition foreignKey)
{
return string.Format(CreateForeignKeyConstraint,
GetQuotedTableName(foreignKey.ForeignTable),
GetQuotedColumnName(foreignKey.ForeignColumns.First()),
GetQuotedTableName(foreignKey.PrimaryTable),
GetQuotedColumnName(foreignKey.PrimaryColumns.First()),
FormatCascade("DELETE", foreignKey.OnDelete),
FormatCascade("UPDATE", foreignKey.OnUpdate));
}
public override string FormatPrimaryKey(TableDefinition table)
{
return string.Empty;
}
protected override string FormatConstraint(ColumnDefinition column)
{
return string.Empty;
}
protected override string FormatIdentity(ColumnDefinition column)
{
return column.IsIdentity ? AutoIncrementDefinition : string.Empty;
}
protected override string FormatDefaultValue(ColumnDefinition column)
{
if (column.DefaultValue == null)
return string.Empty;
//hack - probably not needed with latest changes
if (column.DefaultValue.ToString().ToLower().Equals("getdate()".ToLower()))
column.DefaultValue = SystemMethods.CurrentDateTime;
// see if this is for a system method
if (column.DefaultValue is SystemMethods)
{
string method = FormatSystemMethods((SystemMethods)column.DefaultValue);
if (string.IsNullOrEmpty(method))
return string.Empty;
return string.Format(DefaultValueFormat, method);
}
//needs quote
return string.Format(DefaultValueFormat, string.Format("'{0}'", column.DefaultValue));
}
protected override string FormatPrimaryKey(ColumnDefinition column)
{
return string.Empty;
}
protected override string FormatSystemMethods(SystemMethods systemMethod)
{
switch (systemMethod)
{
case SystemMethods.NewGuid:
return null; // NOT SUPPORTED!
case SystemMethods.CurrentDateTime:
return "CURRENT_TIMESTAMP";
}
return null;
}
public override string DeleteDefaultConstraint
{
get
{
return "ALTER TABLE {0} ALTER COLUMN {1} DROP DEFAULT";
}
}
public override string AlterColumn { get { return "ALTER TABLE {0} MODIFY COLUMN {1}"; } }
//CREATE TABLE {0} ({1}) ENGINE = INNODB versus CREATE TABLE {0} ({1}) ENGINE = MYISAM ?
public override string CreateTable { get { return "CREATE TABLE {0} ({1}{2})"; } }
public override string CreateIndex { get { return "CREATE INDEX {0} ON {1} ({2})"; } }
public override string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD FOREIGN KEY ({1}) REFERENCES {2} ({3}){4}{5}"; } }
public override string DeleteConstraint { get { return "ALTER TABLE {0} DROP {1} {2}"; } }
public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } }
public override string RenameColumn { get { return "ALTER TABLE {0} CHANGE {1} {2}"; } }
public override string ConvertIntegerToOrderableString { get { return "LPAD(FORMAT({0}, 0), 8, '0')"; } }
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(IDatabase db)
{
bool? supportsCaseInsensitiveQueries = null;
try
{
db.OpenSharedConnection();
// Need 4 @ signs as it is regarded as a parameter, @@ escapes it once, @@@@ escapes it twice
var lowerCaseTableNames = db.Fetch<int>("SELECT @@@@Global.lower_case_table_names");
if (lowerCaseTableNames.Any())
supportsCaseInsensitiveQueries = lowerCaseTableNames.First() == 1;
}
catch (Exception ex)
{
_logger.Error<MySqlSyntaxProvider>(ex, "Error querying for lower_case support");
}
finally
{
db.CloseSharedConnection();
}
// Could return null, which means testing failed,
// add message to check with their hosting provider
return supportsCaseInsensitiveQueries;
}
public override string EscapeString(string val)
{
return NPocoDatabaseExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val));
}
}
}
@@ -200,12 +200,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return "NVARCHAR";
}
public virtual bool? SupportsCaseInsensitiveQueries(IDatabase db)
{
return true;
}
public virtual IEnumerable<string> GetTablesInSchema(IDatabase db)
{
return new List<string>();
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
/// <summary>
/// This is used to generate a delete query that uses a sub-query to select the data, it is required because there's a very particular syntax that
/// needs to be used to work for all servers: MySql, SQLCE and MSSQL
/// needs to be used to work for all servers: SQLCE and MSSQL
/// </summary>
/// <returns></returns>
/// <remarks>
@@ -167,15 +167,7 @@ namespace Umbraco.Core.Persistence
#if DEBUG_DATABASES
// determines the database connection SPID for debugging
if (DatabaseType.IsMySql())
{
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT CONNECTION_ID()";
_spid = Convert.ToInt32(command.ExecuteScalar());
}
}
else if (DatabaseType.IsSqlServer())
if (DatabaseType.IsSqlServer())
{
using (var command = connection.CreateCommand())
{
@@ -247,8 +247,6 @@ namespace Umbraco.Core.Persistence
{
switch (providerName)
{
case Constants.DbProviderNames.MySql:
return new MySqlSyntaxProvider(_logger);
case Constants.DbProviderNames.SqlCe:
return new SqlCeSyntaxProvider();
case Constants.DbProviderNames.SqlServer:
-2
View File
@@ -69,7 +69,6 @@
<Version>4.0.0</Version>
</PackageReference>
<PackageReference Include="MiniProfiler" Version="3.2.0.157" />
<PackageReference Include="MySql.Data" Version="6.10.7" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NPoco" Version="3.9.4" />
<PackageReference Include="Semver" Version="2.0.4" />
@@ -1263,7 +1262,6 @@
<Compile Include="Persistence\SqlSyntax\DbTypes.cs" />
<Compile Include="Persistence\SqlSyntax\ISqlSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\MicrosoftSqlSyntaxProviderBase.cs" />
<Compile Include="Persistence\SqlSyntax\MySqlSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlCeSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlServerSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlServerVersionName.cs" />
-2
View File
@@ -74,8 +74,6 @@
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0"/>
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
<remove invariant="MySql.Data.MySqlClient"/>
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</DbProviderFactories>
</system.data>
@@ -1,822 +0,0 @@
/*******************************************************************************************
Umbraco database installation script for MySQL
IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
Database version: 4.8.0.4
Please increment this version number if ANY change is made to this script,
so compatibility with scripts for other database systems can be verified easily.
The first 3 digits depict the Umbraco version, the last digit is the database version.
(e.g. version 4.0.0.3 means "Umbraco version 4.0.0, database version 3")
Check-in policy: only commit this script if
* you ran the Umbraco installer completely;
* you ran it on the targetted database system;
* you ran the Boost and Nitro installation;
* you were able to browse the Boost site;
* you were able to open the Umbraco administration panel;
* you have documented the code change in this script;
* you have incremented the version number in this script.
IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
********************************************************************************************/
CREATE TABLE umbracoRelation
(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
parentId int NOT NULL,
childId int NOT NULL,
relType int NOT NULL,
datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
comment nvarchar (1000) NOT NULL
)
;
CREATE TABLE cmsDocument
(
nodeId int NOT NULL,
published bit NOT NULL,
documentUser int NOT NULL,
versionId CHAR(36) NOT NULL PRIMARY KEY,
text nvarchar (255) NOT NULL,
releaseDate datetime NULL,
expireDate datetime NULL,
updateDate TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
templateId int NULL,
alias nvarchar (255) NULL ,
newest bit NOT NULL DEFAULT 0
)
;
CREATE TABLE umbracoLog
(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
userId int NOT NULL,
NodeId int NOT NULL,
Datestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
logHeader nvarchar (50) NOT NULL,
logComment nvarchar (4000) NULL
)
;
CREATE TABLE umbracoUserGroup
(
id smallint NOT NULL AUTO_INCREMENT PRIMARY KEY,
userGroupName nvarchar (255) NOT NULL
)
;
/* TABLE IS NEVER USED, REMOVED FOR 4.1
CREATE TABLE umbracoUser2userGroup
(
user int NOT NULL,
userGroup smallint NOT NULL
)
;
ALTER TABLE umbracoUser2userGroup ADD CONSTRAINT PK_user2userGroup PRIMARY KEY CLUSTERED (user, userGroup)
;
*/
CREATE TABLE umbracoApp
(
sortOrder tinyint NOT NULL DEFAULT 0,
appAlias nvarchar (50) PRIMARY KEY NOT NULL,
appIcon nvarchar (255) NOT NULL,
appName nvarchar (255) NOT NULL,
appInitWithTreeAlias nvarchar (255) NULL
)
;
CREATE TABLE cmsPropertyData
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
contentNodeId int NOT NULL,
versionId CHAR(36) NULL,
propertytypeid int NOT NULL,
dataInt int NULL,
dataDate datetime NULL,
dataNvarchar nvarchar (500) NULL,
dataNtext LONGTEXT NULL
)
;
CREATE INDEX IX_cmsPropertyData_1 ON cmsPropertyData (contentNodeId)
;
CREATE INDEX IX_cmsPropertyData_2 ON cmsPropertyData (versionId)
;
CREATE INDEX IX_cmsPropertyData_3 ON cmsPropertyData (propertytypeid)
;
CREATE TABLE cmsContent
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,
nodeId int NOT NULL,
contentType int NOT NULL
)
;
CREATE TABLE cmsContentType
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,
nodeId int NOT NULL,
alias nvarchar (255) NULL,
icon nvarchar (255) NULL
)
;
CREATE TABLE cmsMacroPropertyType
(
id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT,
macroPropertyTypeAlias nvarchar (50) NULL,
macroPropertyTypeRenderAssembly nvarchar (255) NULL,
macroPropertyTypeRenderType nvarchar (255) NULL,
macroPropertyTypeBaseType nvarchar (255) NULL
)
;
/* TABLE IS NEVER USED, REMOVED FOR 4.1
CREATE TABLE umbracoStylesheetProperty
(
id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT,
stylesheetPropertyEditor bit NOT NULL DEFAULT 0,
stylesheet tinyint NOT NULL,
stylesheetPropertyAlias nvarchar (50) NULL,
stylesheetPropertyName nvarchar (255) NULL,
stylesheetPropertyValue nvarchar (400) NULL
)
;
*/
CREATE TABLE cmsTab
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
contenttypeNodeId int NOT NULL,
text nvarchar (255) NOT NULL,
sortorder int NOT NULL
)
;
CREATE TABLE cmsTemplate
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,
nodeId int NOT NULL,
master int NULL,
alias nvarchar (100) NULL,
design LONGTEXT NOT NULL
)
;
CREATE TABLE umbracoUser2app
(
user int NOT NULL,
app nvarchar (50) NOT NULL
)
;
ALTER TABLE umbracoUser2app ADD CONSTRAINT PK_user2app PRIMARY KEY CLUSTERED (user, app)
;
CREATE TABLE umbracoUserType
(
id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT,
userTypeAlias nvarchar (50) NULL,
userTypeName nvarchar (255) NOT NULL,
userTypeDefaultPermissions nvarchar (50) NULL
)
;
CREATE TABLE umbracoUser
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
userDisabled bit NOT NULL DEFAULT 0,
userNoConsole bit NOT NULL DEFAULT 0,
userType smallint NOT NULL,
startStructureID int NOT NULL,
startMediaID int NULL,
userName nvarchar (255) NOT NULL,
userLogin nvarchar (125) NOT NULL,
userPassword nvarchar (125) NOT NULL,
userEmail nvarchar (255) NOT NULL,
userDefaultPermissions nvarchar (50) NULL,
userLanguage nvarchar (10) NULL ,
defaultToLiveEditing bit NOT NULL DEFAULT 0
)
;
CREATE TABLE cmsDocumentType
(
contentTypeNodeId int NOT NULL,
templateNodeId int NOT NULL,
IsDefault bit NOT NULL DEFAULT 0
)
;
ALTER TABLE cmsDocumentType ADD CONSTRAINT PK_cmsDocumentType PRIMARY KEY CLUSTERED (contentTypeNodeId, templateNodeId)
;
CREATE TABLE cmsMemberType
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,
NodeId int NOT NULL,
propertytypeId int NOT NULL,
memberCanEdit bit NOT NULL DEFAULT 0,
viewOnProfile bit NOT NULL DEFAULT 0
)
;
CREATE TABLE cmsMember
(
nodeId int NOT NULL,
Email nvarchar (1000) NOT NULL DEFAULT '',
LoginName nvarchar (1000) NOT NULL DEFAULT '',
Password nvarchar (1000) NOT NULL DEFAULT ''
)
;
CREATE TABLE umbracoNode
(
id int NOT NULL PRIMARY KEY,
trashed bit NOT NULL DEFAULT 0,
parentID int NOT NULL,
nodeUser int NULL,
level smallint NOT NULL,
path nvarchar (150) NOT NULL,
sortOrder int NOT NULL,
uniqueID CHAR(36) NULL,
text nvarchar (255) NULL,
nodeObjectType CHAR(36) NULL,
createDate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
;
CREATE INDEX IX_umbracoNodeParentId ON umbracoNode (parentID)
;
CREATE INDEX IX_umbracoNodeObjectType ON umbracoNode (nodeObjectType)
;
CREATE TABLE cmsPropertyType
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
dataTypeId int NOT NULL,
contentTypeId int NOT NULL,
tabId int NULL,
Alias nvarchar (255) NOT NULL,
Name nvarchar (255) NULL,
helpText nvarchar (1000) NULL,
sortOrder int NOT NULL DEFAULT 0,
mandatory bit NOT NULL DEFAULT 0,
validationRegExp nvarchar (255) NULL,
Description nvarchar (2000) NULL
)
;
CREATE TABLE cmsMacroProperty
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
macroPropertyHidden bit NOT NULL DEFAULT 0,
macroPropertyType smallint NOT NULL,
macro int NOT NULL,
macroPropertySortOrder tinyint NOT NULL DEFAULT 0,
macroPropertyAlias nvarchar (50) NOT NULL,
macroPropertyName nvarchar (255) NOT NULL
)
;
CREATE TABLE cmsMacro
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
macroUseInEditor bit NOT NULL DEFAULT 0,
macroRefreshRate int NOT NULL DEFAULT 0,
macroAlias nvarchar (255) NOT NULL,
macroName nvarchar (255) NULL,
macroScriptType nvarchar (255) NULL,
macroScriptAssembly nvarchar (255) NULL,
macroXSLT nvarchar (255) NULL,
macroCacheByPage bit NOT NULL DEFAULT 1,
macroCachePersonalized bit NOT NULL DEFAULT 0,
macroDontRender bit NOT NULL DEFAULT 0
)
;
CREATE TABLE cmsContentVersion
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
ContentId int NOT NULL,
VersionId CHAR(36) NOT NULL,
VersionDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
;
CREATE TABLE umbracoAppTree
(
treeSilent bit NOT NULL DEFAULT 0,
treeInitialize bit NOT NULL DEFAULT 1,
treeSortOrder tinyint NOT NULL,
appAlias nvarchar (50) NOT NULL,
treeAlias nvarchar (150) NOT NULL,
treeTitle nvarchar (255) NOT NULL,
treeIconClosed nvarchar (255) NOT NULL,
treeIconOpen nvarchar (255) NOT NULL,
treeHandlerAssembly nvarchar (255) NOT NULL,
treeHandlerType nvarchar (255) NOT NULL,
action nvarchar (300) NULL
)
;
ALTER TABLE umbracoAppTree ADD CONSTRAINT PK_umbracoAppTree PRIMARY KEY CLUSTERED (appAlias, treeAlias)
;
CREATE TABLE cmsContentTypeAllowedContentType
(
Id int NOT NULL,
AllowedId int NOT NULL
)
;
ALTER TABLE cmsContentTypeAllowedContentType ADD CONSTRAINT PK_cmsContentTypeAllowedContentType PRIMARY KEY CLUSTERED (Id, AllowedId)
;
CREATE TABLE cmsContentXml
(
nodeId int NOT NULL PRIMARY KEY,
xml LONGTEXT NOT NULL
)
;
CREATE TABLE cmsDataType
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT PRIMARY KEY,
nodeId int NOT NULL,
controlId CHAR(36) NOT NULL,
dbType varchar (50) NOT NULL
)
;
CREATE TABLE cmsDataTypePreValues
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
datatypeNodeId int NOT NULL,
value NVARCHAR(2500) NULL,
sortorder int NOT NULL,
alias nvarchar (50) NULL
)
;
CREATE TABLE cmsDictionary
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,
id CHAR(36) NOT NULL,
parent CHAR(36) NOT NULL,
`key` nvarchar (1000) NOT NULL
)
;
CREATE TABLE cmsLanguageText
(
pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,
languageId int NOT NULL,
UniqueId CHAR(36) NOT NULL,
value nvarchar (1000) NOT NULL
)
;
CREATE TABLE cmsMember2MemberGroup
(
Member int NOT NULL,
MemberGroup int NOT NULL
)
;
ALTER TABLE cmsMember2MemberGroup ADD CONSTRAINT PK_cmsMember2MemberGroup PRIMARY KEY CLUSTERED (Member, MemberGroup)
;
CREATE TABLE cmsStylesheet
(
nodeId int NOT NULL,
filename nvarchar (100) NOT NULL,
content LONGTEXT NULL
)
;
CREATE TABLE cmsStylesheetProperty
(
nodeId int NOT NULL,
stylesheetPropertyEditor bit NULL,
stylesheetPropertyAlias nvarchar (50) NULL,
stylesheetPropertyValue nvarchar (400) NULL
)
;
CREATE TABLE umbracoDomains
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
domainDefaultLanguage int NULL,
domainRootStructureID int NULL,
domainName nvarchar (255) NOT NULL
)
;
CREATE TABLE umbracoLanguage
(
id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT,
languageISOCode nvarchar (10) NULL,
languageCultureName nvarchar (100) NULL
)
;
CREATE TABLE umbracoRelationType
(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
`dual` bit NOT NULL,
parentObjectType CHAR(36) NOT NULL,
childObjectType CHAR(36) NOT NULL,
name nvarchar (255) NOT NULL,
alias nvarchar (100) NULL
)
;
/* TABLE IS NEVER USED, REMOVED FOR 4.1
CREATE TABLE umbracoStylesheet
(
nodeId int NOT NULL PRIMARY KEY,
filename nvarchar (100) NOT NULL,
content LONGTEXT NULL
)
;
*/
CREATE TABLE umbracoUser2NodeNotify
(
userId int NOT NULL,
nodeId int NOT NULL,
action char (1) NOT NULL
)
;
ALTER TABLE umbracoUser2NodeNotify ADD CONSTRAINT PK_umbracoUser2NodeNotify PRIMARY KEY CLUSTERED (userId, nodeId, action)
;
CREATE TABLE umbracoUser2NodePermission
(
userId int NOT NULL,
nodeId int NOT NULL,
permission char (1) NOT NULL
)
;
ALTER TABLE umbracoUser2NodePermission ADD CONSTRAINT PK_umbracoUser2NodePermission PRIMARY KEY CLUSTERED (userId, nodeId, permission)
;
INSERT INTO umbracoNode (id, trashed, parentID, nodeUser, level, path, sortOrder, uniqueID, text, nodeObjectType, createDate) VALUES
(-92, 0, -1, 0, 11, '-1,-92', 37, 'f0bc4bfb-b499-40d6-ba86-058885a5178c', 'Label', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-90, 0, -1, 0, 11, '-1,-90', 35, '84c6b441-31df-4ffe-b67e-67d5bc3ae65a', 'Upload', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-89, 0, -1, 0, 11, '-1,-89', 34, 'c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3', 'Textarea', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-88, 0, -1, 0, 11, '-1,-88', 33, '0cc0eba1-9960-42c9-bf9b-60e150b429ae', 'Textstring', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-87, 0, -1, 0, 11, '-1,-87', 32, 'ca90c950-0aff-4e72-b976-a30b1ac57dad', 'Richtext editor', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-51, 0, -1, 0, 11, '-1,-51', 4, '2e6d3631-066e-44b8-aec4-96f09099b2b5', 'Numeric', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-49, 0, -1, 0, 11, '-1,-49', 2, '92897bc6-a5f3-4ffe-ae27-f2e7e33dda49', 'True/false', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-43, 0, -1, 0, 1, '-1,-43', 2, 'fbaf13a8-4036-41f2-93a3-974f678c312a', 'Checkbox list', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:11:04.367'),
(-42, 0, -1, 0, 1, '-1,-42', 2, '0b6a45e7-44ba-430d-9da5-4e46060b9e03', 'Dropdow', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:59.000'),
(-41, 0, -1, 0, 1, '-1,-41', 2, '5046194e-4237-453c-a547-15db3a07c4e1', 'Date Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:54.303'),
(-40, 0, -1, 0, 1, '-1,-40', 2, 'bb5f57c9-ce2b-4bb9-b697-4caca783a805', 'Radiobox', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:49.253'),
(-39, 0, -1, 0, 1, '-1,-39', 2, 'f38f0ac7-1d27-439c-9f3f-089cd8825a53', 'Dropdown multiple', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:44.480'),
(-38, 0, -1, 0, 1, '-1,-38', 2, 'fd9f1447-6c61-4a7c-9595-5aa39147d318', 'Folder Browser', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:37.020'),
(-37, 0, -1, 0, 1, '-1,-37', 2, '0225af17-b302-49cb-9176-b9f35cab9c17', 'Approved Color', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:30.580'),
(-36, 0, -1, 0, 1, '-1,-36', 2, 'e4d66c0f-b935-4200-81f0-025f7256b89a', 'Date Picker with time', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:23.007'),
(-20, 0, -1, 0, 0, '-1,-20', 0, '0F582A79-1E41-4CF0-BFA0-76340651891A', 'Recycle Bin', '01BB7FF2-24DC-4C0C-95A2-C24EF72BBAC8', '2004/09/30 14:01:49.920'),
(-1, 0, -1, 0, 0, '-1', 0, '916724a5-173d-4619-b97e-b9de133dd6f5', 'SYSTEM DATA: umbraco master root', 'ea7d8624-4cfe-4578-a871-24aa946bf34d', '2004/09/30 14:01:49.920'),
(1031, 0, -1, 1, 1, '-1,1031', 2, 'f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d', 'Folder', '4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e', '2004/12/01 00:13:40.743'),
(1032, 0, -1, 1, 1, '-1,1032', 2, 'cc07b313-0843-4aa8-bbda-871c8da728c8', 'Image', '4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e', '2004/12/01 00:13:43.737'),
(1033, 0, -1, 1, 1, '-1,1033', 2, '4c52d8ab-54e6-40cd-999c-7a5f24903e4d', 'File', '4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e', '2004/12/01 00:13:46.210'),
(1034, 0, -1, 0, 1, '-1,1034', 2, 'a6857c73-d6e9-480c-b6e6-f15f6ad11125', 'Content Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:29.203'),
(1035, 0, -1, 0, 1, '-1,1035', 2, '93929b9a-93a2-4e2a-b239-d99334440a59', 'Media Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:36.143'),
(1036, 0, -1, 0, 1, '-1,1036', 2, '2b24165f-9782-4aa3-b459-1de4a4d21f60', 'Member Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:40.260'),
(1038, 0, -1, 0, 1, '-1,1038', 2, '1251c96c-185c-4e9b-93f4-b48205573cbd', 'Simple Editor', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'),
(1039, 0, -1, 0, 1, '-1,1039', 2, '06f349a9-c949-4b6a-8660-59c10451af42', 'Ultimate Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'),
(1040, 0, -1, 0, 1, '-1,1040', 2, '21e798da-e06e-4eda-a511-ed257f78d4fa', 'Related Links', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'),
(1041, 0, -1, 0, 1, '-1,1041', 2, 'b6b73142-b9c1-4bf8-a16d-e1c23320b549', 'Tags', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'),
(1042, 0, -1, 0, 1, '-1,1042', 2, '0a452bd5-83f9-4bc3-8403-1286e13fb77e', 'Macro Container', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'),
(1043, 0, -1, 0, 1, '-1,1042', 2, '1df9f033-e6d4-451f-b8d2-e0cbc50a836f', 'Image Cropper', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250')
;
INSERT INTO cmsContentType (pk, nodeId, alias, icon) VALUES
(532, 1031, 'Folder', 'folder.gif'),
(533, 1032, 'Image', 'mediaPhoto.gif'),
(534, 1033, 'File', 'mediaMulti.gif')
;
INSERT INTO umbracoUserType (id, userTypeAlias, userTypeName, userTypeDefaultPermissions) VALUES
(1, 'admin', 'Administrators', 'CADMOSKTPIURZ5:'),
(2, 'writer', 'Writer', 'CAH:'),
(3, 'editor', 'Editors', 'CADMOSKTPUZ5:'),
(4, 'translator', 'Translator', 'A')
;
INSERT INTO umbracoUser (id, userDisabled, userNoConsole, userType, startStructureID, startMediaID, userName, userLogin, userPassword, userEmail, userDefaultPermissions, userLanguage) VALUES (0, 0, 0, 1, -1, -1, 'Administrator', 'admin', 'default', '', NULL, 'en')
;
UPDATE umbracoUser SET id=0 WHERE id=1 AND userLogin='admin'
;
INSERT INTO umbracoApp (appAlias, sortOrder, appIcon, appName, appInitWithTreeAlias) VALUES
('content', 0, '.traycontent', 'Indhold', 'content'),
('developer', 7, '.traydeveloper', 'Developer', NULL),
('media', 1, '.traymedia', 'Mediearkiv', NULL),
('member', 8, '.traymember', 'Medlemmer', NULL),
('settings', 6, '.traysettings', 'Indstillinger', NULL),
('users', 5, '.trayusers', 'Brugere', NULL)
;
INSERT INTO umbracoUser2app (user, app) VALUES
(0, 'content'),
(0, 'developer'),
(0, 'media'),
(0, 'member'),
(0, 'settings'),
(0, 'users')
;
INSERT INTO umbracoAppTree (appAlias, treeAlias, treeSilent, treeInitialize, treeSortOrder, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) VALUES
('content', 'content', 1, 1, 0, 'Indhold', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadContent'),
('developer', 'cacheBrowser', 0, 1, 0, 'CacheBrowser', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadCache'),
('developer', 'CacheItem', 0, 0, 0, 'Cachebrowser', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadCacheItem'),
('developer', 'datatype', 0, 1, 1, 'Datatyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadDataTypes'),
('developer', 'macros', 0, 1, 2, 'Macros', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMacros'),
('developer', 'xslt', 0, 1, 5, 'XSLT Files', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadXslt'),
('developer', 'packagerPackages', 0, 0, 1, 'Packager Packages', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadPackages'),
('media', 'media', 0, 1, 0, 'Medier', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMedia'),
('member', 'member', 0, 1, 0, 'Medlemmer', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMembers'),
('member', 'memberGroups', 0, 1, 1, 'MemberGroups', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMemberGroups'),
('member', 'memberTypes', 0, 1, 2, 'Medlemstyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMemberTypes'),
('settings', 'languages', 0, 1, 4, 'Languages', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadLanguages'),
('settings', 'mediaTypes', 0, 1, 5, 'Medietyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMediaTypes'),
('settings', 'documentTypes', 0, 1, 6, 'Dokumenttyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadNodeTypes'),
('settings', 'stylesheetProperty', 0, 0, 0, 'Stylesheet Property', '', '', 'umbraco', 'loadStylesheetProperty'),
('settings', 'stylesheets', 0, 1, 0, 'Stylesheets', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadStylesheets'),
('settings', 'templates', 0, 1, 1, 'Templates', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadTemplates'),
('users', 'users', 0, 1, 0, 'Brugere', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadUsers')
;
INSERT INTO umbracoAppTree (appAlias, treeAlias, treeSilent, treeInitialize, treeSortOrder, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType, action) VALUES
('settings', 'dictionary', 0, 1, 3, 'Dictionary', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadDictionary','openDictionary()')
;
INSERT INTO cmsMacroPropertyType (id, macroPropertyTypeAlias, macroPropertyTypeRenderAssembly, macroPropertyTypeRenderType, macroPropertyTypeBaseType) VALUES
(3, 'mediaCurrent', 'umbraco.macroRenderings', 'media', 'Int32'),
(4, 'contentSubs', 'umbraco.macroRenderings', 'content', 'Int32'),
(5, 'contentRandom', 'umbraco.macroRenderings', 'content', 'Int32'),
(6, 'contentPicker', 'umbraco.macroRenderings', 'content', 'Int32'),
(13, 'number', 'umbraco.macroRenderings', 'numeric', 'Int32'),
(14, 'bool', 'umbraco.macroRenderings', 'yesNo', 'Boolean'),
(16, 'text', 'umbraco.macroRenderings', 'text', 'String'),
(17, 'contentTree', 'umbraco.macroRenderings', 'content', 'Int32'),
(18, 'contentType', 'umbraco.macroRenderings', 'contentTypeSingle', 'Int32'),
(19, 'contentTypeMultiple', 'umbraco.macroRenderings', 'contentTypeMultiple', 'Int32'),
(20, 'contentAll', 'umbraco.macroRenderings', 'content', 'Int32'),
(21, 'tabPicker', 'umbraco.macroRenderings', 'tabPicker', 'String'),
(22, 'tabPickerMultiple', 'umbraco.macroRenderings', 'tabPickerMultiple', 'String'),
(23, 'propertyTypePicker', 'umbraco.macroRenderings', 'propertyTypePicker', 'String'),
(24, 'propertyTypePickerMultiple', 'umbraco.macroRenderings', 'propertyTypePickerMultiple', 'String'),
(25, 'textMultiLine', 'umbraco.macroRenderings', 'textMultiple', 'String')
;
INSERT INTO cmsTab (id, contenttypeNodeId, text, sortorder) VALUES
(3, 1032, 'Image', 1),
(4, 1033, 'File', 1),
(5, 1031, 'Contents', 1)
;
INSERT INTO cmsPropertyType (id, dataTypeId, contentTypeId, tabId, Alias, Name, helpText, sortOrder, mandatory, validationRegExp, Description) VALUES
(6, -90, 1032, 3, 'umbracoFile', 'Upload image', NULL, 0, 0, NULL, NULL),
(7, -92, 1032, 3, 'umbracoWidth', 'Width', NULL, 0, 0, NULL, NULL),
(8, -92, 1032, 3, 'umbracoHeight', 'Height', NULL, 0, 0, NULL, NULL),
(9, -92, 1032, 3, 'umbracoBytes', 'Size', NULL, 0, 0, NULL, NULL),
(10, -92, 1032, 3, 'umbracoExtension', 'Type', NULL, 0, 0, NULL, NULL),
(24, -90, 1033, 4, 'umbracoFile', 'Upload file', NULL, 0, 0, NULL, NULL),
(25, -92, 1033, 4, 'umbracoExtension', 'Type', NULL, 0, 0, NULL, NULL),
(26, -92, 1033, 4, 'umbracoBytes', 'Size', NULL, 0, 0, NULL, NULL),
(27, -38, 1031, 5, 'contents', 'Contents:', NULL, 0, 0, NULL, NULL)
;
INSERT INTO umbracoLanguage (id, languageISOCode, languageCultureName) VALUES (1, 'en-US', 'en-US')
;
INSERT INTO cmsContentTypeAllowedContentType (Id, AllowedId) VALUES (1031, 1031),(1031, 1032),(1031, 1033)
;
INSERT INTO cmsDataType (pk, nodeId, controlId, dbType) VALUES
(4, -49, '38b352c1-e9f8-4fd8-9324-9a2eab06d97a', 'Integer'),
(6, -51, '1413afcb-d19a-4173-8e9a-68288d2a73b8', 'Integer'),
(8, -87, '5E9B75AE-FACE-41c8-B47E-5F4B0FD82F83', 'Ntext'),
(9, -88, 'ec15c1e5-9d90-422a-aa52-4f7622c63bea', 'Nvarchar'),
(10, -89, '67db8357-ef57-493e-91ac-936d305e0f2a', 'Ntext'),
(11, -90, '5032a6e6-69e3-491d-bb28-cd31cd11086c', 'Nvarchar'),
(12, -91, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'),
(13, -92, '6c738306-4c17-4d88-b9bd-6546f3771597', 'Nvarchar'),
(14, -36, 'b6fb1622-afa5-4bbf-a3cc-d9672a442222', 'Date'),
(15, -37, 'f8d60f68-ec59-4974-b43b-c46eb5677985', 'Nvarchar'),
(16, -38, 'cccd4ae9-f399-4ed2-8038-2e88d19e810c', 'Nvarchar'),
(17, -39, '928639ed-9c73-4028-920c-1e55dbb68783', 'Nvarchar'),
(18, -40, 'a52c7c1c-c330-476e-8605-d63d3b84b6a6', 'Nvarchar'),
(19, -41, '23e93522-3200-44e2-9f29-e61a6fcbb79a', 'Date'),
(20, -42, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Integer'),
(21, -43, 'b4471851-82b6-4c75-afa4-39fa9c6a75e9', 'Nvarchar'),
(22, -44, 'a3776494-0574-4d93-b7de-efdfdec6f2d1', 'Ntext'),
(23, -128, 'a52c7c1c-c330-476e-8605-d63d3b84b6a6', 'Nvarchar'),
(24, -129, '928639ed-9c73-4028-920c-1e55dbb68783', 'Nvarchar'),
(25, -130, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'),
(26, -131, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'),
(27, -132, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'),
(28, -133, '6c738306-4c17-4d88-b9bd-6546f3771597', 'Ntext'),
(29, -134, '928639ed-9c73-4028-920c-1e55dbb68783', 'Nvarchar'),
(30, -50, 'aaf99bb2-dbbe-444d-a296-185076bf0484', 'Date'),
(31, 1034, '158aa029-24ed-4948-939e-c3da209e5fba', 'Integer'),
(32, 1035, 'ead69342-f06d-4253-83ac-28000225583b', 'Integer'),
(33, 1036, '39f533e4-0551-4505-a64b-e0425c5ce775', 'Integer'),
(35, 1038, '60b7dabf-99cd-41eb-b8e9-4d2e669bbde9', 'Ntext'),
(36, 1039, 'cdbf0b5d-5cb2-445f-bc12-fcaaec07cf2c', 'Ntext'),
(37, 1040, '71b8ad1a-8dc2-425c-b6b8-faa158075e63', 'Ntext'),
(38, 1041, '4023e540-92f5-11dd-ad8b-0800200c9a66', 'Ntext'),
(39, 1042, '474FCFF8-9D2D-11DE-ABC6-AD7A56D89593', 'Ntext'),
(40, 1043, '7A2D436C-34C2-410F-898F-4A23B3D79F54', 'Ntext')
;
ALTER TABLE umbracoAppTree ADD FOREIGN KEY (appAlias) REFERENCES umbracoApp (appAlias)
;
ALTER TABLE cmsPropertyData ADD FOREIGN KEY (contentNodeId) REFERENCES umbracoNode (id)
;
/* TABLE IS NEVER USED, REMOVED FOR 4.1
ALTER TABLE umbracoUser2userGroup ADD FOREIGN KEY (user) REFERENCES umbracoUser (id)
;
ALTER TABLE umbracoUser2userGroup ADD FOREIGN KEY (userGroup) REFERENCES umbracoUserGroup (id)
;
*/
ALTER TABLE cmsDocument ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id)
;
ALTER TABLE cmsMacroProperty ADD FOREIGN KEY (macroPropertyType) REFERENCES cmsMacroPropertyType (id)
;
ALTER TABLE umbracoUser ADD FOREIGN KEY (userType) REFERENCES umbracoUserType (id)
;
ALTER TABLE cmsTemplate ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id)
;
ALTER TABLE cmsContentType ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id)
;
ALTER TABLE umbracoNode ADD FOREIGN KEY (parentID) REFERENCES umbracoNode (id)
;
ALTER TABLE cmsPropertyType ADD FOREIGN KEY (tabId) REFERENCES cmsTab (id)
;
ALTER TABLE cmsContent ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id)
;
ALTER TABLE umbracoUser2app ADD FOREIGN KEY (app) REFERENCES umbracoApp (appAlias)
;
/* TABLE IS NEVER USED, REMOVED FOR 4.1
ALTER TABLE umbracoUser2userGroup ADD FOREIGN KEY (user) REFERENCES umbracoUser (id)
;
*/
CREATE TABLE cmsTask
(
closed bit NOT NULL DEFAULT 0,
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
taskTypeId tinyint NOT NULL,
nodeId int NOT NULL,
parentUserId int NOT NULL,
userId int NOT NULL,
DateTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
Comment nvarchar (500) NULL
)
;
CREATE TABLE cmsTaskType
(
id tinyint NOT NULL PRIMARY KEY AUTO_INCREMENT,
alias nvarchar (255) NOT NULL
)
;
insert into cmsTaskType (alias) values ('toTranslate')
;
insert into umbracoRelationType (`dual`, parentObjectType, childObjectType, name, alias) values (1, 'c66ba18e-eaf3-4cff-8a22-41b16d66a972', 'c66ba18e-eaf3-4cff-8a22-41b16d66a972', 'Relate Document On Copy','relateDocumentOnCopy')
;
ALTER TABLE cmsMacro ADD macroPython nvarchar(255)
;
INSERT INTO umbracoAppTree(treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) VALUES(0, 1, 4, 'developer', 'python', 'Python Files', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadPython')
;
INSERT INTO umbracoAppTree(treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) VALUES(0, 1, 2, 'settings', 'scripts', 'Scripts', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadScripts')
;
alter TABLE cmsContentType add thumbnail nvarchar(255) NOT NULL DEFAULT 'folder.png'
;
alter TABLE cmsContentType add description nvarchar(1500) NULL
;
alter TABLE cmsContentType add masterContentType int NULL
;
insert into cmsDataTypePreValues (id, dataTypeNodeId, value, sortorder, alias) values
(3,-87,',code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|', 0, ''),
(4,1041,'default', 0, 'group')
;
UPDATE umbracoUserType SET userTypeDefaultPermissions = CONCAT(userTypeDefaultPermissions, 'F') WHERE INSTR(userTypeDefaultPermissions,'A') >= 1
AND INSTR(userTypeDefaultPermissions,'F') < 1
;
UPDATE umbracoUserType SET userTypeDefaultPermissions = CONCAT(userTypeDefaultPermissions, 'H') WHERE userTypeAlias = 'writer'
AND INSTR(userTypeDefaultPermissions,'F') < 1
;
INSERT IGNORE INTO umbracoUser2NodePermission (userID, nodeId, permission)
SELECT userID, nodeId, 'F' FROM umbracoUser2NodePermission WHERE permission='A'
;
INSERT IGNORE INTO umbracoUser2NodePermission (userID, nodeId, permission)
SELECT DISTINCT userID, nodeId, 'H' FROM umbracoUser2NodePermission WHERE userId IN
(SELECT umbracoUser.id FROM umbracoUserType INNER JOIN umbracoUser ON umbracoUserType.id = umbracoUser.userType WHERE (umbracoUserType.userTypeAlias = 'writer'))
;
INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES (0, 0, 0, 'content', 'contentRecycleBin', 'RecycleBin', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.ContentRecycleBin')
;
INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES (0, 1, 1, 'users', 'userTypes', 'User Types', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.UserTypes')
;
INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES (0, 1, 2, 'users', 'userPermissions', 'User Permissions', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.UserPermissions')
;
CREATE TABLE cmsTagRelationship
(
nodeId int NOT NULL,
tagId int NOT NULL
);
ALTER TABLE cmsTagRelationship ADD CONSTRAINT PK_user2app PRIMARY KEY CLUSTERED (nodeId, tagId);
CREATE TABLE cmsTags(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
tag VARCHAR(200) NULL,
parentId INT NULL,
`group` VARCHAR(100) NULL
);
ALTER TABLE cmsTagRelationship ADD CONSTRAINT umbracoNode_cmsTagRelationship FOREIGN KEY(nodeId)
REFERENCES umbracoNode (id)
ON DELETE CASCADE;
ALTER TABLE cmsTagRelationship ADD CONSTRAINT cmsTags_cmsTagRelationship FOREIGN KEY(tagId)
REFERENCES cmsTags (id)
ON DELETE CASCADE;
/* TRANSLATION RELATED SQL */
INSERT INTO umbracoApp (appAlias, sortOrder, appIcon, appName, appInitWithTreeAlias)
VALUES ('translation', 5, '.traytranslation', 'Translation', NULL)
;
INSERT INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES (0, 1, 1, 'translation','openTasks', 'Tasks assigned to you', '.sprTreeFolder', '.sprTreeFolder_o', 'umbraco', 'loadOpenTasks')
;
INSERT INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES (0, 1, 2, 'translation','yourTasks', 'Tasks created by you', '.sprTreeFolder', '.sprTreeFolder_o', 'umbraco', 'loadYourTasks')
;
ALTER TABLE umbraconode MODIFY COLUMN id INTEGER NOT NULL AUTO_INCREMENT; /* fix for MySQL bug 36411 */
/* remove auto increment so we can insert identity */
ALTER TABLE umbraconode MODIFY COLUMN id INTEGER NOT NULL;
/* INSERT NEW MEDIA RECYCLE BIN NODE */
INSERT INTO umbracoNode (id, trashed, parentID, nodeUser, level, path, sortOrder, uniqueID, text, nodeObjectType, createDate)
VALUES (-21, 0, -1, 0, 0, '-1,-21', 0, 'BF7C7CBC-952F-4518-97A2-69E9C7B33842', 'Recycle Bin', 'CF3D8E34-1C1C-41e9-AE56-878B57B32113', '2009/08/28 00:28:28.920')
;
/* re-add auto increment */
ALTER TABLE umbraconode MODIFY COLUMN id INTEGER NOT NULL AUTO_INCREMENT;
/* Add the mediaRecycleBin tree type */
INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES (0, 0, 0, 'media', 'mediaRecycleBin', 'RecycleBin', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.MediaRecycleBin')
;
CREATE TABLE cmsPreviewXml(
nodeId int NOT NULL,
versionId CHAR(36) NOT NULL,
timestamp datetime NOT NULL,
xml LONGTEXT NOT NULL)
;
ALTER TABLE cmsPreviewXml ADD CONSTRAINT PK_cmsContentPreviewXml PRIMARY KEY CLUSTERED (nodeId, versionId)
;
/* Create missing indexes and primary keys */
CREATE INDEX IX_Icon ON cmsContentType(nodeId, icon)
;
/* CHANGE:Allan Stegelmann Laustsen */
/* Create Custom Index to speed up tree loading */
CREATE INDEX IX_contentid_versiondate ON cmscontentversion(CONTENTID, VERSIONDATE)
;
/* CHANGE:End */
@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Migrations.SqlScripts {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SqlResources {
@@ -60,31 +60,6 @@ namespace Umbraco.Tests.Migrations.SqlScripts {
}
}
/// <summary>
/// Looks up a localized string similar to /*******************************************************************************************
///
///
///
///
///
///
///
/// Umbraco database installation script for MySQL
///
///IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
///
/// Database version: 4.8.0.4
///
/// Please increment this version number if ANY change is made to this script,
/// so compatibility with scripts for other database systems can be verified easily.
/// The first 3 digits depict the Umbraco version, t [rest of string was truncated]&quot;;.
/// </summary>
internal static string MySqlTotal_480 {
get {
return ResourceManager.GetString("MySqlTotal_480", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to CREATE TABLE [umbracoUserType] (
/// [id] int NOT NULL IDENTITY (5,1)
@@ -118,9 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="MySqlTotal_480" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>mysqltotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="SqlCeTotal_480" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>sqlcetotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
@@ -130,4 +127,4 @@
<data name="SqlServerTotal_480" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>sqlservertotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>
</root>
@@ -160,41 +160,7 @@ namespace Umbraco.Tests.Persistence.Querying
Assert.AreEqual("upper([umbracoUser].[userLogin]) = upper(@0)", result);
Assert.AreEqual("hello@world.com", modelToSqlExpressionHelper.GetSqlParameters()[0]);
}
[Test]
public void Model_Expression_Value_Does_Not_Get_Double_Escaped()
{
//mysql escapes backslashes, so we'll test with that
var sqlSyntax = new MySqlSyntaxProvider(Mock.Of<ILogger>());
var sqlContext = new SqlContext(sqlSyntax, DatabaseType.MySQL, SqlContext.PocoDataFactory);
Expression<Func<IUser, bool>> predicate = user => user.Username.Equals("mydomain\\myuser");
var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor<IUser>(sqlContext.SqlSyntax, Mappers);
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Model to Sql ExpressionHelper: \n" + result);
Assert.AreEqual("upper(`umbracoUser`.`userLogin`) = upper(@0)", result);
Assert.AreEqual("mydomain\\myuser", modelToSqlExpressionHelper.GetSqlParameters()[0]);
}
[Test]
public void Poco_Expression_Value_Does_Not_Get_Double_Escaped()
{
//mysql escapes backslashes, so we'll test with that
var sqlSyntax = new MySqlSyntaxProvider(Mock.Of<ILogger>());
var sqlContext = new SqlContext(sqlSyntax, DatabaseType.MySQL, SqlContext.PocoDataFactory);
Expression<Func<UserDto, bool>> predicate = user => user.Login.StartsWith("mydomain\\myuser");
var modelToSqlExpressionHelper = new PocoToSqlExpressionVisitor<UserDto>(sqlContext, null);
var result = modelToSqlExpressionHelper.Visit(predicate);
Debug.Print("Poco to Sql ExpressionHelper: \n" + result);
Assert.AreEqual("upper(`umbracoUser`.`userLogin`) LIKE upper(@0)", result);
Assert.AreEqual("mydomain\\myuser%", modelToSqlExpressionHelper.GetSqlParameters()[0]);
}
[Test]
public void Sql_Replace_Mapped()
{
@@ -6,8 +6,7 @@ angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseControll
$scope.dbs = [
{ name: 'Microsoft SQL Server Compact (SQL CE)', id: 0},
{ name: 'Microsoft SQL Server', id: 1},
{ name: 'Microsoft SQL Azure', id: 3 },
{ name: 'MySQL', id: 2 },
{ name: 'Microsoft SQL Azure', id: 3 },
{ name: 'Custom connection string', id: -1}
];
@@ -1,18 +1,5 @@
<div class="umb-editors">
<!-- FIXME -->
<!--
For some reason I can't get the animation to work when we use the umb-editor directive.
The the template isn't rendered quick enough and we can't access the css classes inside the directive
I have also tried with the animation service but I can't get the animations to run when the ng-repeat is on the umb-editor directive
<umb-editor
ng-repeat="editor in editors"
model="editor">
</umb-editor>
-->
<!-- Temp solution -->
<div class="umb-editor" ng-repeat="model in editors" ng-style="model.style" ng-class="{'umb-editor--small': model.size === 'small', 'umb-editor--animating': model.animating}">
<div ng-if="!model.view && !model.animating" ng-transclude></div>
<div ng-if="model.view && !model.animating" ng-include="model.view"></div>
-1
View File
@@ -104,7 +104,6 @@
<PackageReference Include="Microsoft.Owin.Security.Cookies" Version="4.0.0" />
<PackageReference Include="Microsoft.Owin.Security.OAuth" Version="4.0.0" />
<PackageReference Include="MiniProfiler" Version="3.2.0.157" />
<PackageReference Include="MySql.Data" Version="6.10.7" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Umbraco.ModelsBuilder.Ui">
<Version>8.0.0-alpha.33</Version>
@@ -115,8 +115,6 @@ namespace Umbraco.Web.UI.Umbraco.Developer.Macros
protected IEnumerable<IDataEditor> GetMacroParameterEditors()
{
// we need to show the depracated ones for backwards compatibility
// FIXME not managing deprecated here?!
return Current.ParameterEditors;
}
-8
View File
@@ -71,8 +71,6 @@
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe" />
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" />
</DbProviderFactories>
</system.data>
@@ -150,12 +148,6 @@
</providers>
</roleManager>
<siteMap>
<providers>
<remove name="MySqlSiteMapProvider" />
</providers>
</siteMap>
</system.web>
<system.webServer>
-2
View File
@@ -100,8 +100,6 @@ namespace Umbraco.Web.Install
var syntax = sqlContext.SqlSyntax;
if (syntax is SqlCeSyntaxProvider)
dbProvider = "SqlServerCE";
else if (syntax is MySqlSyntaxProvider)
dbProvider = "MySql";
else if (syntax is SqlServerSyntaxProvider)
dbProvider = (syntax as SqlServerSyntaxProvider).ServerVersion.IsAzure ? "SqlAzure" : "SqlServer";
@@ -4,7 +4,6 @@
{
SqlCe,
SqlServer,
MySql,
SqlAzure,
Custom
}
@@ -273,8 +273,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
/// <inheritdoc />
public override PublishedItemType ItemType => _contentNode.ContentType.ItemType;
// fixme
// was => _contentData.Published == false;
/// <inheritdoc />
public override bool IsDraft(string culture = null)
{
@@ -201,7 +201,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private void InitializeRepositoryEvents()
{
//fixme: The reason these events are in the repository is for legacy, the events should exist at the service
//todo: The reason these events are in the repository is for legacy, the events should exist at the service
// level now since we can fire these events within the transaction... so move the events to service level
// plug repository event handlers
@@ -584,7 +584,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
continue;
}
// fixme - should we do some RV check here? (later)
// todo- should we do some RV check here? (later)
var capture = payload;
using (var scope = _scopeProvider.CreateScope())
@@ -674,7 +674,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
continue;
}
// fixme - should we do some RV checks here? (later)
// todo- should we do some RV checks here? (later)
var capture = payload;
using (var scope = _scopeProvider.CreateScope())
@@ -773,7 +773,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
using (_contentStore.GetWriter(_scopeProvider))
using (_mediaStore.GetWriter(_scopeProvider))
{
// fixme - need to add a datatype lock
// todo - need to add a datatype lock
// this is triggering datatypes reload in the factory, and right after we create some
// content types by loading them ... there's a race condition here, which would require
// some locking on datatypes
@@ -30,7 +30,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
private Task _collectTask;
private volatile int _wlocked;
// fixme - collection trigger (ok for now)
// minGenDelta to be adjusted
// we may want to throttle collects even if delta is reached
// we may want to force collect if delta is not reached but very old
@@ -107,7 +106,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
// gets a scope contextual representing a locked writer to the dictionary
// fixme GetScopedWriter? should the dict have a ref onto the scope provider?
// GetScopedWriter? should the dict have a ref onto the scope provider?
public IDisposable GetWriter(IScopeProvider scopeProvider)
{
return ScopeContextualBase.Get(scopeProvider, _instanceId, scoped => new SnapDictionaryWriter(this, scoped));
@@ -12,7 +12,7 @@ namespace Umbraco.Web.PublishedCache
//
// at the moment we do NOT support models for sets - that would require
// an entirely new models factory + not even sure it makes sense at all since
// sets are created manually fixme yes it does!
// sets are created manually todo yes it does! - what does this all mean?
//
internal class PublishedElement : IPublishedElement
{
@@ -25,7 +25,6 @@ namespace Umbraco.Web.PublishedCache
_membershipUser = member;
_publishedMemberType = publishedMemberType ?? throw new ArgumentNullException(nameof(publishedMemberType));
// fixme
// RawValueProperty is used for two things here
// - for the 'map properties' thing that we should really get rid of
// - for populating properties that every member should always have, and that we force-create
@@ -49,8 +48,6 @@ namespace Umbraco.Web.PublishedCache
#region Membership provider member properties
// fixme why this?
public string Email => _membershipUser.Email;
public string UserName => _membershipUser.Username;
@@ -5,7 +5,7 @@ using Umbraco.Core.Scoping;
namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
// fixme should be a ScopeContextualBase
// todo should be a ScopeContextualBase
internal class SafeXmlReaderWriter : IDisposable
{
private readonly bool _scoped;
@@ -369,7 +369,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
catch (InvalidOperationException e)
{
// fixme - enable!
// todo - enable!
//content.Instance.RefreshContentFromDatabase();
throw new InvalidOperationException($"{e.Message}. This usually indicates that the content cache is corrupt; the content cache has been rebuilt in an attempt to self-fix the issue.");
}
@@ -69,7 +69,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// internal for unit tests
// no file nor db, no config check
// fixme - er, we DO have a DB?
// todo - er, we DO have a DB?
internal XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom,
bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer)
@@ -602,7 +602,7 @@ AND (umbracoNode.id=@id)";
// should we have async versions that would do: ?
// var releaser = await _xmlLock.LockAsync();
//
// fixme - not sure about the "resync current published snapshot" thing here, see 7.6...
// todo - not sure about the "resync current published snapshot" thing here, see 7.6...
// gets a locked safe read access to the main xml
private SafeXmlReaderWriter GetSafeXmlReader()
@@ -641,7 +641,7 @@ AND (umbracoNode.id=@id)";
public void EnsureFilePermission()
{
// FIXME - but do we really have a store, initialized, at that point?
// todo - but do we really have a store, initialized, at that point?
var filename = _xmlFileName + ".temp";
File.WriteAllText(filename, "TEMP");
File.Delete(filename);
@@ -1559,8 +1559,8 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
// need to update the published xml if we're saving the published version,
// or having an impact on that version - we update the published xml even when masked
// fixme - in the repo... either its 'unpublished' and 'publishing', or 'published' and 'published', this has changed!
// fixme - what are we serializing really? which properties?
// todo - in the repo... either its 'unpublished' and 'publishing', or 'published' and 'published', this has changed!
// todo - what are we serializing really? which properties?
// if not publishing, no change to published xml
if (((Content) entity).PublishedState != PublishedState.Publishing)
@@ -1669,7 +1669,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
// RepositoryCacheMode.Scoped because we do NOT want to use the L2 cache that may be out-of-sync
// hopefully this does not cause issues and we're not nested in another scope w/different mode
// fixme - well, guess what?
// todo - well, guess what?
// original code made sure the repository used no cache
// now we're using the Scoped scope cache mode
// and then?
@@ -2027,7 +2027,7 @@ AND cmsPreviewXml.nodeId IS NULL OR cmsPreviewXml.xml NOT LIKE '% key=""'
{
// every non-trashed media item should have a corresponding row in cmsContentXml
// and that row should have the key="..." attribute
// fixme - where's the trashed test here?
// todo - where's the trashed test here?
var mediaObjectType = Constants.ObjectTypes.Media;
var db = scope.Database;
@@ -251,7 +251,7 @@ namespace Umbraco.Web
public static IEnumerable<PublishedSearchResult> SearchDescendants(this IPublishedContent content, string term, string indexName = null)
{
//fixme: pass in the IExamineManager
//todo inject examine manager
indexName = string.IsNullOrEmpty(indexName) ? Constants.UmbracoIndexes.ExternalIndexName : indexName;
if (!ExamineManager.Instance.TryGetIndex(indexName, out var index))
@@ -272,7 +272,7 @@ namespace Umbraco.Web
public static IEnumerable<PublishedSearchResult> SearchChildren(this IPublishedContent content, string term, string indexName = null)
{
//fixme: pass in the IExamineManager
//todo inject examine manager
indexName = string.IsNullOrEmpty(indexName) ? Constants.UmbracoIndexes.ExternalIndexName : indexName;
if (!ExamineManager.Instance.TryGetIndex(indexName, out var index))
@@ -954,7 +954,7 @@ namespace Umbraco.Web
/// </remarks>
public static IEnumerable<IPublishedContent> Children(this IPublishedContent content, string culture = null)
{
if (content == null) throw new ArgumentNullException(nameof(content)); // fixme wtf is this?
if (content == null) throw new ArgumentNullException(nameof(content)); // fixme/task wtf is this?
return content.Children.Where(x =>
{
@@ -1017,7 +1017,7 @@ namespace Umbraco.Web
/// <summary>
/// Gets the first child of the content, of a given content type.
/// </summary>
public static IPublishedContent FirstChild(this IPublishedContent content, string alias, string culture = null) // fixme oops
public static IPublishedContent FirstChild(this IPublishedContent content, string alias, string culture = null) // fixme/task oops
{
return content.Children(culture,alias).FirstOrDefault();
}
@@ -69,25 +69,6 @@ namespace Umbraco.Web
return prop != null && prop.HasValue(culture, segment);
}
// fixme - .Value() refactoring - in progress
// missing variations...
/// <summary>
/// Returns one of two strings depending on whether the content has a value for a property identified by its alias.
/// </summary>
/// <param name="content">The content.</param>
/// <param name="alias">The property alias.</param>
/// <param name="valueIfTrue">The value to return if the content has a value for the property.</param>
/// <param name="valueIfFalse">The value to return if the content has no value for the property.</param>
/// <returns>Either <paramref name="valueIfTrue"/> or <paramref name="valueIfFalse"/> depending on whether the content
/// has a value for the property identified by the alias.</returns>
public static IHtmlString IfValue(this IPublishedElement content, string alias, string valueIfTrue, string valueIfFalse = null)
{
return content.HasValue(alias)
? new HtmlString(valueIfTrue)
: new HtmlString(valueIfFalse ?? string.Empty);
}
#endregion
#region Value
@@ -165,57 +146,6 @@ namespace Umbraco.Web
#endregion
#region Value or Umbraco.Field - WORK IN PROGRESS
// fixme - .Value() refactoring - in progress
// trying to reproduce Umbraco.Field so we can get rid of it
//
// what we want:
// - alt aliases
// - recursion
// - default value
// - before & after (if value)
//
// convertLineBreaks: should be an extension string.ConvertLineBreaks()
// stripParagraphs: should be an extension string.StripParagraphs()
// format: should use the standard .ToString(format)
//
// see UmbracoComponentRenderer.Field - which is ugly ;-(
// recurse first, on each alias (that's how it's done in Field)
//
// there is no strongly typed recurse, etc => needs to be in ModelsBuilder?
// that one can only happen in ModelsBuilder as that's where the attributes are defined
// the attribute that carries the alias is in ModelsBuilder!
//public static TValue Value<TModel, TValue>(this TModel content, Expression<Func<TModel, TValue>> propertySelector, ...)
// where TModel : IPublishedElement
//{
// PropertyInfo pi = GetPropertyFromExpression(propertySelector);
// var attr = pi.GetCustomAttribute<ImplementPropertyAttribute>();
// var alias = attr.Alias;
// return content.Value<TValue>(alias, ...)
//}
// recurse should be implemented via fallback
// todo - that one should be refactored, missing culture and so many things
public static IHtmlString Value<T>(this IPublishedElement content, string aliases, Func<T, string> format, string alt = "")
{
if (format == null) format = x => x.ToString();
var property = aliases.Split(',')
.Where(x => string.IsNullOrWhiteSpace(x) == false)
.Select(x => content.GetProperty(x.Trim()))
.FirstOrDefault(x => x != null);
return property != null
? new HtmlString(format(property.Value<T>()))
: new HtmlString(alt);
}
#endregion
#region ToIndexedArray
public static IndexedArrayItem<TContent>[] ToIndexedArray<TContent>(this IEnumerable<TContent> source)
@@ -96,7 +96,7 @@ namespace Umbraco.Web.Routing
return v.InvariantContains(a1) || v.InvariantContains(a2);
}
// fixme - even with Linq, what happens below has to be horribly slow
// todo - even with Linq, what happens below has to be horribly slow
// but the only solution is to entirely refactor url providers to stop being dynamic
if (rootNodeId > 0)
+2 -2
View File
@@ -107,7 +107,7 @@ namespace Umbraco.Web.Routing
/// <param name="filter">An optional function to filter the list of domains, if more than one applies.</param>
/// <returns>The domain and its normalized uri, that best matches the specified uri and cultures.</returns>
/// <remarks>
/// fixme - must document and explain this all
/// todo - must document and explain this all
/// <para>If <paramref name="uri"/> is null, pick the first domain that matches <paramref name="culture"/>,
/// else the first that matches <paramref name="defaultCulture"/>, else the first one (ordered by id), else null.</para>
/// <para>If <paramref name="uri"/> is not null, look for domains that would be a base uri of the current uri,</para>
@@ -244,7 +244,7 @@ namespace Umbraco.Web.Routing
/// <returns>The domains and their normalized uris, that match the specified uri.</returns>
internal static IEnumerable<DomainAndUri> SelectDomains(IEnumerable<Domain> domains, Uri uri)
{
// fixme where are we matching ?!!?
// todo where are we matching ?!!?
return domains
.Where(d => d.IsWildcard == false)
.Select(d => new DomainAndUri(d, uri))
+3 -4
View File
@@ -19,8 +19,7 @@ using RenderingEngine = Umbraco.Core.RenderingEngine;
namespace Umbraco.Web.Routing
{
// fixme - make this public
// fixme - making sense to have an interface?
// todo - making sense to have an interface?
public class PublishedRouter
{
private readonly IWebRoutingSection _webRoutingSection;
@@ -53,7 +52,7 @@ namespace Umbraco.Web.Routing
GetRolesForLogin = s => Roles.Provider.GetRolesForUser(s);
}
// fixme
// todo
// in 7.7 this is cached in the PublishedContentRequest, which ... makes little sense
// killing it entirely, if we need cache, just implement it properly !!
// this is all soooo weird
@@ -381,7 +380,7 @@ namespace Umbraco.Web.Routing
// NOTE: we could start with what's the current default?
// fixme - bad - we probably should be using the appropriate filesystems!
// todo - bad - we probably should be using the appropriate filesystems!
if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.MvcViews)),
alias, new[] { ".cshtml", ".vbhtml" }))
+2 -2
View File
@@ -181,7 +181,7 @@ namespace Umbraco.Web.Routing
/// <inheritdoc />
public virtual IEnumerable<DomainAndUri> MapDomains(IReadOnlyCollection<DomainAndUri> domainAndUris, Uri current, bool excludeDefault, string culture, string defaultCulture)
{
// fixme ignoring cultures entirely?
// todo ignoring cultures entirely?
var currentAuthority = current.GetLeftPart(UriPartial.Authority);
KeyValuePair<string, string[]>[] candidateSites = null;
@@ -279,7 +279,7 @@ namespace Umbraco.Web.Routing
if (domainAndUris == null) throw new ArgumentNullException(nameof(domainAndUris));
if (domainAndUris.Count == 0) throw new ArgumentException("Cannot be empty.", nameof(domainAndUris));
// fixme how shall we deal with cultures?
// todo how shall we deal with cultures?
// we do our best, but can't do the impossible
// get the "default" domain ie the first one for the culture, else the first one (exists, length > 0)
@@ -108,7 +108,7 @@ namespace Umbraco.Web.Runtime
.SetDefaultRenderMvcController<RenderMvcController>(); // default controller for template views
composition.WithCollectionBuilder<SearchableTreeCollectionBuilder>()
.Add(() => composition.TypeLoader.GetTypes<ISearchableTree>()); // fixme which searchable trees?!
.Add(() => composition.TypeLoader.GetTypes<ISearchableTree>());
composition.Register<UmbracoTreeSearcher>(Lifetime.Request);
@@ -15,6 +15,6 @@ namespace Umbraco.Web.Scheduling
void Add(T task);
bool TryAdd(T task);
// fixme - complete the interface?
// todo - complete the interface?
}
}
@@ -56,7 +56,7 @@ namespace Umbraco.Web.Scheduling
// ensure we run with an UmbracoContext, because this may run in a background task,
// yet developers may be using the 'current' UmbracoContext in the event handlers
//
// fixme
// todo
// - or maybe not, CacheRefresherComponent already ensures a context when handling events
// - UmbracoContext 'current' needs to be refactored and cleaned up
// - batched messenger should not depend on a current HttpContext
+1 -2
View File
@@ -154,7 +154,6 @@ namespace Umbraco.Web.Search
_rebuildOnStartupRunner = new BackgroundTaskRunner<IBackgroundTask>(
"RebuildIndexesOnStartup",
//new BackgroundTaskRunnerOptions{ LongRunning= true }, //fixme, this flag doesn't have any affect anymore
logger);
_rebuildOnStartupRunner.TryAdd(task);
@@ -214,7 +213,7 @@ namespace Umbraco.Web.Search
// just ignore that payload
// so what?!
//fixme: Rebuild the index at this point?
//todo: Rebuild the index at this point?
}
else // RefreshNode or RefreshBranch (maybe trashed)
{
+1 -1
View File
@@ -326,7 +326,7 @@ namespace Umbraco.Web.Security
switch (umbracoType)
{
case UmbracoObjectTypes.Member:
// fixme - need to implement Get(guid)!
// todo - need to implement Get(guid)!
var memberAttempt = entityService.GetId(guidUdi.Guid, umbracoType);
if (memberAttempt.Success)
return GetById(memberAttempt.Result);
@@ -37,8 +37,8 @@ namespace Umbraco.Web.Templates
_umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
}
private IFileService FileService => Current.Services.FileService; // fixme inject
private PublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<PublishedRouter>(); // fixme inject
private IFileService FileService => Current.Services.FileService; // todo inject
private PublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<PublishedRouter>(); // todo inject
/// <summary>
@@ -235,7 +235,6 @@ namespace Umbraco.Web.Trees
AddActionNode<ActionSort>(item, menu, true);
AddActionNode<ActionAssignDomain>(item, menu, opensDialog: true);
AddActionNode<ActionRights>(item, menu, opensDialog: true);
//fixme - conver this editor to angular
AddActionNode<ActionProtect>(item, menu, true, convert: true, opensDialog: true);
if (EmailSender.CanSendRequiredEmail)
{
@@ -308,7 +307,7 @@ namespace Umbraco.Web.Trees
entity.Name = "[[" + entity.Id + "]]";
}
//fixme: Remove the need for converting to legacy
//todo: Remove the need for converting to legacy
private void AddActionNode<TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false, bool opensDialog = false)
where TAction : IAction
{
@@ -401,7 +401,7 @@ namespace Umbraco.Web.Trees
internal IEnumerable<MenuItem> GetAllowedUserMenuItemsForNode(IUmbracoEntity dd)
{
var permission = Services.UserService.GetPermissions(Security.CurrentUser, dd.Path);
//fixme: inject
//todo: inject
var actions = Current.Actions.FromEntityPermission(permission)
.ToList();
+1 -1
View File
@@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees
[Tree(Constants.Applications.Settings, "files", "Files", "icon-folder", "icon-folder", sortOrder: 13, initialize: false)]
public class FilesTreeController : FileSystemTreeController
{
protected override IFileSystem FileSystem => new PhysicalFileSystem("~/"); // fixme inject
protected override IFileSystem FileSystem => new PhysicalFileSystem("~/"); // todo inject
private static readonly string[] ExtensionsStatic = { "*" };
+1 -1
View File
@@ -1,6 +1,6 @@
namespace Umbraco.Web.Trees
{
//fixme - we don't really use this, it is nice to have the treecontroller, attribute and ApplicationTree streamlined to implement this but it's not used
//todo- we don't really use this, it is nice to have the treecontroller, attribute and ApplicationTree streamlined to implement this but it's not used
//leave as internal for now, maybe we'll use in the future, means we could pass around ITree
internal interface ITree
{
@@ -12,7 +12,7 @@ namespace Umbraco.Web.Trees
/// </summary>
internal class LegacyTreeDataConverter
{
//fixme: remove this whole class when everything is angularized
//todo: remove this whole class when everything is angularized
/// <summary>
/// This will look at the legacy IAction's JsFunctionName and convert it to a confirmation dialog view if possible
@@ -9,7 +9,7 @@ namespace Umbraco.Web.Trees
[Tree(Constants.Applications.Settings, Constants.Trees.Scripts, "Scripts", "icon-folder", "icon-folder", sortOrder: 10)]
public class ScriptsTreeController : FileSystemTreeController
{
protected override IFileSystem FileSystem => Current.FileSystems.ScriptsFileSystem; // fixme inject
protected override IFileSystem FileSystem => Current.FileSystems.ScriptsFileSystem; // todo inject
private static readonly string[] ExtensionsStatic = { "js" };
@@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees
[Tree(Constants.Applications.Settings, Constants.Trees.Stylesheets, "Stylesheets", "icon-folder", "icon-folder", sortOrder: 9)]
public class StylesheetsTreeController : FileSystemTreeController
{
protected override IFileSystem FileSystem => Current.FileSystems.StylesheetsFileSystem; // fixme inject
protected override IFileSystem FileSystem => Current.FileSystems.StylesheetsFileSystem; // todo inject
private static readonly string[] ExtensionsStatic = { "css" };
@@ -8,7 +8,6 @@ namespace Umbraco.Web.UI.Controls
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
// fixme - image is gone!
base.ImageUrl = "/images/progressBar.gif";
base.AlternateText = Title;
@@ -20,7 +20,7 @@ namespace Umbraco.Web.UI.Controls
UmbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
Umbraco = new UmbracoHelper(umbracoContext, services);
// fixme inject somehow
// todo inject somehow
Logger = Current.Logger;
ProfilingLogger = Current.ProfilingLogger;
Services = Current.Services;
@@ -31,7 +31,7 @@ namespace Umbraco.Web.UI.Controls
Umbraco = new UmbracoHelper(umbracoContext, services);
Members = Current.Factory.GetInstance<MembershipHelper>();
// fixme inject somehow
// todo inject somehow
Logger = Current.Logger;
ProfilingLogger = Current.ProfilingLogger;
Services = Current.Services;
+1 -1
View File
@@ -41,7 +41,7 @@ namespace Umbraco.Web
/// <param name="replace">A value indicating whether to replace the existing context.</param>
/// <returns>The "current" UmbracoContext.</returns>
/// <remarks>
/// fixme - this needs to be clarified
/// todo - this needs to be clarified
///
/// If <paramref name="replace"/> is true then the "current" UmbracoContext is replaced
/// with a new one even if there is one already. See <see cref="WebRuntimeComponent"/>. Has to do with
+3 -12
View File
@@ -325,23 +325,14 @@ namespace Umbraco.Web
var umbracoType = Constants.UdiEntityType.ToUmbracoObjectType(udi.EntityType);
var entityService = Current.Services.EntityService;
switch (umbracoType)
{
case UmbracoObjectTypes.Document:
return Content(guidUdi.Guid);
case UmbracoObjectTypes.Media:
// fixme - need to implement Media(guid)!
var mediaAttempt = entityService.GetId(guidUdi.Guid, umbracoType);
if (mediaAttempt.Success)
return Media(mediaAttempt.Result);
break;
return Media(guidUdi.Guid);
case UmbracoObjectTypes.Member:
// fixme - need to implement Member(guid)!
var memberAttempt = entityService.GetId(guidUdi.Guid, umbracoType);
if (memberAttempt.Success)
return Member(memberAttempt.Result);
break;
return Member(guidUdi.Guid);
}
return null;
@@ -650,7 +641,7 @@ namespace Umbraco.Web
//TODO: This is horrible but until the media cache properly supports GUIDs we have no choice here and
// currently there won't be any way to add this method correctly to `ITypedPublishedContentQuery` without breaking an interface and adding GUID support for media
var entityService = Current.Services.EntityService; // fixme inject
var entityService = Current.Services.EntityService; // todo inject
var mediaAttempt = entityService.GetId(id, UmbracoObjectTypes.Media);
return mediaAttempt.Success ? ContentQuery.Media(mediaAttempt.Result) : null;
}
+1 -1
View File
@@ -23,7 +23,7 @@ namespace Umbraco.Web
UmbracoContext = umbracoContext;
Umbraco = new UmbracoHelper(umbracoContext, services);
// fixme inject somehow
// todo inject somehow
Logger = Current.Logger;
ProfilingLogger = Current.ProfilingLogger;
Services = Current.Services;
@@ -11,6 +11,6 @@ namespace Umbraco.Web.WebApi.Filters
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public sealed class EnableOverrideAuthorizationAttribute : Attribute
{
//fixme we should remove this and use the System.Web.Http.OverrideAuthorizationAttribute which uses IOverrideFilter instead
//todo we should remove this and use the System.Web.Http.OverrideAuthorizationAttribute which uses IOverrideFilter instead
}
}
@@ -83,13 +83,13 @@ namespace Umbraco.Web.WebApi.Filters
}
else if (Udi.TryParse(argument, true, out Udi udi))
{
//fixme: inject? we can't because this is an attribute but we could provide ctors and empty ctors that pass in the required services
//todo: inject? we can't because this is an attribute but we could provide ctors and empty ctors that pass in the required services
nodeId = Current.Services.EntityService.GetId(udi).Result;
}
else
{
Guid.TryParse(argument, out Guid key);
//fixme: inject? we can't because this is an attribute but we could provide ctors and empty ctors that pass in the required services
//todo: inject? we can't because this is an attribute but we could provide ctors and empty ctors that pass in the required services
nodeId = Current.Services.EntityService.GetId(key, UmbracoObjectTypes.Document).Result;
}
}
@@ -42,7 +42,7 @@ namespace Umbraco.Web.WebApi.Filters
_paramName = paramName;
}
// fixme v8 guess this is not used anymore, source is ignored?!
// todo v8 guess this is not used anymore, source is ignored?!
public EnsureUserPermissionForMediaAttribute(string paramName, DictionarySource source)
{
if (string.IsNullOrEmpty(paramName)) throw new ArgumentNullOrEmptyException(nameof(paramName));
@@ -5,7 +5,7 @@ using System.Web.Http.Controllers;
namespace Umbraco.Web.WebApi.Filters
{
//fixme remove this since we don't need it, see notes in EnableOverrideAuthorizationAttribute
//todo remove this since we don't need it, see notes in EnableOverrideAuthorizationAttribute
/// <summary>
/// Abstract auth filter class that can be used to enable overriding class auth filters at the action level
@@ -19,7 +19,7 @@ namespace Umbraco.Web.WebApi
/// </summary>
internal static bool Enable = true;
// fixme - inject!
// todo - inject!
private readonly UmbracoContext _umbracoContext;
private readonly IRuntimeState _runtimeState;