Port 7.7 - WIP
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Update;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
@@ -9,6 +10,7 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
IExecuteBuilder Execute { get; }
|
||||
IDeleteBuilder Delete { get; }
|
||||
IUpdateBuilder Update { get; }
|
||||
IAlterSyntaxBuilder Alter { get; }
|
||||
ICreateBuilder Create { get; }
|
||||
string GetSql();
|
||||
|
||||
@@ -49,14 +49,19 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
CreateUmbracoUserData();
|
||||
}
|
||||
|
||||
if (tableName.Equals("umbracoUserType"))
|
||||
if (tableName.Equals("umbracoUserGroup"))
|
||||
{
|
||||
CreateUmbracoUserTypeData();
|
||||
CreateUmbracoUserGroupData();
|
||||
}
|
||||
|
||||
if (tableName.Equals("umbracoUser2app"))
|
||||
if (tableName.Equals("umbracoUser2UserGroup"))
|
||||
{
|
||||
CreateUmbracoUser2AppData();
|
||||
CreateUmbracoUser2UserGroupData();
|
||||
}
|
||||
|
||||
if (tableName.Equals("umbracoUserGroup2App"))
|
||||
{
|
||||
CreateUmbracoUserGroup2AppData();
|
||||
}
|
||||
|
||||
if (tableName.Equals("cmsPropertyTypeGroup"))
|
||||
@@ -172,27 +177,34 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
private void CreateUmbracoUserData()
|
||||
{
|
||||
_database.Insert("umbracoUser", "id", false, new UserDto { Id = 0, Disabled = false, NoConsole = false, Type = 1, ContentStartId = -1, MediaStartId = -1, UserName = "Administrator", Login = "admin", Password = "default", Email = "", UserLanguage = "en" });
|
||||
//_database.Update<UserDto>("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" });
|
||||
_database.Insert("umbracoUser", "id", false, new UserDto { Id = 0, Disabled = false, NoConsole = false, UserName = "Administrator", Login = "admin", Password = "default", Email = "", UserLanguage = "en", CreateDate = DateTime.Now, UpdateDate = DateTime.Now });
|
||||
}
|
||||
|
||||
private void CreateUmbracoUserTypeData()
|
||||
private void CreateUmbracoUserGroupData()
|
||||
{
|
||||
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 1, Alias = "admin", Name = "Administrators", DefaultPermissions = "CADMOSKTPIURZ:5F7" });
|
||||
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 2, Alias = "writer", Name = "Writer", DefaultPermissions = "CAH:F" });
|
||||
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 3, Alias = "editor", Name = "Editors", DefaultPermissions = "CADMOSKTPUZ:5F" });
|
||||
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 4, Alias = "translator", Name = "Translator", DefaultPermissions = "AF" });
|
||||
_database.Insert("umbracoUserGroup", "id", false, new UserGroupDto { Id = 1, StartMediaId = -1, StartContentId = -1, Alias = Constants.Security.AdminGroupAlias, Name = "Administrators", DefaultPermissions = "CADMOSKTPIURZ:5F7ï", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-medal" });
|
||||
_database.Insert("umbracoUserGroup", "id", false, new UserGroupDto { Id = 2, StartMediaId = -1, StartContentId = -1, Alias = "writer", Name = "Writers", DefaultPermissions = "CAH:F", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-edit" });
|
||||
_database.Insert("umbracoUserGroup", "id", false, new UserGroupDto { Id = 3, StartMediaId = -1, StartContentId = -1, Alias = "editor", Name = "Editors", DefaultPermissions = "CADMOSKTPUZ:5Fï", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-tools" });
|
||||
_database.Insert("umbracoUserGroup", "id", false, new UserGroupDto { Id = 4, StartMediaId = -1, StartContentId = -1, Alias = "translator", Name = "Translators", DefaultPermissions = "AF", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-globe" });
|
||||
}
|
||||
|
||||
private void CreateUmbracoUser2AppData()
|
||||
private void CreateUmbracoUser2UserGroupData()
|
||||
{
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Content });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Developer });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Media });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Members });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Settings });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Users });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Forms });
|
||||
_database.Insert(new User2UserGroupDto { UserGroupId = 1, UserId = 0 });
|
||||
}
|
||||
|
||||
private void CreateUmbracoUserGroup2AppData()
|
||||
{
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Content });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Media });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Settings });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Developer });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Users });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Members });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 2, AppAlias = Constants.Applications.Content });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Content });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Media });
|
||||
_database.Insert(new UserGroup2AppDto { UserGroupId = 4, AppAlias = Constants.Applications.Translation });
|
||||
_database.Insert("umbracoUser2app", "user", false, new User2AppDto { UserId = 0, AppAlias = Constants.Applications.Translation });
|
||||
}
|
||||
|
||||
|
||||
@@ -71,15 +71,15 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{29, typeof (TagRelationshipDto)},
|
||||
|
||||
//removed: {30...
|
||||
{31, typeof (UserTypeDto)},
|
||||
//removed in 7.6: {31, typeof (UserTypeDto)},
|
||||
{32, typeof (UserDto)},
|
||||
{33, typeof (TaskTypeDto)},
|
||||
{34, typeof (TaskDto)},
|
||||
{35, typeof (ContentType2ContentTypeDto)},
|
||||
{36, typeof (ContentTypeAllowedContentTypeDto)},
|
||||
{37, typeof (User2AppDto)},
|
||||
//removed in 7.6: {37, typeof (User2AppDto)},
|
||||
{38, typeof (User2NodeNotifyDto)},
|
||||
{39, typeof (User2NodePermissionDto)},
|
||||
//removed in 7.6: {39, typeof (User2NodePermissionDto)},
|
||||
|
||||
{40, typeof (ServerRegistrationDto)},
|
||||
{41, typeof (AccessDto)},
|
||||
@@ -92,7 +92,12 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{48, typeof (RedirectUrlDto) },
|
||||
{49, typeof (LockDto) },
|
||||
|
||||
{50, typeof (ContentNuDto) }
|
||||
{50, typeof (UserGroupDto) },
|
||||
{51, typeof (User2UserGroupDto) },
|
||||
{52, typeof (UserGroup2NodePermissionDto) },
|
||||
{53, typeof (UserGroup2AppDto) },
|
||||
{54, typeof (UserStartNodeDto) },
|
||||
{55, typeof (ContentNuDto) }
|
||||
};
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -150,6 +150,12 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
return new Version(7, 5, 0);
|
||||
}
|
||||
|
||||
//if the error is for umbracoUserGroup it must be the previous version to 7.7 since that is when it is added
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.InvariantEquals("umbracoUserStartNode"))))
|
||||
{
|
||||
return new Version(7, 6, 0);
|
||||
}
|
||||
|
||||
return UmbracoVersion.Current;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Core.Persistence.Migrations.Syntax.Alter;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Update;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
@@ -18,6 +19,8 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
|
||||
public IDeleteBuilder Delete => new DeleteBuilder(this);
|
||||
|
||||
public IUpdateBuilder Update => new UpdateBuilder(this);
|
||||
|
||||
public IAlterSyntaxBuilder Alter => new AlterSyntaxBuilder(this);
|
||||
|
||||
public ICreateBuilder Create => new CreateBuilder(this);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero
|
||||
{
|
||||
[MigrationAttribute("4.9.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class RemoveUmbracoAppConstraints : MigrationBase
|
||||
{
|
||||
public RemoveUmbracoAppConstraints(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//This will work on mysql and should work on mssql however the old keys were not named consistently with how the keys are
|
||||
// structured now. So we need to do a check and manually remove them based on their old aliases.
|
||||
|
||||
if (DatabaseType.IsMySql())
|
||||
{
|
||||
Delete.ForeignKey().FromTable("umbracoUser2app").ForeignColumn("app").ToTable("umbracoApp").PrimaryColumn("appAlias");
|
||||
Delete.ForeignKey().FromTable("umbracoAppTree").ForeignColumn("appAlias").ToTable("umbracoApp").PrimaryColumn("appAlias");
|
||||
}
|
||||
else
|
||||
{
|
||||
//These are the old aliases, before removing them, check they exist
|
||||
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
|
||||
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoApp")))
|
||||
{
|
||||
Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app");
|
||||
//name this migration, this is a hack for DeleteAppTables to ensure it's not executed twice
|
||||
((MigrationExpressionBase)Context.Expressions.Last()).Name = "FK_umbracoUser2app_umbracoApp";
|
||||
}
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoUser")))
|
||||
{
|
||||
Delete.ForeignKey("FK_umbracoUser2app_umbracoUser").OnTable("umbracoUser2app");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Create.ForeignKey("FK_umbracoUser2app_umbracoApp").FromTable("umbracoUser2app").ForeignColumn("app")
|
||||
.ToTable("umbracoApp").PrimaryColumn("appAlias").OnDeleteOrUpdate(Rule.None);
|
||||
|
||||
Create.ForeignKey("FK_umbracoAppTree_umbracoApp").FromTable("umbracoAppTree").ForeignColumn("appAlias")
|
||||
.ToTable("umbracoApp").PrimaryColumn("appAlias").OnDeleteOrUpdate(Rule.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourOneZero
|
||||
{
|
||||
[Migration("4.1.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class AddPreviewXmlTable : MigrationBase
|
||||
{
|
||||
public AddPreviewXmlTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var tableName = "cmsPreviewXml";
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
if (tables.InvariantContains(tableName)) return;
|
||||
|
||||
Create.Table(tableName)
|
||||
.WithColumn("nodeId").AsInt32().NotNullable()
|
||||
.WithColumn("versionId").AsGuid().NotNullable()
|
||||
.WithColumn("timestamp").AsDateTime().NotNullable()
|
||||
.WithColumn("xml").AsString();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero
|
||||
@@ -14,7 +15,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDto>("WHERE alias=@alias", new {alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias});
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDtoCapture>("WHERE alias=@alias", new {alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias});
|
||||
if (exists == null)
|
||||
{
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
@@ -26,13 +27,42 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
|
||||
// need to capture the DTO as it is modified in later migrations
|
||||
|
||||
[TableName("umbracoRelationType")]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
internal class RelationTypeDtoCapture
|
||||
{
|
||||
public const int NodeIdSeed = 3;
|
||||
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(IdentitySeed = NodeIdSeed)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("dual")]
|
||||
public bool Dual { get; set; }
|
||||
|
||||
[Column("parentObjectType")]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
|
||||
[Column("childObjectType")]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
[Length(100)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_alias")]
|
||||
public string Alias { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
@@ -14,12 +13,9 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
var indexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
@@ -28,24 +24,19 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
|
||||
//must be non-nullable
|
||||
// drop the index if it exists
|
||||
if (indexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")))
|
||||
Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode");
|
||||
|
||||
// set uniqueID to be non-nullable
|
||||
// the index *must* be dropped else 'one or more objects access this column' exception
|
||||
Alter.Table("umbracoNode").AlterColumn("uniqueID").AsGuid().NotNullable();
|
||||
|
||||
//make sure it already exists
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")))
|
||||
{
|
||||
Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode");
|
||||
}
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNode_uniqueID")) == false)
|
||||
{
|
||||
//must be a uniqe index
|
||||
Create.Index("IX_umbracoNode_uniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Unique();
|
||||
}
|
||||
// create the index
|
||||
Create.Index("IX_umbracoNode_uniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Unique();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
|
||||
[Migration("6.0.0", 10, Constants.System.UmbracoMigrationName)]
|
||||
public class DeleteAppTables : MigrationBase
|
||||
{
|
||||
public DeleteAppTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Delete.Table("umbracoAppTree");
|
||||
|
||||
//NOTE: this is a hack since old umbraco versions might not have had their db's upgraded correctly so they are all quite inconsistent.
|
||||
// This is actually done in migration: RemoveUmbracoAppConstraints to target 4.9.0 but we've found with some db's that are currently at 4.9.1,
|
||||
// these upgrades did not run. So, now we not only have to check if these constraints exist, but we also have to check if the RemoveUmbracoAppConstraints
|
||||
// has executed since we cannot drop the same foreign key twice or we'll get errors.
|
||||
|
||||
//Here we'll do a dirty check to see if RemoveUmbracoAppConstraints has executed
|
||||
if (Context.Expressions.Any(x =>
|
||||
{
|
||||
var b = x as MigrationExpressionBase;
|
||||
if (b == null) return false;
|
||||
return b.Name == "FK_umbracoUser2app_umbracoApp";
|
||||
}) == false)
|
||||
{
|
||||
//These are the old aliases, before removing them, check they exist
|
||||
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoApp")))
|
||||
{
|
||||
Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app");
|
||||
}
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoUser")))
|
||||
{
|
||||
Delete.ForeignKey("FK_umbracoUser2app_umbracoUser").OnTable("umbracoUser2app");
|
||||
}
|
||||
}
|
||||
|
||||
Delete.Table("umbracoApp");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
//This cannot be rolled back!!
|
||||
throw new DataLossException("Cannot rollback migration " + typeof(DeleteAppTables) + " the db tables umbracoAppTree and umbracoApp have been droppped");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 9, Constants.System.UmbracoMigrationName)]
|
||||
public class EnsureAppsTreesUpdated : MigrationBase
|
||||
{
|
||||
public EnsureAppsTreesUpdated(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var e = new UpgradingEventArgs();
|
||||
|
||||
if (Upgrading != null)
|
||||
Upgrading(this, e);
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
|
||||
public static event EventHandler<UpgradingEventArgs> Upgrading;
|
||||
|
||||
public class UpgradingEventArgs : EventArgs { }
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 5, Constants.System.UmbracoMigrationName)]
|
||||
public class MoveMasterContentTypeData : MigrationBase
|
||||
{
|
||||
public MoveMasterContentTypeData(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//Reading entries from the cmsContentType table in order to update the parentID on the umbracoNode table.
|
||||
//NOTE This is primarily done because of a shortcoming in sql ce, which has really bad support for updates (can't use FROM or subqueries with multiple results).
|
||||
if (base.Context != null && base.Context.Database != null)
|
||||
{
|
||||
var list = base.Context.Database.Fetch<dynamic>("SELECT nodeId, masterContentType FROM cmsContentType WHERE not masterContentType is null AND masterContentType != 0");
|
||||
foreach (var item in list)
|
||||
{
|
||||
Update.Table("umbracoNode").Set(new { parentID = item.masterContentType }).Where(new { id = item.nodeId });
|
||||
}
|
||||
}
|
||||
|
||||
Execute.Sql(
|
||||
"INSERT INTO cmsContentType2ContentType (parentContentTypeId, childContentTypeId) SELECT masterContentType, nodeId FROM cmsContentType WHERE not masterContentType is null and masterContentType != 0");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 4, Constants.System.UmbracoMigrationName)]
|
||||
public class NewCmsContentType2ContentTypeTable : MigrationBase
|
||||
{
|
||||
public NewCmsContentType2ContentTypeTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Create.Table("cmsContentType2ContentType")
|
||||
.WithColumn("parentContentTypeId").AsInt16().NotNullable()
|
||||
.WithColumn("childContentTypeId").AsInt16().NotNullable();
|
||||
|
||||
Create.PrimaryKey("PK_cmsContentType2ContentType")
|
||||
.OnTable("cmsContentType2ContentType")
|
||||
.Columns(new[] { "parentContentTypeId", "childContentTypeId" });
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.PrimaryKey("PK_cmsContentType2ContentType").FromTable("cmsContentType2ContentType");
|
||||
|
||||
Delete.Table("cmsContentType2ContentType");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using NPoco;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 6, Constants.System.UmbracoMigrationName)]
|
||||
public class RemoveMasterContentTypeColumn : MigrationBase
|
||||
{
|
||||
public RemoveMasterContentTypeColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//NOTE Don't think we can remove this column yet as it seems to be used by some starterkits
|
||||
IfDatabase(DatabaseType.SQLCe, DatabaseType.SqlServer2008)
|
||||
.Delete.DefaultConstraint().OnTable("cmsContentType").OnColumn("masterContentType");
|
||||
|
||||
Delete.Column("masterContentType").FromTable("cmsContentType");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Create.UniqueConstraint("DF_cmsContentType_masterContentType").OnTable("cmsContentType").Column("masterContentType");
|
||||
|
||||
Create.Column("masterContentType").OnTable("cmsContentType").AsInt16().Nullable().WithDefaultValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class RenameCmsTabTable : MigrationBase
|
||||
{
|
||||
public RenameCmsTabTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Rename.Table("cmsTab").To("cmsPropertyTypeGroup");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Rename.Table("cmsPropertyTypeGroup").To("cmsTab");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
using System.Data;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 7, Constants.System.UmbracoMigrationName)]
|
||||
public class RenameTabIdColumn : MigrationBase
|
||||
{
|
||||
public RenameTabIdColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//Conditional Create-column for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Create.Column("propertyTypeGroupId").OnTable("cmsPropertyType").AsInt16().Nullable();
|
||||
|
||||
//Conditional Create-foreign for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Create.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup")
|
||||
.FromTable("cmsPropertyType").ForeignColumn("propertyTypeGroupId")
|
||||
.ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None);
|
||||
|
||||
//Conditional Delete-foreignkey for MySql databases
|
||||
IfDatabase(DatabaseType.MySQL)
|
||||
.Delete.ForeignKey().FromTable("cmsPropertyType").ForeignColumn("tabId").ToTable("cmsPropertyTypeGroup").PrimaryColumn("id");
|
||||
|
||||
Rename.Column("tabId").OnTable("cmsPropertyType").To("propertyTypeGroupId");
|
||||
|
||||
//Conditional Create-foreign for MySql databases
|
||||
IfDatabase(DatabaseType.MySQL)
|
||||
.Create.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup")
|
||||
.FromTable("cmsPropertyType").ForeignColumn("propertyTypeGroupId")
|
||||
.ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None);
|
||||
|
||||
//Conditional Delete-foreignkey for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Delete.ForeignKey("FK_cmsPropertyType_cmsTab").OnTable("cmsPropertyType");
|
||||
|
||||
//Conditional Delete-column for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Delete.Column("tabId").FromTable("cmsPropertyType");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
//Conditional Create-column for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Create.Column("tabId").OnTable("cmsPropertyType").AsInt16().Nullable();
|
||||
|
||||
//Conditional Create-foreign for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Create.ForeignKey("FK_cmsPropertyType_cmsTab")
|
||||
.FromTable("cmsPropertyType").ForeignColumn("tabId")
|
||||
.ToTable("cmsTab").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None);
|
||||
|
||||
//Conditional Delete-foreignkey for MySql databases
|
||||
IfDatabase(DatabaseType.MySQL)
|
||||
.Delete.ForeignKey().FromTable("cmsPropertyType").ForeignColumn("propertyTypeGroupId").ToTable("cmsPropertyTypeGroup").PrimaryColumn("id");
|
||||
|
||||
Rename.Column("propertyTypeGroupId").OnTable("cmsPropertyType").To("tabId");
|
||||
|
||||
//Conditional Create-foreign for MySql databases
|
||||
IfDatabase(DatabaseType.MySQL)
|
||||
.Create.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup")
|
||||
.FromTable("cmsPropertyType").ForeignColumn("tabId")
|
||||
.ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None);
|
||||
|
||||
//Conditional Delete-foreignkey for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Delete.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup").OnTable("cmsPropertyType");
|
||||
|
||||
//Conditional Delete-column for Sql Ce databases
|
||||
IfDatabase(DatabaseType.SQLCe)
|
||||
.Delete.Column("propertyTypeGroupId").FromTable("propertyTypeGroupId");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 3, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdateCmsContentTypeAllowedContentTypeTable : MigrationBase
|
||||
{
|
||||
public UpdateCmsContentTypeAllowedContentTypeTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Alter.Table("cmsContentTypeAllowedContentType").AddColumn("sortOrder").AsInt16().NotNullable().WithDefaultValue(1);
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Column("sortOrder").FromTable("cmsContentTypeAllowedContentType");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 2, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdateCmsContentTypeTable : MigrationBase
|
||||
{
|
||||
public UpdateCmsContentTypeTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Alter.Table("cmsContentType").AddColumn("isContainer").AsBoolean().NotNullable().WithDefaultValue(0);
|
||||
|
||||
Alter.Table("cmsContentType").AddColumn("allowAtRoot").AsBoolean().NotNullable().WithDefaultValue(0);
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Column("allowAtRoot").FromTable("cmsContentType");
|
||||
|
||||
Delete.Column("isContainer").FromTable("cmsContentType");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 8, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdateCmsContentVersionTable : MigrationBase
|
||||
{
|
||||
public UpdateCmsContentVersionTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Alter.Table("cmsContentVersion").AddColumn("LanguageLocale").AsString(10).Nullable();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Column("LanguageLocale").FromTable("cmsContentVersion");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System.Data;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
|
||||
{
|
||||
[Migration("6.0.0", 1, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdateCmsPropertyTypeGroupTable : MigrationBase
|
||||
{
|
||||
public UpdateCmsPropertyTypeGroupTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Alter.Table("cmsPropertyTypeGroup").AddColumn("parentGroupId").AsInt16().Nullable();
|
||||
|
||||
Create.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id")
|
||||
.FromTable("cmsPropertyTypeGroup").ForeignColumn("parentGroupId")
|
||||
.ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None);
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.ForeignKey().FromTable("cmsPropertyTypeGroup").ForeignColumn("parentGroupId").ToTable("cmsPropertyTypeGroup").PrimaryColumn("id");
|
||||
|
||||
Delete.Column("parentGroupId").FromTable("cmsPropertyTypeGroup");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixOneZero
|
||||
{
|
||||
|
||||
[Migration("6.1.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class CreateServerRegistryTable : MigrationBase
|
||||
{
|
||||
public CreateServerRegistryTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var schemaHelper = new DatabaseSchemaHelper(Context.Database, Logger);
|
||||
|
||||
//NOTE: This isn't the correct way to do this but to manually create this table with the Create syntax is a pain in the arse
|
||||
schemaHelper.CreateTable<ServerRegistrationDto>();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Table("umbracoServer");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
[Migration("7.1.0", 3, Constants.System.UmbracoMigrationName)]
|
||||
[Migration("6.2.0", 3, Constants.System.UmbracoMigrationName)]
|
||||
public class AddChangeDocumentTypePermission : MigrationBase
|
||||
{
|
||||
public AddChangeDocumentTypePermission(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Code(AddChangeDocumentTypePermissionDo);
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Execute.Code(UndoChangeDocumentTypePermissionDo);
|
||||
}
|
||||
|
||||
private static string AddChangeDocumentTypePermissionDo(IDatabase database)
|
||||
{
|
||||
var adminUserType = database.Fetch<UserTypeDto>("WHERE Id = 1").FirstOrDefault();
|
||||
|
||||
if (adminUserType != null)
|
||||
{
|
||||
if (adminUserType.DefaultPermissions.Contains("7") == false)
|
||||
{
|
||||
adminUserType.DefaultPermissions = adminUserType.DefaultPermissions + "7";
|
||||
database.Save<UserTypeDto>(adminUserType);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string UndoChangeDocumentTypePermissionDo(IDatabase database)
|
||||
{
|
||||
var adminUserType = database.Fetch<UserTypeDto>("WHERE Id = 1").FirstOrDefault();
|
||||
|
||||
if (adminUserType != null)
|
||||
{
|
||||
if (adminUserType.DefaultPermissions.Contains("7"))
|
||||
{
|
||||
adminUserType.DefaultPermissions = adminUserType.DefaultPermissions.Replace("7", "");
|
||||
database.Save<UserTypeDto>(adminUserType);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Migrations.Initial;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
[Migration("7.1.0", 1, Constants.System.UmbracoMigrationName)]
|
||||
[Migration("6.2.0", 1, Constants.System.UmbracoMigrationName)]
|
||||
public class AdditionalIndexesAndKeys : MigrationBase
|
||||
{
|
||||
public AdditionalIndexesAndKeys(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
|
||||
//do not create any indexes if they already exist in the database
|
||||
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeTrashed")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered();
|
||||
}
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsContentVersion_ContentId")) == false)
|
||||
{
|
||||
Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered();
|
||||
}
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDocument_published")) == false)
|
||||
{
|
||||
Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered();
|
||||
}
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDocument_newest")) == false)
|
||||
{
|
||||
Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered();
|
||||
}
|
||||
|
||||
// drop the umbracoUserLogins_Index index since it is named incorrectly
|
||||
// and then re-create it so it follows the standard naming convention
|
||||
var sqlServerSyntax = SqlSyntax as SqlServerSyntaxProvider;
|
||||
if (sqlServerSyntax != null // if running sql server
|
||||
&& sqlServerSyntax.ServerVersion.IsAzure // on Azure
|
||||
&& sqlServerSyntax.ServerVersion.ProductVersion.StartsWith("11.")) // version 11.x
|
||||
{
|
||||
// SQL Azure v2 does not support dropping clustered indexes on a table
|
||||
// see http://issues.umbraco.org/issue/U4-5673
|
||||
// and so we have to use a special method to do some manual work
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("umbracoUserLogins_Index")))
|
||||
{
|
||||
//It's the old version that doesn't support dropping a clustered index on a table, so we need to do some manual work.
|
||||
ExecuteSqlAzureSqlForChangingIndex();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other db can delete and recreate
|
||||
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("umbracoUserLogins_Index")))
|
||||
{
|
||||
Delete.Index("umbracoUserLogins_Index").OnTable("umbracoUserLogins");
|
||||
}
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoUserLogins_Index")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoUserLogins_Index").OnTable("umbracoUserLogins").OnColumn("contextID").Ascending().WithOptions().Clustered();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode");
|
||||
Delete.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion");
|
||||
Delete.Index("IX_cmsDocument_published").OnTable("cmsDocument");
|
||||
Delete.Index("IX_cmsDocument_newest").OnTable("cmsDocument");
|
||||
}
|
||||
|
||||
private void ExecuteSqlAzureSqlForChangingIndex()
|
||||
{
|
||||
Context.Database.Execute(@"CREATE TABLE ""umbracoUserLogins_temp""
|
||||
(
|
||||
contextID uniqueidentifier NOT NULL,
|
||||
userID int NOT NULL,
|
||||
[timeout] bigint NOT NULL
|
||||
);
|
||||
CREATE CLUSTERED INDEX ""IX_umbracoUserLogins_Index"" ON ""umbracoUserLogins_temp"" (""contextID"");
|
||||
INSERT INTO ""umbracoUserLogins_temp"" SELECT * FROM ""umbracoUserLogins""
|
||||
DROP TABLE ""umbracoUserLogins""
|
||||
CREATE TABLE ""umbracoUserLogins""
|
||||
(
|
||||
contextID uniqueidentifier NOT NULL,
|
||||
userID int NOT NULL,
|
||||
[timeout] bigint NOT NULL
|
||||
);
|
||||
CREATE CLUSTERED INDEX ""IX_umbracoUserLogins_Index"" ON ""umbracoUserLogins"" (""contextID"");
|
||||
INSERT INTO ""umbracoUserLogins"" SELECT * FROM ""umbracoUserLogins_temp""
|
||||
DROP TABLE ""umbracoUserLogins_temp""");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Web.UI;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
|
||||
//see: http://issues.umbraco.org/issue/U4-4430
|
||||
[Migration("7.1.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
[Migration("6.2.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class AssignMissingPrimaryForMySqlKeys : MigrationBase
|
||||
{
|
||||
public AssignMissingPrimaryForMySqlKeys(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
if (DatabaseType.IsMySql())
|
||||
{
|
||||
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
|
||||
|
||||
//This should be 2 because this table has 2 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentTypeAllowedContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_cmsContentTypeAllowedContentType")
|
||||
.OnTable("cmsContentTypeAllowedContentType")
|
||||
.Columns(new[] { "Id", "AllowedId" });
|
||||
}
|
||||
|
||||
//This should be 2 because this table has 2 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("cmsDocumentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_cmsDocumentType")
|
||||
.OnTable("cmsDocumentType")
|
||||
.Columns(new[] { "contentTypeNodeId", "templateNodeId" });
|
||||
}
|
||||
|
||||
//This should be 2 because this table has 2 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("cmsMember2MemberGroup") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_cmsMember2MemberGroup")
|
||||
.OnTable("cmsMember2MemberGroup")
|
||||
.Columns(new[] { "Member", "MemberGroup" });
|
||||
}
|
||||
|
||||
//This should be 2 because this table has 2 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_cmsContentPreviewXml")
|
||||
.OnTable("cmsPreviewXml")
|
||||
.Columns(new[] { "nodeId", "versionId" });
|
||||
}
|
||||
|
||||
//This should be 2 because this table has 2 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_user2app")
|
||||
.OnTable("umbracoUser2app")
|
||||
.Columns(new[] { "user", "app" });
|
||||
}
|
||||
|
||||
//This should be 2 because this table has 3 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("umbracoUser2NodeNotify") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_umbracoUser2NodeNotify")
|
||||
.OnTable("umbracoUser2NodeNotify")
|
||||
.Columns(new[] { "userId", "nodeId", "action" });
|
||||
}
|
||||
|
||||
//This should be 2 because this table has 3 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("umbracoUser2NodePermission") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_umbracoUser2NodePermission")
|
||||
.OnTable("umbracoUser2NodePermission")
|
||||
.Columns(new[] { "userId", "nodeId", "permission" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
//don't do anything, these keys should have always existed!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
//We have to target this specifically to ensure this DOES NOT execute if upgrading from a version previous to 6.0,
|
||||
// this is because when the 6.0.0 migrations are executed, this primary key get's created so if this migration is also executed
|
||||
// we will get exceptions because it is trying to create the PK two times.
|
||||
[Migration("6.0.0", "6.2.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class AssignMissingPrimaryForMySqlKeys2 : MigrationBase
|
||||
{
|
||||
public AssignMissingPrimaryForMySqlKeys2(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
if (DatabaseType.IsMySql())
|
||||
{
|
||||
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
|
||||
|
||||
//This should be 2 because this table has 2 keys
|
||||
if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentType2ContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
|
||||
{
|
||||
Create.PrimaryKey("PK_cmsContentType2ContentType")
|
||||
.OnTable("cmsContentType2ContentType")
|
||||
.Columns(new[] { "parentContentTypeId", "childContentTypeId" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
//don't do anything, these keys should have always existed!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
[Migration("7.1.0", 2, Constants.System.UmbracoMigrationName)]
|
||||
[Migration("6.2.0", 2, Constants.System.UmbracoMigrationName)]
|
||||
public class ChangePasswordColumn : MigrationBase
|
||||
{
|
||||
public ChangePasswordColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//up to 500 chars
|
||||
Alter.Table("umbracoUser").AlterColumn("userPassword").AsString(500).NotNullable();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
//back to 125 chars
|
||||
Alter.Table("umbracoUser").AlterColumn("userPassword").AsString(125).NotNullable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
[Migration("7.1.0", 4, Constants.System.UmbracoMigrationName)]
|
||||
[Migration("6.2.0", 4, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdateToNewMemberPropertyAliases : MigrationBase
|
||||
{
|
||||
public UpdateToNewMemberPropertyAliases(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Code(Update);
|
||||
}
|
||||
|
||||
internal string Update(IDatabase database)
|
||||
{
|
||||
if (database != null)
|
||||
{
|
||||
var aliasMap = new Dictionary<string, string>
|
||||
{
|
||||
{"umbracoPasswordRetrievalQuestionPropertyTypeAlias", Constants.Conventions.Member.PasswordQuestion},
|
||||
{"umbracoPasswordRetrievalAnswerPropertyTypeAlias", Constants.Conventions.Member.PasswordAnswer},
|
||||
{"umbracoCommentPropertyTypeAlias", Constants.Conventions.Member.Comments},
|
||||
{"umbracoApprovePropertyTypeAlias", Constants.Conventions.Member.IsApproved},
|
||||
{"umbracoLockPropertyTypeAlias", Constants.Conventions.Member.IsLockedOut},
|
||||
{"umbracoLastLoginPropertyTypeAlias", Constants.Conventions.Member.LastLoginDate},
|
||||
{"umbracoMemberLastPasswordChange", Constants.Conventions.Member.LastPasswordChangeDate},
|
||||
{"umbracoMemberLastLockout", Constants.Conventions.Member.LastLockoutDate},
|
||||
{"umbracoFailedPasswordAttemptsPropertyTypeAlias", Constants.Conventions.Member.FailedPasswordAttempts}
|
||||
};
|
||||
|
||||
|
||||
//This query is structured to work with MySql, SQLCE and SqlServer:
|
||||
// http://issues.umbraco.org/issue/U4-3876
|
||||
|
||||
const string propertyTypeUpdateSql = @"UPDATE cmsPropertyType
|
||||
SET Alias = @newAlias
|
||||
WHERE Alias = @oldAlias AND contentTypeId IN (
|
||||
SELECT nodeId FROM (SELECT DISTINCT cmsContentType.nodeId FROM cmsPropertyType
|
||||
INNER JOIN cmsContentType ON cmsPropertyType.contentTypeId = cmsContentType.nodeId
|
||||
INNER JOIN umbracoNode ON cmsContentType.nodeId = umbracoNode.id
|
||||
WHERE umbracoNode.nodeObjectType = @objectType) x)";
|
||||
|
||||
const string xmlSelectSql = @"SELECT cmsContentXml.* FROM cmsContentXml
|
||||
INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
|
||||
WHERE umbracoNode.nodeObjectType = @objectType";
|
||||
|
||||
using (var trans = database.GetTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//Upate all of the property type aliases
|
||||
foreach (var map in aliasMap)
|
||||
{
|
||||
database.Execute(propertyTypeUpdateSql, new { newAlias = map.Value, oldAlias = map.Key, objectType = Constants.ObjectTypes.MemberType });
|
||||
}
|
||||
|
||||
//Update all of the XML
|
||||
var items = database.Fetch<ContentXmlDto>(xmlSelectSql, new { objectType = Constants.ObjectTypes.Member });
|
||||
foreach (var item in items)
|
||||
{
|
||||
foreach (var map in aliasMap)
|
||||
{
|
||||
item.Xml = item.Xml.Replace("<" + map.Key + ">", "<" + map.Value + ">");
|
||||
item.Xml = item.Xml.Replace("</" + map.Key + ">", "</" + map.Value + ">");
|
||||
}
|
||||
database.Update(item);
|
||||
}
|
||||
|
||||
trans.Complete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error<UpdateToNewMemberPropertyAliases>("Exception was thrown when trying to upgrade old member aliases to the new ones", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
|
||||
{
|
||||
[Migration("6.0.2", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdatePropertyTypesAndGroups : MigrationBase
|
||||
{
|
||||
public UpdatePropertyTypesAndGroups(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Code(UpdatePropertyTypesAndGroupsDo);
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static string UpdatePropertyTypesAndGroupsDo(IDatabase database)
|
||||
{
|
||||
if (database != null)
|
||||
{
|
||||
//Fetch all PropertyTypes that belongs to a PropertyTypeGroup
|
||||
//NOTE: We are writing the full query because we've added a column to the PropertyTypeDto in later versions so one of the columns
|
||||
// won't exist yet
|
||||
var propertyTypes = database.Fetch<dynamic>("SELECT * FROM cmsPropertyType WHERE propertyTypeGroupId > 0");
|
||||
|
||||
// need to use dynamic, as PropertyTypeGroupDto has new properties
|
||||
var propertyGroups = database.Fetch<dynamic>("SELECT * FROM cmsPropertyTypeGroup WHERE id > 0");
|
||||
|
||||
foreach (var propertyType in propertyTypes)
|
||||
{
|
||||
// get the PropertyTypeGroup of the current PropertyType, skip if not found
|
||||
var propertyTypeGroup = propertyGroups.FirstOrDefault(x => x.id == propertyType.propertyTypeGroupId);
|
||||
if (propertyTypeGroup == null) continue;
|
||||
|
||||
// if the PropretyTypeGroup belongs to the same content type as the PropertyType, then fine
|
||||
if (propertyTypeGroup.contenttypeNodeId == propertyType.contentTypeId) continue;
|
||||
|
||||
// else we want to assign the PropertyType to a proper PropertyTypeGroup
|
||||
// ie one that does belong to the same content - look for it
|
||||
var okPropertyTypeGroup = propertyGroups.FirstOrDefault(x =>
|
||||
x.text == propertyTypeGroup.text && // same name
|
||||
x.contenttypeNodeId == propertyType.contentTypeId); // but for proper content type
|
||||
|
||||
if (okPropertyTypeGroup == null)
|
||||
{
|
||||
// does not exist, create a new PropertyTypeGroup
|
||||
// cannot use a PropertyTypeGroupDto because of the new (not-yet-existing) uniqueID property
|
||||
// cannot use a dynamic because database.Insert fails to set the value of property
|
||||
var propertyGroup = new PropertyTypeGroupDtoTemp
|
||||
{
|
||||
id = 0,
|
||||
contenttypeNodeId = propertyType.contentTypeId,
|
||||
text = propertyTypeGroup.text,
|
||||
sortorder = propertyTypeGroup.sortorder
|
||||
};
|
||||
|
||||
// save + add to list of groups
|
||||
int id = Convert.ToInt16(database.Insert("cmsPropertyTypeGroup", "id", propertyGroup));
|
||||
propertyGroup.id = id;
|
||||
propertyGroups.Add(propertyGroup);
|
||||
|
||||
// update the PropertyType to use the new PropertyTypeGroup
|
||||
propertyType.propertyTypeGroupId = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// exists, update PropertyType to use the PropertyTypeGroup
|
||||
propertyType.propertyTypeGroupId = okPropertyTypeGroup.id;
|
||||
}
|
||||
database.Update("cmsPropertyType", "id", propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private class PropertyTypeGroupDtoTemp
|
||||
{
|
||||
public int id { get; set; }
|
||||
public int contenttypeNodeId { get; set; }
|
||||
public string text { get; set; }
|
||||
public int sortorder { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.Temp8
|
||||
{
|
||||
[Migration("7.7.0", 5, Constants.System.UmbracoMigrationName)]
|
||||
public class AddIndexToDictionaryKeyColumn : MigrationBase
|
||||
{
|
||||
public AddIndexToDictionaryKeyColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Code(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")));
|
||||
|
||||
if (colLen < 900 == false && colLen != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_key")) == false)
|
||||
{
|
||||
var local = Context.GetLocalMigration();
|
||||
|
||||
//we can apply the index
|
||||
local.Create.Index("IX_cmsDictionary_key").OnTable("cmsDictionary")
|
||||
.OnColumn("key")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered();
|
||||
|
||||
return local.GetSql();
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Index("IX_cmsDictionary_key").OnTable("cmsDictionary");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.Temp8
|
||||
{
|
||||
[Migration("8.0.0", 1, Constants.System.UmbracoMigrationName)]
|
||||
public class AddUserGroupTables : MigrationBase
|
||||
{
|
||||
public AddUserGroupTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
|
||||
|
||||
if (AddNewTables(tables))
|
||||
{
|
||||
MigrateUserPermissions();
|
||||
MigrateUserTypesToGroups();
|
||||
DeleteOldTables(tables, constraints);
|
||||
SetDefaultIcons();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDefaultIcons()
|
||||
{
|
||||
Execute.Sql($"UPDATE umbracoUserGroup SET icon = \'\' WHERE userGroupAlias = \'{Constants.Security.AdminGroupAlias}\'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET icon = \'icon-edit\' WHERE userGroupAlias = \'writer\'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET icon = \'icon-tools\' WHERE userGroupAlias = \'editor\'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET icon = \'icon-globe\' WHERE userGroupAlias = \'translator\'");
|
||||
}
|
||||
|
||||
private bool AddNewTables(string[] tables)
|
||||
{
|
||||
var updated = false;
|
||||
if (tables.InvariantContains("umbracoUserGroup") == false)
|
||||
{
|
||||
Create.Table<UserGroupDto>();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUser2UserGroup") == false)
|
||||
{
|
||||
Create.Table<User2UserGroupDto>();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUserGroup2App") == false)
|
||||
{
|
||||
Create.Table<UserGroup2AppDto>();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUserGroup2NodePermission") == false)
|
||||
{
|
||||
Create.Table<UserGroup2NodePermissionDto>();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
private void MigrateUserTypesToGroups()
|
||||
{
|
||||
// Create a user group for each user type
|
||||
Execute.Sql(@"INSERT INTO umbracoUserGroup (userGroupAlias, userGroupName, userGroupDefaultPermissions)
|
||||
SELECT userTypeAlias, userTypeName, userTypeDefaultPermissions
|
||||
FROM umbracoUserType");
|
||||
|
||||
// Add each user to the group created from their type
|
||||
Execute.Sql(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
|
||||
SELECT u.id, ug.id
|
||||
FROM umbracoUser u
|
||||
INNER JOIN umbracoUserType ut ON ut.id = u.userType
|
||||
INNER JOIN umbracoUserGroup ug ON ug.userGroupAlias = ut.userTypeAlias");
|
||||
|
||||
// Add the built-in administrator account to all apps
|
||||
Execute.Sql(@"INSERT INTO umbracoUserGroup2app (userGroupId,app)
|
||||
SELECT ug.id, app
|
||||
FROM umbracoUserGroup ug
|
||||
INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
|
||||
INNER JOIN umbracoUser u ON u.id = u2ug.userId
|
||||
INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
|
||||
WHERE u.id = 0");
|
||||
|
||||
// Rename some groups for consistency (plural form)
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET userGroupName = 'Writers' WHERE userGroupAlias = 'writer'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET userGroupName = 'Translators' WHERE userGroupAlias = 'translator'");
|
||||
|
||||
//Ensure all built in groups have a start node of -1
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'editor'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'editor'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'writer'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'writer'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'translator'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'translator'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'admin'");
|
||||
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'admin'");
|
||||
}
|
||||
|
||||
private void MigrateUserPermissions()
|
||||
{
|
||||
// Create user group records for all non-admin users that have specific permissions set
|
||||
Execute.Sql(@"INSERT INTO umbracoUserGroup(userGroupAlias, userGroupName)
|
||||
SELECT userName + 'Group', 'Group for ' + userName
|
||||
FROM umbracoUser
|
||||
WHERE (id IN (
|
||||
SELECT " + SqlSyntax.GetQuotedColumnName("user") + @"
|
||||
FROM umbracoUser2app
|
||||
) OR id IN (
|
||||
SELECT userid
|
||||
FROM umbracoUser2NodePermission
|
||||
))
|
||||
AND id > 0");
|
||||
|
||||
// Associate those groups with the users
|
||||
Execute.Sql(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
|
||||
SELECT u.id, ug.id
|
||||
FROM umbracoUser u
|
||||
INNER JOIN umbracoUserGroup ug ON ug.userGroupAlias = userName + 'Group'");
|
||||
|
||||
// Create node permissions on the groups
|
||||
Execute.Sql(@"INSERT INTO umbracoUserGroup2NodePermission (userGroupId,nodeId,permission)
|
||||
SELECT ug.id, nodeId, permission
|
||||
FROM umbracoUserGroup ug
|
||||
INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
|
||||
INNER JOIN umbracoUser u ON u.id = u2ug.userId
|
||||
INNER JOIN umbracoUser2NodePermission u2np ON u2np.userId = u.id
|
||||
WHERE ug.userGroupAlias NOT IN (
|
||||
SELECT userTypeAlias
|
||||
FROM umbracoUserType
|
||||
)");
|
||||
|
||||
// Create app permissions on the groups
|
||||
Execute.Sql(@"INSERT INTO umbracoUserGroup2app (userGroupId,app)
|
||||
SELECT ug.id, app
|
||||
FROM umbracoUserGroup ug
|
||||
INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
|
||||
INNER JOIN umbracoUser u ON u.id = u2ug.userId
|
||||
INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
|
||||
WHERE ug.userGroupAlias NOT IN (
|
||||
SELECT userTypeAlias
|
||||
FROM umbracoUserType
|
||||
)");
|
||||
}
|
||||
|
||||
private void DeleteOldTables(string[] tables, Tuple<string, string, string>[] constraints)
|
||||
{
|
||||
if (tables.InvariantContains("umbracoUser2App"))
|
||||
{
|
||||
Delete.Table("umbracoUser2App");
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUser2NodePermission"))
|
||||
{
|
||||
Delete.Table("umbracoUser2NodePermission");
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUserType") && tables.InvariantContains("umbracoUser"))
|
||||
{
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id")))
|
||||
{
|
||||
Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser");
|
||||
}
|
||||
|
||||
Delete.Column("userType").FromTable("umbracoUser");
|
||||
Delete.Table("umbracoUserType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.Temp8
|
||||
{
|
||||
[Migration("8.0.0", 2, Constants.System.UmbracoMigrationName)]
|
||||
public class AddUserStartNodeTable : MigrationBase
|
||||
{
|
||||
public AddUserStartNodeTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains("umbracoUserStartNode")) return;
|
||||
|
||||
Create.Table<UserStartNodeDto>();
|
||||
|
||||
MigrateUserStartNodes();
|
||||
|
||||
//now remove the old columns
|
||||
|
||||
Delete.Column("startStructureID").FromTable("umbracoUser");
|
||||
Delete.Column("startMediaID").FromTable("umbracoUser");
|
||||
}
|
||||
|
||||
private void MigrateUserStartNodes()
|
||||
{
|
||||
Execute.Sql(@"INSERT INTO umbracoUserStartNode (userId, startNode, startNodeType)
|
||||
SELECT id, startStructureID, 1
|
||||
FROM umbracoUser
|
||||
WHERE startStructureID IS NOT NULL AND startStructureID > 0 AND startStructureID IN (SELECT id FROM umbracoNode WHERE nodeObjectType='" + Constants.ObjectTypes.Document + "')");
|
||||
|
||||
Execute.Sql(@"INSERT INTO umbracoUserStartNode (userId, startNode, startNodeType)
|
||||
SELECT id, startMediaID, 2
|
||||
FROM umbracoUser
|
||||
WHERE startMediaID IS NOT NULL AND startMediaID > 0 AND startMediaID IN (SELECT id FROM umbracoNode WHERE nodeObjectType='" + Constants.ObjectTypes.Media + "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.Temp8
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures the built-in user groups have the blueprint permission by default on upgrade
|
||||
/// </summary>
|
||||
[Migration("8.0.0", 6, Constants.System.UmbracoMigrationName)]
|
||||
public class EnsureContentTemplatePermissions : MigrationBase
|
||||
{
|
||||
public EnsureContentTemplatePermissions(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Code(database =>
|
||||
{
|
||||
var userGroups = database.Fetch<UserGroupDto>(
|
||||
Context.Sql().Select("*")
|
||||
.From<UserGroupDto>()
|
||||
.Where<UserGroupDto>(x => x.Alias == "admin" || x.Alias == "editor"));
|
||||
|
||||
var local = Context.GetLocalMigration();
|
||||
|
||||
foreach (var userGroup in userGroups)
|
||||
{
|
||||
if (userGroup.DefaultPermissions.Contains('ï') == false)
|
||||
{
|
||||
userGroup.DefaultPermissions += "ï";
|
||||
local.Update.Table("umbracoUserGroup")
|
||||
.Set(new { userGroupDefaultPermissions = userGroup.DefaultPermissions })
|
||||
.Where(new { id = userGroup.Id });
|
||||
}
|
||||
}
|
||||
|
||||
return local.GetSql();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.Temp8
|
||||
{
|
||||
[Migration("8.0.0", 4, Constants.System.UmbracoMigrationName)]
|
||||
public class ReduceDictionaryKeyColumnsSize : MigrationBase
|
||||
{
|
||||
public ReduceDictionaryKeyColumnsSize(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//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
|
||||
|
||||
Execute.Code(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")));
|
||||
|
||||
if (colLen < 900 == false) return null;
|
||||
|
||||
var local = Context.GetLocalMigration();
|
||||
|
||||
//if it exists we need to drop it first
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_key")))
|
||||
{
|
||||
local.Delete.Index("IX_cmsDictionary_key").OnTable("cmsDictionary");
|
||||
}
|
||||
|
||||
//we can apply the col length change
|
||||
local.Alter.Table("cmsDictionary")
|
||||
.AlterColumn("key")
|
||||
.AsString(450)
|
||||
.NotNullable();
|
||||
|
||||
return local.GetSql();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.Temp8
|
||||
{
|
||||
[Migration("8.0.0", 0, Constants.System.UmbracoMigrationName)]
|
||||
public class UpdateUserTables : MigrationBase
|
||||
{
|
||||
public UpdateUserTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//Don't exeucte if the column is already there
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("createDate")) == false)
|
||||
Create.Column("createDate").OnTable("umbracoUser").AsDateTime().NotNullable().WithDefault(SystemMethods.CurrentDateTime);
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("updateDate")) == false)
|
||||
Create.Column("updateDate").OnTable("umbracoUser").AsDateTime().NotNullable().WithDefault(SystemMethods.CurrentDateTime);
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("emailConfirmedDate")) == false)
|
||||
Create.Column("emailConfirmedDate").OnTable("umbracoUser").AsDateTime().Nullable();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("invitedDate")) == false)
|
||||
Create.Column("invitedDate").OnTable("umbracoUser").AsDateTime().Nullable();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("passwordConfig")) == false)
|
||||
{
|
||||
Create.Column("passwordConfig").OnTable("umbracoUser").AsString(500).Nullable();
|
||||
//Check if we have a known config, we only want to store config for hashing
|
||||
var membershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
if (membershipProvider.PasswordFormat == MembershipPasswordFormat.Hashed)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(new { hashAlgorithm = Membership.HashAlgorithmType });
|
||||
Execute.Sql("UPDATE umbracoUser SET passwordConfig = '" + json + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
using NPoco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
@@ -12,7 +15,7 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
@@ -20,6 +23,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
#error the entire clads needs to be refactored for proper NPoco usage
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
@@ -27,20 +31,26 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
internal class UserRepository : NPocoRepositoryBase<int, IUser>, IUserRepository
|
||||
{
|
||||
private readonly IUserTypeRepository _userTypeRepository;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
private readonly IMapperCollection _mapperCollection;
|
||||
private readonly IDictionary<string, string> _passwordConfig;
|
||||
private PermissionRepository<IContent> _permissionRepository;
|
||||
|
||||
public UserRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IUserTypeRepository userTypeRepository, IMapperCollection mapperCollection, IDictionary<string, string> passwordConfig = null)
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="work"></param>
|
||||
/// <param name="cacheHelper"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="passwordConfig">
|
||||
/// A dictionary specifying the configuration for user passwords. If this is null then no password configuration will be persisted or read.
|
||||
/// </param>
|
||||
#error password config, change: null will ???
|
||||
public UserRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, IMapperCollection mapperCollection, IDictionary<string, string> passwordConfig = null)
|
||||
: base(work, cacheHelper, logger)
|
||||
{
|
||||
_userTypeRepository = userTypeRepository;
|
||||
_mapperCollection = mapperCollection;
|
||||
_cacheHelper = cacheHelper;
|
||||
|
||||
if (passwordConfig == null)
|
||||
|
||||
if (passwordConfig == null) // fixme this is bad bc we may want it to remain null?!
|
||||
{
|
||||
var userMembershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
passwordConfig = userMembershipProvider == null || userMembershipProvider.PasswordFormat != MembershipPasswordFormat.Hashed
|
||||
@@ -58,49 +68,193 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override IUser PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
var sql = GetQueryWithGroups();
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
sql //must be included for relator to work
|
||||
.OrderBy<UserDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserGroupDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
|
||||
var dto = Database
|
||||
.FetchOneToMany<UserDto>(x => x.User2AppDtos, sql)
|
||||
var dto = Database.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(new UserGroupRelator().Map, sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
var userType = _userTypeRepository.Get(dto.Type);
|
||||
var userFactory = new UserFactory(userType);
|
||||
var user = userFactory.BuildEntity(dto);
|
||||
|
||||
var user = UserFactory.BuildEntity(dto);
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a user by username
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="includeSecurityData">
|
||||
/// Can be used for slightly faster user lookups if the result doesn't require security data (i.e. groups, apps & start nodes).
|
||||
/// This is really only used for a shim in order to upgrade to 7.6.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A non cached <see cref="IUser"/> instance
|
||||
/// </returns>
|
||||
public IUser GetByUsername(string username, bool includeSecurityData)
|
||||
{
|
||||
UserDto dto;
|
||||
if (includeSecurityData)
|
||||
{
|
||||
var sql = GetQueryWithGroups();
|
||||
sql.Where<UserDto>(userDto => userDto.Login == username, SqlSyntax);
|
||||
sql //must be included for relator to work
|
||||
.OrderBy<UserDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserGroupDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
dto = Database
|
||||
.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(
|
||||
new UserGroupRelator().Map, sql)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = GetBaseQuery("umbracoUser.*");
|
||||
sql.Where<UserDto>(userDto => userDto.Login == username, SqlSyntax);
|
||||
dto = Database.FirstOrDefault<UserDto>(sql);
|
||||
}
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
var user = UserFactory.BuildEntity(dto);
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a user by id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="includeSecurityData">
|
||||
/// This is really only used for a shim in order to upgrade to 7.6 but could be used
|
||||
/// for slightly faster user lookups if the result doesn't require security data (i.e. groups, apps & start nodes)
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A non cached <see cref="IUser"/> instance
|
||||
/// </returns>
|
||||
public IUser Get(int id, bool includeSecurityData)
|
||||
{
|
||||
UserDto dto;
|
||||
if (includeSecurityData)
|
||||
{
|
||||
var sql = GetQueryWithGroups();
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
sql //must be included for relator to work
|
||||
.OrderBy<UserDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserGroupDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
dto = Database
|
||||
.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(
|
||||
new UserGroupRelator().Map, sql)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = GetBaseQuery("umbracoUser.*");
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
dto = Database.FirstOrDefault<UserDto>(sql);
|
||||
}
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
var user = UserFactory.BuildEntity(dto);
|
||||
return user;
|
||||
}
|
||||
|
||||
public IProfile GetProfile(string username)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where<UserDto>(userDto => userDto.UserName == username, SqlSyntax);
|
||||
|
||||
var dto = Database.Fetch<UserDto>(sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
return new UserProfile(dto.Id, dto.UserName);
|
||||
}
|
||||
|
||||
public IProfile GetProfile(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where<UserDto>(userDto => userDto.Id == id, SqlSyntax);
|
||||
|
||||
var dto = Database.Fetch<UserDto>(sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
return new UserProfile(dto.Id, dto.UserName);
|
||||
}
|
||||
|
||||
public IDictionary<UserState, int> GetUserStates()
|
||||
{
|
||||
var sql = @"SELECT '1CountOfAll' AS colName, COUNT(id) AS num FROM umbracoUser
|
||||
UNION
|
||||
SELECT '2CountOfActive' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NOT NULL
|
||||
UNION
|
||||
SELECT '3CountOfDisabled' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userDisabled = 1
|
||||
UNION
|
||||
SELECT '4CountOfLockedOut' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userNoConsole = 1
|
||||
UNION
|
||||
SELECT '5CountOfInvited' AS colName, COUNT(id) AS num FROM umbracoUser WHERE lastLoginDate IS NULL AND userDisabled = 1 AND invitedDate IS NOT NULL
|
||||
ORDER BY colName";
|
||||
|
||||
var result = Database.Fetch<dynamic>(sql);
|
||||
|
||||
return new Dictionary<UserState, int>
|
||||
{
|
||||
{UserState.All, result[0].num},
|
||||
{UserState.Active, result[1].num},
|
||||
{UserState.Disabled, result[2].num},
|
||||
{UserState.LockedOut, result[3].num},
|
||||
{UserState.Invited, result[4].num}
|
||||
};
|
||||
}
|
||||
|
||||
protected override IEnumerable<IUser> PerformGetAll(params int[] ids)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
|
||||
var sql = GetQueryWithGroups();
|
||||
if (ids.Any())
|
||||
{
|
||||
sql.Where("umbracoUser.id in (@ids)", new {ids = ids});
|
||||
sql.Where("umbracoUser.id in (@ids)", new { ids = ids });
|
||||
}
|
||||
#error refactor with FetchOneToMany
|
||||
sql //must be included for relator to work
|
||||
.OrderBy<UserDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserGroupDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
|
||||
var dtos = Database
|
||||
.FetchOneToMany<UserDto>(x => x.User2AppDtos, sql);
|
||||
var users = ConvertFromDtos(Database.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(new UserGroupRelator().Map, sql))
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
return ConvertFromDtos(dtos).ToArray(); // do it now and do it once, else can end up with nulls in cache
|
||||
return users;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IUser> PerformGetByQuery(IQuery<IUser> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var sqlClause = GetQueryWithGroups();
|
||||
var translator = new SqlTranslator<IUser>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
#error obviously refactor with FetchOneToMany!
|
||||
sql //must be included for relator to work
|
||||
.OrderBy<UserDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserGroupDto>(d => d.Id, SqlSyntax)
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
|
||||
var dtos = Database
|
||||
.FetchOneToMany<UserDto>(x => x.User2AppDtos, sql)
|
||||
var dtos = Database.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(new UserGroupRelator().Map, sql)
|
||||
.DistinctBy(x => x.Id);
|
||||
|
||||
return ConvertFromDtos(dtos).ToArray(); // do it now and do it once, else can end up with nulls in cache
|
||||
var users = ConvertFromDtos(dtos)
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -119,16 +273,39 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.On<UserDto, User2AppDto>(left => left.Id, right => right.UserId);
|
||||
}
|
||||
|
||||
#error prob needs to be refactored entirely
|
||||
/// <summary>
|
||||
/// A query to return a user with it's groups and with it's groups sections
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Sql GetQueryWithGroups()
|
||||
{
|
||||
//base query includes user groups
|
||||
var sql = GetBaseQuery("umbracoUser.*, umbracoUserGroup.*, umbracoUserGroup2App.*, umbracoUserStartNode.*");
|
||||
AddGroupLeftJoin(sql);
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static void AddGroupLeftJoin(Sql<SqlContext> sql)
|
||||
{
|
||||
sql
|
||||
.LeftJoin<User2UserGroupDto>()
|
||||
.On<User2UserGroupDto, UserDto>(left => left.UserId, right => right.Id)
|
||||
.LeftJoin<UserGroupDto>()
|
||||
.On<UserGroupDto, User2UserGroupDto>(left => left.Id, right => right.UserGroupId)
|
||||
.LeftJoin<UserGroup2AppDto>()
|
||||
.On<UserGroup2AppDto, UserGroupDto>(left => left.UserGroupId, right => right.Id)
|
||||
.LeftJoin<UserStartNodeDto>()
|
||||
.On<UserStartNodeDto, UserDto>(left => left.UserId, right => right.Id);
|
||||
}
|
||||
|
||||
private Sql<SqlContext> GetBaseQuery(string columns)
|
||||
{
|
||||
return Sql()
|
||||
.Select(columns)
|
||||
.From<UserDto>()
|
||||
.LeftJoin<User2AppDto>()
|
||||
.On<UserDto, User2AppDto>(left => left.Id, right => right.UserId);
|
||||
.From<UserDto>();
|
||||
}
|
||||
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return "umbracoUser.id = @Id";
|
||||
@@ -137,43 +314,66 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE userId = @Id",
|
||||
"DELETE FROM cmsTask WHERE parentUserId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUser2app WHERE " + SqlSyntax.GetQuotedColumnName("user") + "=@Id",
|
||||
"DELETE FROM umbracoUser WHERE id = @Id",
|
||||
"DELETE FROM umbracoExternalLogin WHERE id = @Id"
|
||||
};
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE userId = @Id",
|
||||
"DELETE FROM cmsTask WHERE parentUserId = @Id",
|
||||
"DELETE FROM umbracoUser2UserGroup WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUser WHERE id = @Id",
|
||||
"DELETE FROM umbracoExternalLogin WHERE id = @Id"
|
||||
};
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
protected override Guid NodeObjectTypeId => throw new NotImplementedException();
|
||||
|
||||
protected override void PersistNewItem(IUser entity)
|
||||
{
|
||||
var userFactory = new UserFactory(entity.UserType);
|
||||
((User) entity).AddingEntity();
|
||||
|
||||
//ensure security stamp if non
|
||||
// ensure security stamp if missing
|
||||
if (entity.SecurityStamp.IsNullOrWhiteSpace())
|
||||
{
|
||||
entity.SecurityStamp = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
var userDto = userFactory.BuildDto(entity);
|
||||
var userDto = UserFactory.BuildDto(entity);
|
||||
|
||||
// check if we have a known config, we only want to store config for hashing
|
||||
//TODO: This logic will need to be updated when we do http://issues.umbraco.org/issue/U4-10089
|
||||
if (_passwordConfig != null && _passwordConfig.Count > 0)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_passwordConfig);
|
||||
userDto.PasswordConfig = json;
|
||||
}
|
||||
|
||||
var id = Convert.ToInt32(Database.Insert(userDto));
|
||||
entity.Id = id;
|
||||
|
||||
foreach (var sectionDto in userDto.User2AppDtos)
|
||||
if (entity.IsPropertyDirty("StartContentIds"))
|
||||
{
|
||||
//need to set the id explicitly here
|
||||
sectionDto.UserId = id;
|
||||
Database.Insert(sectionDto);
|
||||
AddingOrUpdateStartNodes(entity, Enumerable.Empty<UserStartNodeDto>(), UserStartNodeDto.StartNodeTypeValue.Content, entity.StartContentIds);
|
||||
}
|
||||
|
||||
if (entity.IsPropertyDirty("StartMediaIds"))
|
||||
{
|
||||
AddingOrUpdateStartNodes(entity, Enumerable.Empty<UserStartNodeDto>(), UserStartNodeDto.StartNodeTypeValue.Media, entity.StartMediaIds);
|
||||
}
|
||||
|
||||
if (entity.IsPropertyDirty("Groups"))
|
||||
{
|
||||
// lookup all assigned
|
||||
var assigned = entity.Groups == null || entity.Groups.Any() == false
|
||||
? new List<UserGroupDto>()
|
||||
: Database.Fetch<UserGroupDto>("SELECT * FROM umbracoUserGroup WHERE userGroupAlias IN (@aliases)", new { aliases = entity.Groups.Select(x => x.Alias) });
|
||||
|
||||
foreach (var groupDto in assigned)
|
||||
{
|
||||
var dto = new User2UserGroupDto
|
||||
{
|
||||
UserGroupId = groupDto.Id,
|
||||
UserId = entity.Id
|
||||
};
|
||||
Database.Insert(dto);
|
||||
}
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
@@ -181,25 +381,21 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IUser entity)
|
||||
{
|
||||
var userFactory = new UserFactory(entity.UserType);
|
||||
// updates Modified date
|
||||
((User) entity).UpdatingEntity();
|
||||
|
||||
//ensure security stamp if non
|
||||
// ensure security stamp if missing
|
||||
if (entity.SecurityStamp.IsNullOrWhiteSpace())
|
||||
{
|
||||
entity.SecurityStamp = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
var userDto = userFactory.BuildDto(entity);
|
||||
var userDto = UserFactory.BuildDto(entity);
|
||||
|
||||
var dirtyEntity = (ICanBeDirty)entity;
|
||||
|
||||
//build list of columns to check for saving - we don't want to save the password if it hasn't changed!
|
||||
//List the columns to save, NOTE: would be nice to not have hard coded strings here but no real good way around that
|
||||
var colsToSave = new Dictionary<string, string>()
|
||||
// build list of columns to check for saving - we don't want to save the password if it hasn't changed!
|
||||
// list the columns to save, NOTE: would be nice to not have hard coded strings here but no real good way around that
|
||||
var colsToSave = new Dictionary<string, string>
|
||||
{
|
||||
{"userDisabled", "IsApproved"},
|
||||
{"userNoConsole", "IsLockedOut"},
|
||||
{"userType", "UserType"},
|
||||
{"startStructureID", "StartContentId"},
|
||||
{"startMediaID", "StartMediaId"},
|
||||
{"userName", "Name"},
|
||||
@@ -211,27 +407,42 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{"lastPasswordChangeDate", "LastPasswordChangeDate"},
|
||||
{"lastLoginDate", "LastLoginDate"},
|
||||
{"failedLoginAttempts", "FailedPasswordAttempts"},
|
||||
{"createDate", "CreateDate"},
|
||||
{"updateDate", "UpdateDate"},
|
||||
{"avatar", "Avatar"},
|
||||
{"emailConfirmedDate", "EmailConfirmedDate"},
|
||||
{"invitedDate", "InvitedDate"}
|
||||
};
|
||||
|
||||
//create list of properties that have changed
|
||||
// create list of properties that have changed
|
||||
var changedCols = colsToSave
|
||||
.Where(col => dirtyEntity.IsPropertyDirty(col.Value))
|
||||
.Where(col => entity.IsPropertyDirty(col.Value))
|
||||
.Select(col => col.Key)
|
||||
.ToList();
|
||||
|
||||
// DO NOT update the password if it has not changed or if it is null or empty
|
||||
if (dirtyEntity.IsPropertyDirty("RawPasswordValue") && entity.RawPasswordValue.IsNullOrWhiteSpace() == false)
|
||||
if (entity.IsPropertyDirty("RawPasswordValue") && entity.RawPasswordValue.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
changedCols.Add("userPassword");
|
||||
|
||||
//special case - when using ASP.Net identity the user manager will take care of updating the security stamp, however
|
||||
// special case - when using ASP.Net identity the user manager will take care of updating the security stamp, however
|
||||
// when not using ASP.Net identity (i.e. old membership providers), we'll need to take care of updating this manually
|
||||
// so we can just detect if that property is dirty, if it's not we'll set it manually
|
||||
if (dirtyEntity.IsPropertyDirty("SecurityStamp") == false)
|
||||
if (entity.IsPropertyDirty("SecurityStamp") == false)
|
||||
{
|
||||
userDto.SecurityStampToken = entity.SecurityStamp = Guid.NewGuid().ToString();
|
||||
changedCols.Add("securityStampToken");
|
||||
}
|
||||
|
||||
// check if we have a known config, we only want to store config for hashing
|
||||
//TODO: This logic will need to be updated when we do http://issues.umbraco.org/issue/U4-10089
|
||||
if (_passwordConfig != null && _passwordConfig.Count > 0)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_passwordConfig);
|
||||
userDto.PasswordConfig = json;
|
||||
|
||||
changedCols.Add("passwordConfig");
|
||||
}
|
||||
}
|
||||
|
||||
//only update the changed cols
|
||||
@@ -240,42 +451,66 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Update(userDto, changedCols);
|
||||
}
|
||||
|
||||
//update the sections if they've changed
|
||||
var user = (User)entity;
|
||||
if (user.IsPropertyDirty("AllowedSections"))
|
||||
if (entity.IsPropertyDirty("StartContentIds") || entity.IsPropertyDirty("StartMediaIds"))
|
||||
{
|
||||
//now we need to delete any applications that have been removed
|
||||
foreach (var section in user.RemovedSections)
|
||||
var assignedStartNodes = Database.Fetch<UserStartNodeDto>("SELECT * FROM umbracoUserStartNode WHERE userId = @userId", new { userId = entity.Id });
|
||||
if (entity.IsPropertyDirty("StartContentIds"))
|
||||
{
|
||||
//we need to manually delete thsi record because it has a composite key
|
||||
Database.Delete<User2AppDto>("WHERE app=@Section AND " + SqlSyntax.GetQuotedColumnName("user") + "=@UserId",
|
||||
new { Section = section, UserId = (int)user.Id });
|
||||
AddingOrUpdateStartNodes(entity, assignedStartNodes, UserStartNodeDto.StartNodeTypeValue.Content, entity.StartContentIds);
|
||||
}
|
||||
|
||||
//for any that exist on the object, we need to determine if we need to update or insert
|
||||
//NOTE: the User2AppDtos collection wil always be equal to the User.AllowedSections
|
||||
foreach (var sectionDto in userDto.User2AppDtos)
|
||||
if (entity.IsPropertyDirty("StartMediaIds"))
|
||||
{
|
||||
//if something has been added then insert it
|
||||
if (user.AddedSections.Contains(sectionDto.AppAlias))
|
||||
{
|
||||
//we need to insert since this was added
|
||||
Database.Insert(sectionDto);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we need to manually update this record because it has a composite key
|
||||
Database.Update<User2AppDto>("SET app=@Section WHERE app=@Section AND " + SqlSyntax.GetQuotedColumnName("user") + "=@UserId",
|
||||
new { Section = sectionDto.AppAlias, UserId = sectionDto.UserId });
|
||||
}
|
||||
AddingOrUpdateStartNodes(entity, assignedStartNodes, UserStartNodeDto.StartNodeTypeValue.Media, entity.StartMediaIds);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.IsPropertyDirty("Groups"))
|
||||
{
|
||||
//lookup all assigned
|
||||
var assigned = entity.Groups == null || entity.Groups.Any() == false
|
||||
? new List<UserGroupDto>()
|
||||
: Database.Fetch<UserGroupDto>("SELECT * FROM umbracoUserGroup WHERE userGroupAlias IN (@aliases)", new { aliases = entity.Groups.Select(x => x.Alias) });
|
||||
|
||||
//first delete all
|
||||
//TODO: We could do this a nicer way instead of "Nuke and Pave"
|
||||
Database.Delete<User2UserGroupDto>("WHERE UserId = @UserId", new { UserId = entity.Id });
|
||||
|
||||
foreach (var groupDto in assigned)
|
||||
{
|
||||
var dto = new User2UserGroupDto
|
||||
{
|
||||
UserGroupId = groupDto.Id,
|
||||
UserId = entity.Id
|
||||
};
|
||||
Database.Insert(dto);
|
||||
}
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
private void AddingOrUpdateStartNodes(IEntity entity, IEnumerable<UserStartNodeDto> current, UserStartNodeDto.StartNodeTypeValue startNodeType, int[] entityStartIds)
|
||||
{
|
||||
var assignedIds = current.Where(x => x.StartNodeType == (int)startNodeType).Select(x => x.StartNode).ToArray();
|
||||
|
||||
//remove the ones not assigned to the entity
|
||||
var toDelete = assignedIds.Except(entityStartIds).ToArray();
|
||||
if (toDelete.Length > 0)
|
||||
Database.Delete<UserStartNodeDto>("WHERE UserId = @UserId AND startNode IN (@startNodes)", new { UserId = entity.Id, startNodes = toDelete });
|
||||
//add the ones not currently in the db
|
||||
var toAdd = entityStartIds.Except(assignedIds).ToArray();
|
||||
foreach (var i in toAdd)
|
||||
{
|
||||
var dto = new UserStartNodeDto
|
||||
{
|
||||
StartNode = i,
|
||||
StartNodeType = (int)startNodeType,
|
||||
UserId = entity.Id
|
||||
};
|
||||
Database.Insert(dto);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IUserRepository
|
||||
@@ -302,47 +537,81 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return Database.ExecuteScalar<int>(sql) > 0;
|
||||
}
|
||||
|
||||
public IEnumerable<IUser> GetUsersAssignedToSection(string sectionAlias)
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="IUser"/> objects associated with a given group
|
||||
/// </summary>
|
||||
/// <param name="groupId">Id of group</param>
|
||||
public IEnumerable<IUser> GetAllInGroup(int groupId)
|
||||
{
|
||||
//Here we're building up a query that looks like this, a sub query is required because the resulting structure
|
||||
// needs to still contain all of the section rows per user.
|
||||
return GetAllInOrNotInGroup(groupId, true);
|
||||
}
|
||||
|
||||
//SELECT *
|
||||
//FROM [umbracoUser]
|
||||
//LEFT JOIN [umbracoUser2app]
|
||||
//ON [umbracoUser].[id] = [umbracoUser2app].[user]
|
||||
//WHERE umbracoUser.id IN (SELECT umbracoUser.id
|
||||
// FROM [umbracoUser]
|
||||
// LEFT JOIN [umbracoUser2app]
|
||||
// ON [umbracoUser].[id] = [umbracoUser2app].[user]
|
||||
// WHERE umbracoUser2app.app = 'content')
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="IUser"/> objects not associated with a given group
|
||||
/// </summary>
|
||||
/// <param name="groupId">Id of group</param>
|
||||
public IEnumerable<IUser> GetAllNotInGroup(int groupId)
|
||||
{
|
||||
return GetAllInOrNotInGroup(groupId, false);
|
||||
}
|
||||
|
||||
var sql = GetBaseQuery(false);
|
||||
var innerSql = GetBaseQuery("umbracoUser.id");
|
||||
innerSql.Where("umbracoUser2app.app = " + SqlSyntax.GetQuotedValue(sectionAlias));
|
||||
sql.Where(string.Format("umbracoUser.id IN ({0})", innerSql.SQL));
|
||||
private IEnumerable<IUser> GetAllInOrNotInGroup(int groupId, bool include)
|
||||
{
|
||||
#error this needs to be rewritten
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserDto>();
|
||||
|
||||
var dtos = Database
|
||||
.FetchOneToMany<UserDto>(x => x.User2AppDtos, sql);
|
||||
var innerSql = new Sql();
|
||||
innerSql.Select("umbracoUser.id")
|
||||
.From<UserDto>()
|
||||
.LeftJoin<User2UserGroupDto>()
|
||||
.On<UserDto, User2UserGroupDto>(left => left.Id, right => right.UserId)
|
||||
.Where("umbracoUser2UserGroup.userGroupId = " + groupId);
|
||||
|
||||
return ConvertFromDtos(dtos);
|
||||
sql.Where(string.Format("umbracoUser.id {0} ({1})",
|
||||
include ? "IN" : "NOT IN",
|
||||
innerSql.SQL));
|
||||
return ConvertFromDtos(Database.Fetch<UserDto>(sql));
|
||||
}
|
||||
|
||||
[Obsolete("Use the overload with long operators instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, int pageIndex, int pageSize, out int totalRecords, Expression<Func<IUser, string>> orderBy)
|
||||
{
|
||||
if (orderBy == null) throw new ArgumentNullException("orderBy");
|
||||
|
||||
// get the referenced column name and find the corresp mapped column name
|
||||
var expressionMember = ExpressionHelper.GetMemberInfo(orderBy);
|
||||
var mapper = MappingResolver.Current.ResolveMapperByType(typeof(IUser));
|
||||
var mappedField = mapper.Map(expressionMember.Name);
|
||||
|
||||
if (mappedField.IsNullOrWhiteSpace())
|
||||
throw new ArgumentException("Could not find a mapping for the column specified in the orderBy clause");
|
||||
|
||||
long tr;
|
||||
var results = GetPagedResultsByQuery(query, Convert.ToInt64(pageIndex), pageSize, out tr, mappedField, Direction.Ascending);
|
||||
totalRecords = Convert.ToInt32(tr);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged user results
|
||||
/// </summary>
|
||||
/// <param name="query">
|
||||
/// The where clause, if this is null all records are queried
|
||||
/// </param>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="orderDirection"></param>
|
||||
/// <param name="userGroups">Optional parameter to filter by specified user groups</param>
|
||||
/// <param name="userState">Optional parameter to filter by specfied user state</param>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The query supplied will ONLY work with data specifically on the umbracoUser table because we are using NPoco paging (SQL paging)
|
||||
/// </remarks>
|
||||
public IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, long pageIndex, int pageSize, out long totalRecords, Expression<Func<IUser, string>> orderBy)
|
||||
public IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, long pageIndex, int pageSize, out long totalRecords, Expression<Func<IUser, object>> orderBy, Direction orderDirection, string[] userGroups = null, UserState[] userState = null, IQuery<IUser> filter = null)
|
||||
{
|
||||
if (orderBy == null) throw new ArgumentNullException(nameof(orderBy));
|
||||
|
||||
@@ -354,29 +623,180 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
if (mappedField.IsNullOrWhiteSpace())
|
||||
throw new ArgumentException("Could not find a mapping for the column specified in the orderBy clause");
|
||||
|
||||
var sql = Sql()
|
||||
.Select("umbracoUser.Id")
|
||||
.From<UserDto>();
|
||||
return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, mappedField, orderDirection, userGroups, userState, filter);
|
||||
}
|
||||
|
||||
var idsQuery = query == null ? sql : new SqlTranslator<IUser>(sql, query).Translate();
|
||||
|
||||
// need to ensure the order by is in brackets, see: https://github.com/toptensoftware/PetaPoco/issues/177
|
||||
idsQuery.OrderBy("(" + mappedField + ")");
|
||||
var page = Database.Page<int>(pageIndex + 1, pageSize, idsQuery);
|
||||
totalRecords = Convert.ToInt32(page.TotalItems);
|
||||
|
||||
if (totalRecords == 0)
|
||||
return Enumerable.Empty<IUser>();
|
||||
private IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection,
|
||||
string[] userGroups = null,
|
||||
UserState[] userState = null,
|
||||
IQuery<IUser> filter = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(orderBy)) throw new ArgumentException("Value cannot be null or whitespace.", "orderBy");
|
||||
|
||||
// now get the actual users and ensure they are ordered properly (same clause)
|
||||
var ids = page.Items.ToArray();
|
||||
return ids.Length == 0 ? Enumerable.Empty<IUser>() : GetAll(ids).OrderBy(orderBy.Compile());
|
||||
|
||||
Sql filterSql = null;
|
||||
if (filter != null || (userGroups != null && userGroups.Length > 0) || (userState != null && userState.Length > 0 && userState.Contains(UserState.All) == false))
|
||||
filterSql = new Sql();
|
||||
|
||||
if (filter != null)
|
||||
{
|
||||
foreach (var filterClause in filter.GetWhereClauses())
|
||||
{
|
||||
filterSql.Append(string.Format("AND ({0})", filterClause.Item1), filterClause.Item2);
|
||||
}
|
||||
}
|
||||
if (userGroups != null && userGroups.Length > 0)
|
||||
{
|
||||
var subQuery = @"AND (umbracoUser.id IN (SELECT DISTINCT umbracoUser.id
|
||||
FROM umbracoUser
|
||||
INNER JOIN umbracoUser2UserGroup ON umbracoUser2UserGroup.userId = umbracoUser.id
|
||||
INNER JOIN umbracoUserGroup ON umbracoUserGroup.id = umbracoUser2UserGroup.userGroupId
|
||||
WHERE umbracoUserGroup.userGroupAlias IN (@userGroups)))";
|
||||
filterSql.Append(subQuery, new { userGroups = userGroups });
|
||||
}
|
||||
if (userState != null && userState.Length > 0)
|
||||
{
|
||||
//the "ALL" state doesn't require any filtering so we ignore that, if it exists in the list we don't do any filtering
|
||||
if (userState.Contains(UserState.All) == false)
|
||||
{
|
||||
var sb = new StringBuilder("(");
|
||||
var appended = false;
|
||||
|
||||
if (userState.Contains(UserState.Active))
|
||||
{
|
||||
sb.Append("(userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NOT NULL)");
|
||||
appended = true;
|
||||
}
|
||||
if (userState.Contains(UserState.Disabled))
|
||||
{
|
||||
if (appended) sb.Append(" OR ");
|
||||
sb.Append("(userDisabled = 1)");
|
||||
}
|
||||
if (userState.Contains(UserState.LockedOut))
|
||||
{
|
||||
if (appended) sb.Append(" OR ");
|
||||
sb.Append("(userNoConsole = 1)");
|
||||
}
|
||||
if (userState.Contains(UserState.Invited))
|
||||
{
|
||||
if (appended) sb.Append(" OR ");
|
||||
sb.Append("(lastLoginDate IS NULL AND userDisabled = 1 AND invitedDate IS NOT NULL)");
|
||||
}
|
||||
|
||||
sb.Append(")");
|
||||
|
||||
filterSql.Append("AND " + sb);
|
||||
}
|
||||
}
|
||||
|
||||
// Get base query for returning IDs
|
||||
var sqlBaseIds = GetBaseQuery("id");
|
||||
|
||||
if (query == null) query = new Query<IUser>();
|
||||
var translatorIds = new SqlTranslator<IUser>(sqlBaseIds, query);
|
||||
var sqlQueryIds = translatorIds.Translate();
|
||||
|
||||
//get sorted and filtered sql
|
||||
var sqlNodeIdsWithSort = GetSortedSqlForPagedResults(
|
||||
GetFilteredSqlForPagedResults(sqlQueryIds, filterSql),
|
||||
orderDirection, orderBy);
|
||||
|
||||
// Get page of results and total count
|
||||
var pagedResult = Database.Page<UserDto>(pageIndex + 1, pageSize, sqlNodeIdsWithSort);
|
||||
totalRecords = Convert.ToInt32(pagedResult.TotalItems);
|
||||
|
||||
//NOTE: We need to check the actual items returned, not the 'totalRecords', that is because if you request a page number
|
||||
// that doesn't actually have any data on it, the totalRecords will still indicate there are records but there are none in
|
||||
// the pageResult.
|
||||
if (pagedResult.Items.Any())
|
||||
{
|
||||
//Create the inner paged query that was used above to get the paged result, we'll use that as the inner sub query
|
||||
var args = sqlNodeIdsWithSort.Arguments;
|
||||
string sqlStringCount, sqlStringPage;
|
||||
Database.BuildPageQueries<UserDto>(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage);
|
||||
|
||||
var sqlQueryFull = GetBaseQuery("umbracoUser.*, umbracoUserGroup.*, umbracoUserGroup2App.*, umbracoUserStartNode.*");
|
||||
|
||||
var fullQueryWithPagedInnerJoin = sqlQueryFull
|
||||
.Append("INNER JOIN (")
|
||||
//join the paged query with the paged query arguments
|
||||
.Append(sqlStringPage, args)
|
||||
.Append(") temp ")
|
||||
.Append("ON umbracoUser.id = temp.id");
|
||||
|
||||
AddGroupLeftJoin(fullQueryWithPagedInnerJoin);
|
||||
|
||||
//get sorted and filtered sql
|
||||
var fullQuery = GetSortedSqlForPagedResults(
|
||||
GetFilteredSqlForPagedResults(fullQueryWithPagedInnerJoin, filterSql),
|
||||
orderDirection, orderBy);
|
||||
|
||||
var users = ConvertFromDtos(Database.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(new UserGroupRelator().Map, fullQuery))
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
return Enumerable.Empty<IUser>();
|
||||
}
|
||||
|
||||
private Sql GetFilteredSqlForPagedResults(Sql sql, Sql filterSql)
|
||||
{
|
||||
Sql filteredSql;
|
||||
|
||||
// Apply filter
|
||||
if (filterSql != null)
|
||||
{
|
||||
var sqlFilter = " WHERE " + filterSql.SQL.TrimStart("AND ");
|
||||
|
||||
//NOTE: this is certainly strange - NPoco handles this much better but we need to re-create the sql
|
||||
// instance a couple of times to get the parameter order correct, for some reason the first
|
||||
// time the arguments don't show up correctly but the SQL argument parameter names are actually updated
|
||||
// accordingly - so we re-create it again. In v8 we don't need to do this and it's already taken care of.
|
||||
|
||||
filteredSql = new Sql(sql.SQL, sql.Arguments);
|
||||
var args = filteredSql.Arguments.Concat(filterSql.Arguments).ToArray();
|
||||
filteredSql = new Sql(
|
||||
string.Format("{0} {1}", filteredSql.SQL, sqlFilter),
|
||||
args);
|
||||
filteredSql = new Sql(filteredSql.SQL, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
//copy to var so that the original isn't changed
|
||||
filteredSql = new Sql(sql.SQL, sql.Arguments);
|
||||
}
|
||||
return filteredSql;
|
||||
}
|
||||
|
||||
private Sql GetSortedSqlForPagedResults(Sql sql, Direction orderDirection, string orderBy)
|
||||
{
|
||||
//copy to var so that the original isn't changed
|
||||
var sortedSql = new Sql(sql.SQL, sql.Arguments);
|
||||
|
||||
// Apply order according to parameters
|
||||
if (string.IsNullOrEmpty(orderBy) == false)
|
||||
{
|
||||
//each order by param needs to be in a bracket! see: https://github.com/toptensoftware/PetaPoco/issues/177
|
||||
var orderByParams = new[] { string.Format("({0})", orderBy) };
|
||||
if (orderDirection == Direction.Ascending)
|
||||
{
|
||||
sortedSql.OrderBy(orderByParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortedSql.OrderByDescending(orderByParams);
|
||||
}
|
||||
}
|
||||
return sortedSql;
|
||||
}
|
||||
|
||||
internal IEnumerable<IUser> GetNextUsers(int id, int count)
|
||||
{
|
||||
var idsQuery = Sql()
|
||||
.Select("umbracoUser.Id")
|
||||
.Select("umbracoUser.id")
|
||||
.From<UserDto>()
|
||||
.Where<UserDto>(x => x.Id >= id)
|
||||
.OrderBy<UserDto>(x => x.Id);
|
||||
@@ -388,54 +808,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return ids.Length == 0 ? Enumerable.Empty<IUser>() : GetAll(ids).OrderBy(x => x.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions for a given user for any number of nodes
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds)
|
||||
{
|
||||
return PermissionRepository.GetUserPermissionsForEntities(userId, entityIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
public void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
PermissionRepository.ReplaceUserPermissions(userId, permissions, entityIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
public void AssignUserPermission(int userId, char permission, params int[] entityIds)
|
||||
{
|
||||
PermissionRepository.AssignUserPermission(userId, permission, entityIds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<IUser> ConvertFromDtos(IEnumerable<UserDto> dtos)
|
||||
{
|
||||
var userTypeIds = dtos.Select(x => Convert.ToInt32(x.Type)).ToArray();
|
||||
|
||||
var allUserTypes = userTypeIds.Length == 0 ? Enumerable.Empty<IUserType>() : _userTypeRepository.GetAll(userTypeIds);
|
||||
|
||||
return dtos.Select(dto =>
|
||||
{
|
||||
var userType = allUserTypes.Single(x => x.Id == dto.Type);
|
||||
|
||||
var userFactory = new UserFactory(userType);
|
||||
return userFactory.BuildEntity(dto);
|
||||
});
|
||||
return dtos.Select(UserFactory.BuildEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,8 +1146,8 @@
|
||||
<Compile Include="Persistence\Repositories\Interfaces\ITaskRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\ITaskTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\ITemplateRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IUserGroupRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IUserRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IUserTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IXsltFileRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\LanguageRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\MacroRepository.cs" />
|
||||
@@ -1181,8 +1181,8 @@
|
||||
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\TemplateRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\TupleExtensions.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserGroupRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\VersionableRepositoryBase.cs" />
|
||||
<Compile Include="Persistence\Repositories\VersionableRepositoryBaseAliasRegex.cs" />
|
||||
<Compile Include="Persistence\Repositories\XsltFileRepository.cs" />
|
||||
|
||||
Reference in New Issue
Block a user