mirror of https://github.com/abpframework/abp.git
40 changed files with 2205 additions and 592 deletions
@ -0,0 +1,14 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.Settings; |
||||
|
|
||||
|
public interface IDynamicSettingDefinitionStore |
||||
|
{ |
||||
|
Task<SettingDefinition> GetAsync([NotNull] string name); |
||||
|
|
||||
|
Task<IReadOnlyList<SettingDefinition>> GetAllAsync(); |
||||
|
|
||||
|
Task<SettingDefinition> GetOrNullAsync([NotNull] string name); |
||||
|
} |
||||
@ -1,14 +1,17 @@ |
|||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
using JetBrains.Annotations; |
using JetBrains.Annotations; |
||||
|
|
||||
namespace Volo.Abp.Settings; |
namespace Volo.Abp.Settings; |
||||
|
|
||||
public interface ISettingDefinitionManager |
public interface ISettingDefinitionManager |
||||
{ |
{ |
||||
[NotNull] |
[ItemNotNull] |
||||
SettingDefinition Get([NotNull] string name); |
Task<SettingDefinition> GetAsync([NotNull] string name); |
||||
|
|
||||
IReadOnlyList<SettingDefinition> GetAll(); |
[ItemNotNull] |
||||
|
Task<IReadOnlyList<SettingDefinition>> GetAllAsync(); |
||||
|
|
||||
SettingDefinition GetOrNull(string name); |
[ItemCanBeNull] |
||||
|
Task<SettingDefinition> GetOrNullAsync([NotNull] string name); |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,14 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.Settings; |
||||
|
|
||||
|
public interface IStaticSettingDefinitionStore |
||||
|
{ |
||||
|
Task<SettingDefinition> GetAsync([NotNull] string name); |
||||
|
|
||||
|
Task<IReadOnlyList<SettingDefinition>> GetAllAsync(); |
||||
|
|
||||
|
Task<SettingDefinition> GetOrNullAsync([NotNull] string name); |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.Immutable; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Settings; |
||||
|
|
||||
|
public class NullDynamicSettingDefinitionStore : IDynamicSettingDefinitionStore, ISingletonDependency |
||||
|
{ |
||||
|
private readonly static Task<SettingDefinition> CachedSettingResult = Task.FromResult((SettingDefinition)null); |
||||
|
|
||||
|
private readonly static Task<IReadOnlyList<SettingDefinition>> CachedSettingsResult = Task.FromResult((IReadOnlyList<SettingDefinition>)Array.Empty<SettingDefinition>().ToImmutableList()); |
||||
|
|
||||
|
public Task<SettingDefinition> GetAsync(string name) |
||||
|
{ |
||||
|
return CachedSettingResult; |
||||
|
} |
||||
|
|
||||
|
public Task<IReadOnlyList<SettingDefinition>> GetAllAsync() |
||||
|
{ |
||||
|
return CachedSettingsResult; |
||||
|
} |
||||
|
|
||||
|
public Task<SettingDefinition> GetOrNullAsync(string name) |
||||
|
{ |
||||
|
return CachedSettingResult; |
||||
|
} |
||||
|
} |
||||
@ -1,72 +1,50 @@ |
|||||
using System; |
using System.Collections.Generic; |
||||
using System.Collections.Generic; |
|
||||
using System.Collections.Immutable; |
using System.Collections.Immutable; |
||||
using System.Linq; |
using System.Linq; |
||||
using Microsoft.Extensions.DependencyInjection; |
using System.Threading.Tasks; |
||||
using Microsoft.Extensions.Options; |
|
||||
using Volo.Abp.DependencyInjection; |
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
namespace Volo.Abp.Settings; |
namespace Volo.Abp.Settings; |
||||
|
|
||||
public class SettingDefinitionManager : ISettingDefinitionManager, ISingletonDependency |
public class SettingDefinitionManager : ISettingDefinitionManager, ISingletonDependency |
||||
{ |
{ |
||||
protected Lazy<IDictionary<string, SettingDefinition>> SettingDefinitions { get; } |
protected readonly IStaticSettingDefinitionStore StaticStore; |
||||
|
protected readonly IDynamicSettingDefinitionStore DynamicStore; |
||||
|
|
||||
protected AbpSettingOptions Options { get; } |
public SettingDefinitionManager(IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) |
||||
|
|
||||
protected IServiceProvider ServiceProvider { get; } |
|
||||
|
|
||||
public SettingDefinitionManager( |
|
||||
IOptions<AbpSettingOptions> options, |
|
||||
IServiceProvider serviceProvider) |
|
||||
{ |
{ |
||||
ServiceProvider = serviceProvider; |
StaticStore = staticStore; |
||||
Options = options.Value; |
DynamicStore = dynamicStore; |
||||
|
|
||||
SettingDefinitions = new Lazy<IDictionary<string, SettingDefinition>>(CreateSettingDefinitions, true); |
|
||||
} |
} |
||||
|
|
||||
public virtual SettingDefinition Get(string name) |
public virtual async Task<SettingDefinition> GetAsync(string name) |
||||
{ |
{ |
||||
Check.NotNull(name, nameof(name)); |
var permission = await GetOrNullAsync(name); |
||||
|
if (permission == null) |
||||
var setting = GetOrNull(name); |
|
||||
|
|
||||
if (setting == null) |
|
||||
{ |
{ |
||||
throw new AbpException("Undefined setting: " + name); |
throw new AbpException("Undefined Template: " + name); |
||||
} |
} |
||||
|
|
||||
return setting; |
return permission; |
||||
} |
} |
||||
|
|
||||
public virtual IReadOnlyList<SettingDefinition> GetAll() |
public virtual async Task<SettingDefinition> GetOrNullAsync(string name) |
||||
{ |
{ |
||||
return SettingDefinitions.Value.Values.ToImmutableList(); |
Check.NotNull(name, nameof(name)); |
||||
} |
|
||||
|
|
||||
public virtual SettingDefinition GetOrNull(string name) |
return await StaticStore.GetOrNullAsync(name) ?? await DynamicStore.GetOrNullAsync(name); |
||||
{ |
|
||||
return SettingDefinitions.Value.GetOrDefault(name); |
|
||||
} |
} |
||||
|
|
||||
protected virtual IDictionary<string, SettingDefinition> CreateSettingDefinitions() |
public virtual async Task<IReadOnlyList<SettingDefinition>> GetAllAsync() |
||||
{ |
{ |
||||
var settings = new Dictionary<string, SettingDefinition>(); |
var staticTemplates = await StaticStore.GetAllAsync(); |
||||
|
var staticTemplateNames = staticTemplates |
||||
|
.Select(p => p.Name) |
||||
|
.ToImmutableHashSet(); |
||||
|
|
||||
using (var scope = ServiceProvider.CreateScope()) |
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
||||
{ |
|
||||
var providers = Options |
|
||||
.DefinitionProviders |
|
||||
.Select(p => scope.ServiceProvider.GetRequiredService(p) as ISettingDefinitionProvider) |
|
||||
.ToList(); |
|
||||
|
|
||||
foreach (var provider in providers) |
|
||||
{ |
|
||||
provider.Define(new SettingDefinitionContext(settings)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return settings; |
/* We prefer static Templates over dynamics */ |
||||
|
return staticTemplates.Concat(dynamicTemplates.Where(d => !staticTemplateNames.Contains(d.Name))).ToImmutableList(); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,71 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.Immutable; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Settings; |
||||
|
|
||||
|
public class StaticSettingDefinitionStore : IStaticSettingDefinitionStore, ISingletonDependency |
||||
|
{ |
||||
|
protected Lazy<IDictionary<string, SettingDefinition>> SettingDefinitions { get; } |
||||
|
|
||||
|
protected AbpSettingOptions Options { get; } |
||||
|
|
||||
|
protected IServiceProvider ServiceProvider { get; } |
||||
|
|
||||
|
public StaticSettingDefinitionStore(IOptions<AbpSettingOptions> options, IServiceProvider serviceProvider) |
||||
|
{ |
||||
|
ServiceProvider = serviceProvider; |
||||
|
Options = options.Value; |
||||
|
|
||||
|
SettingDefinitions = new Lazy<IDictionary<string, SettingDefinition>>(CreateSettingDefinitions, true); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<SettingDefinition> GetAsync(string name) |
||||
|
{ |
||||
|
Check.NotNull(name, nameof(name)); |
||||
|
|
||||
|
var setting = await GetOrNullAsync(name); |
||||
|
|
||||
|
if (setting == null) |
||||
|
{ |
||||
|
throw new AbpException("Undefined setting: " + name); |
||||
|
} |
||||
|
|
||||
|
return setting; |
||||
|
} |
||||
|
|
||||
|
public virtual Task<IReadOnlyList<SettingDefinition>> GetAllAsync() |
||||
|
{ |
||||
|
return Task.FromResult<IReadOnlyList<SettingDefinition>>(SettingDefinitions.Value.Values.ToImmutableList()); |
||||
|
} |
||||
|
|
||||
|
public virtual Task<SettingDefinition> GetOrNullAsync(string name) |
||||
|
{ |
||||
|
return Task.FromResult(SettingDefinitions.Value.GetOrDefault(name)); |
||||
|
} |
||||
|
|
||||
|
protected virtual IDictionary<string, SettingDefinition> CreateSettingDefinitions() |
||||
|
{ |
||||
|
var settings = new Dictionary<string, SettingDefinition>(); |
||||
|
|
||||
|
using (var scope = ServiceProvider.CreateScope()) |
||||
|
{ |
||||
|
var providers = Options |
||||
|
.DefinitionProviders |
||||
|
.Select(p => scope.ServiceProvider.GetRequiredService(p) as ISettingDefinitionProvider) |
||||
|
.ToList(); |
||||
|
|
||||
|
foreach (var provider in providers) |
||||
|
{ |
||||
|
provider.Define(new SettingDefinitionContext(settings)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return settings; |
||||
|
} |
||||
|
} |
||||
@ -1,484 +0,0 @@ |
|||||
using System; |
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
|
||||
|
|
||||
namespace Volo.Abp.SettingManagement.DemoApp.Migrations; |
|
||||
|
|
||||
public partial class init : Migration |
|
||||
{ |
|
||||
protected override void Up(MigrationBuilder migrationBuilder) |
|
||||
{ |
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpClaimTypes", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
Required = table.Column<bool>(type: "bit", nullable: false), |
|
||||
IsStatic = table.Column<bool>(type: "bit", nullable: false), |
|
||||
Regex = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true), |
|
||||
RegexDescription = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), |
|
||||
Description = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
|
||||
ValueType = table.Column<int>(type: "int", nullable: false), |
|
||||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|
||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpClaimTypes", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpLinkUsers", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
SourceUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
SourceTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
TargetUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TargetTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpLinkUsers", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpOrganizationUnits", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
ParentId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
Code = table.Column<string>(type: "nvarchar(95)", maxLength: 95, nullable: false), |
|
||||
DisplayName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
|
||||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|
||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|
||||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true), |
|
||||
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpOrganizationUnits", x => x.Id); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpOrganizationUnits_AbpOrganizationUnits_ParentId", |
|
||||
column: x => x.ParentId, |
|
||||
principalTable: "AbpOrganizationUnits", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Restrict); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpPermissionGrants", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
|
||||
ProviderName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false), |
|
||||
ProviderKey = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpPermissionGrants", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpRoles", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
NormalizedName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
IsDefault = table.Column<bool>(type: "bit", nullable: false), |
|
||||
IsStatic = table.Column<bool>(type: "bit", nullable: false), |
|
||||
IsPublic = table.Column<bool>(type: "bit", nullable: false), |
|
||||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|
||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpRoles", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpSecurityLogs", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
ApplicationName = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true), |
|
||||
Identity = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true), |
|
||||
Action = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true), |
|
||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
|
||||
TenantName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
ClientId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
CorrelationId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
ClientIpAddress = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
BrowserInfo = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|
||||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|
||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpSettings", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
|
||||
Value = table.Column<string>(type: "nvarchar(2048)", maxLength: 2048, nullable: false), |
|
||||
ProviderName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
ProviderKey = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpSettings", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpUsers", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
NormalizedUserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
Name = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
Surname = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
|
||||
Email = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
NormalizedEmail = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
EmailConfirmed = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
PasswordHash = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
|
||||
SecurityStamp = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
IsExternal = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
PhoneNumber = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: true), |
|
||||
PhoneNumberConfirmed = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
TwoFactorEnabled = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
LockoutEnd = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true), |
|
||||
LockoutEnabled = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
AccessFailedCount = table.Column<int>(type: "int", nullable: false, defaultValue: 0), |
|
||||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|
||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|
||||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true), |
|
||||
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|
||||
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpUsers", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpOrganizationUnitRoles", |
|
||||
columns: table => new { |
|
||||
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
OrganizationUnitId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|
||||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpOrganizationUnitRoles", x => new { x.OrganizationUnitId, x.RoleId }); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpOrganizationUnitRoles_AbpOrganizationUnits_OrganizationUnitId", |
|
||||
column: x => x.OrganizationUnitId, |
|
||||
principalTable: "AbpOrganizationUnits", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpOrganizationUnitRoles_AbpRoles_RoleId", |
|
||||
column: x => x.RoleId, |
|
||||
principalTable: "AbpRoles", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpRoleClaims", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
ClaimType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
ClaimValue = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpRoleClaims", x => x.Id); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpRoleClaims_AbpRoles_RoleId", |
|
||||
column: x => x.RoleId, |
|
||||
principalTable: "AbpRoles", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpUserClaims", |
|
||||
columns: table => new { |
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
ClaimType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|
||||
ClaimValue = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpUserClaims", x => x.Id); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserClaims_AbpUsers_UserId", |
|
||||
column: x => x.UserId, |
|
||||
principalTable: "AbpUsers", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpUserLogins", |
|
||||
columns: table => new { |
|
||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
LoginProvider = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
ProviderKey = table.Column<string>(type: "nvarchar(196)", maxLength: 196, nullable: false), |
|
||||
ProviderDisplayName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpUserLogins", x => new { x.UserId, x.LoginProvider }); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserLogins_AbpUsers_UserId", |
|
||||
column: x => x.UserId, |
|
||||
principalTable: "AbpUsers", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpUserOrganizationUnits", |
|
||||
columns: table => new { |
|
||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
OrganizationUnitId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|
||||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpUserOrganizationUnits", x => new { x.OrganizationUnitId, x.UserId }); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserOrganizationUnits_AbpOrganizationUnits_OrganizationUnitId", |
|
||||
column: x => x.OrganizationUnitId, |
|
||||
principalTable: "AbpOrganizationUnits", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserOrganizationUnits_AbpUsers_UserId", |
|
||||
column: x => x.UserId, |
|
||||
principalTable: "AbpUsers", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpUserRoles", |
|
||||
columns: table => new { |
|
||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpUserRoles", x => new { x.UserId, x.RoleId }); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserRoles_AbpRoles_RoleId", |
|
||||
column: x => x.RoleId, |
|
||||
principalTable: "AbpRoles", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserRoles_AbpUsers_UserId", |
|
||||
column: x => x.UserId, |
|
||||
principalTable: "AbpUsers", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "AbpUserTokens", |
|
||||
columns: table => new { |
|
||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|
||||
LoginProvider = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false), |
|
||||
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
|
||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|
||||
Value = table.Column<string>(type: "nvarchar(max)", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_AbpUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_AbpUserTokens_AbpUsers_UserId", |
|
||||
column: x => x.UserId, |
|
||||
principalTable: "AbpUsers", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpLinkUsers_SourceUserId_SourceTenantId_TargetUserId_TargetTenantId", |
|
||||
table: "AbpLinkUsers", |
|
||||
columns: new[] { "SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId" }, |
|
||||
unique: true, |
|
||||
filter: "[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId", |
|
||||
table: "AbpOrganizationUnitRoles", |
|
||||
columns: new[] { "RoleId", "OrganizationUnitId" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpOrganizationUnits_Code", |
|
||||
table: "AbpOrganizationUnits", |
|
||||
column: "Code"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpOrganizationUnits_ParentId", |
|
||||
table: "AbpOrganizationUnits", |
|
||||
column: "ParentId"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpPermissionGrants_Name_ProviderName_ProviderKey", |
|
||||
table: "AbpPermissionGrants", |
|
||||
columns: new[] { "Name", "ProviderName", "ProviderKey" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpRoleClaims_RoleId", |
|
||||
table: "AbpRoleClaims", |
|
||||
column: "RoleId"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpRoles_NormalizedName", |
|
||||
table: "AbpRoles", |
|
||||
column: "NormalizedName"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpSecurityLogs_TenantId_Action", |
|
||||
table: "AbpSecurityLogs", |
|
||||
columns: new[] { "TenantId", "Action" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpSecurityLogs_TenantId_ApplicationName", |
|
||||
table: "AbpSecurityLogs", |
|
||||
columns: new[] { "TenantId", "ApplicationName" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpSecurityLogs_TenantId_Identity", |
|
||||
table: "AbpSecurityLogs", |
|
||||
columns: new[] { "TenantId", "Identity" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpSecurityLogs_TenantId_UserId", |
|
||||
table: "AbpSecurityLogs", |
|
||||
columns: new[] { "TenantId", "UserId" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpSettings_Name_ProviderName_ProviderKey", |
|
||||
table: "AbpSettings", |
|
||||
columns: new[] { "Name", "ProviderName", "ProviderKey" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUserClaims_UserId", |
|
||||
table: "AbpUserClaims", |
|
||||
column: "UserId"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUserLogins_LoginProvider_ProviderKey", |
|
||||
table: "AbpUserLogins", |
|
||||
columns: new[] { "LoginProvider", "ProviderKey" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUserOrganizationUnits_UserId_OrganizationUnitId", |
|
||||
table: "AbpUserOrganizationUnits", |
|
||||
columns: new[] { "UserId", "OrganizationUnitId" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUserRoles_RoleId_UserId", |
|
||||
table: "AbpUserRoles", |
|
||||
columns: new[] { "RoleId", "UserId" }); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUsers_Email", |
|
||||
table: "AbpUsers", |
|
||||
column: "Email"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUsers_NormalizedEmail", |
|
||||
table: "AbpUsers", |
|
||||
column: "NormalizedEmail"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUsers_NormalizedUserName", |
|
||||
table: "AbpUsers", |
|
||||
column: "NormalizedUserName"); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_AbpUsers_UserName", |
|
||||
table: "AbpUsers", |
|
||||
column: "UserName"); |
|
||||
} |
|
||||
|
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
|
||||
{ |
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpClaimTypes"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpLinkUsers"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpOrganizationUnitRoles"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpPermissionGrants"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpRoleClaims"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpSecurityLogs"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpSettings"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpUserClaims"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpUserLogins"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpUserOrganizationUnits"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpUserRoles"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpUserTokens"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpOrganizationUnits"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpRoles"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "AbpUsers"); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,619 @@ |
|||||
|
using System; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
|
||||
|
#nullable disable |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement.DemoApp.Migrations |
||||
|
{ |
||||
|
/// <inheritdoc />
|
||||
|
public partial class Initial : Migration |
||||
|
{ |
||||
|
/// <inheritdoc />
|
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpClaimTypes", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
Required = table.Column<bool>(type: "bit", nullable: false), |
||||
|
IsStatic = table.Column<bool>(type: "bit", nullable: false), |
||||
|
Regex = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true), |
||||
|
RegexDescription = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), |
||||
|
Description = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
||||
|
ValueType = table.Column<int>(type: "int", nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpClaimTypes", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpLinkUsers", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
SourceUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
SourceTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
TargetUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TargetTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpLinkUsers", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpOrganizationUnits", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
ParentId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
Code = table.Column<string>(type: "nvarchar(95)", maxLength: 95, nullable: false), |
||||
|
DisplayName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
EntityVersion = table.Column<int>(type: "int", nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true), |
||||
|
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpOrganizationUnits", x => x.Id); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpOrganizationUnits_AbpOrganizationUnits_ParentId", |
||||
|
column: x => x.ParentId, |
||||
|
principalTable: "AbpOrganizationUnits", |
||||
|
principalColumn: "Id"); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpPermissionGrants", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
ProviderName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false), |
||||
|
ProviderKey = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpPermissionGrants", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpPermissionGroups", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpPermissionGroups", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpPermissions", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
GroupName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
ParentName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), |
||||
|
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
IsEnabled = table.Column<bool>(type: "bit", nullable: false), |
||||
|
MultiTenancySide = table.Column<byte>(type: "tinyint", nullable: false), |
||||
|
Providers = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), |
||||
|
StateCheckers = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpPermissions", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpRoles", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
NormalizedName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
IsDefault = table.Column<bool>(type: "bit", nullable: false), |
||||
|
IsStatic = table.Column<bool>(type: "bit", nullable: false), |
||||
|
IsPublic = table.Column<bool>(type: "bit", nullable: false), |
||||
|
EntityVersion = table.Column<int>(type: "int", nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpRoles", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpSecurityLogs", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
ApplicationName = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true), |
||||
|
Identity = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true), |
||||
|
Action = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true), |
||||
|
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
||||
|
TenantName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
ClientId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
CorrelationId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
ClientIpAddress = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
BrowserInfo = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpSettingDefinitionRecords", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
Description = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
DefaultValue = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
IsVisibleToClients = table.Column<bool>(type: "bit", nullable: false), |
||||
|
Providers = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), |
||||
|
IsInherited = table.Column<bool>(type: "bit", nullable: false), |
||||
|
IsEncrypted = table.Column<bool>(type: "bit", nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpSettingDefinitionRecords", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpSettings", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
Value = table.Column<string>(type: "nvarchar(2048)", maxLength: 2048, nullable: false), |
||||
|
ProviderName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
ProviderKey = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpSettings", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserDelegations", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
SourceUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TargetUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
StartTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
|
EndTime = table.Column<DateTime>(type: "datetime2", nullable: false) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserDelegations", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUsers", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
NormalizedUserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
Surname = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), |
||||
|
Email = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
NormalizedEmail = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
EmailConfirmed = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
PasswordHash = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), |
||||
|
SecurityStamp = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
IsExternal = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
PhoneNumber = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: true), |
||||
|
PhoneNumberConfirmed = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
IsActive = table.Column<bool>(type: "bit", nullable: false), |
||||
|
TwoFactorEnabled = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
LockoutEnd = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true), |
||||
|
LockoutEnabled = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
AccessFailedCount = table.Column<int>(type: "int", nullable: false, defaultValue: 0), |
||||
|
ShouldChangePasswordOnNextLogin = table.Column<bool>(type: "bit", nullable: false), |
||||
|
EntityVersion = table.Column<int>(type: "int", nullable: false), |
||||
|
LastPasswordChangeTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true), |
||||
|
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
|
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true), |
||||
|
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
||||
|
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUsers", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpOrganizationUnitRoles", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
OrganizationUnitId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpOrganizationUnitRoles", x => new { x.OrganizationUnitId, x.RoleId }); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpOrganizationUnitRoles_AbpOrganizationUnits_OrganizationUnitId", |
||||
|
column: x => x.OrganizationUnitId, |
||||
|
principalTable: "AbpOrganizationUnits", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpOrganizationUnitRoles_AbpRoles_RoleId", |
||||
|
column: x => x.RoleId, |
||||
|
principalTable: "AbpRoles", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpRoleClaims", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
ClaimType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
ClaimValue = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpRoleClaims", x => x.Id); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpRoleClaims_AbpRoles_RoleId", |
||||
|
column: x => x.RoleId, |
||||
|
principalTable: "AbpRoles", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserClaims", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
ClaimType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
||||
|
ClaimValue = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserClaims", x => x.Id); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserClaims_AbpUsers_UserId", |
||||
|
column: x => x.UserId, |
||||
|
principalTable: "AbpUsers", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserLogins", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
LoginProvider = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
ProviderKey = table.Column<string>(type: "nvarchar(196)", maxLength: 196, nullable: false), |
||||
|
ProviderDisplayName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserLogins", x => new { x.UserId, x.LoginProvider }); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserLogins_AbpUsers_UserId", |
||||
|
column: x => x.UserId, |
||||
|
principalTable: "AbpUsers", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserOrganizationUnits", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
OrganizationUnitId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserOrganizationUnits", x => new { x.OrganizationUnitId, x.UserId }); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserOrganizationUnits_AbpOrganizationUnits_OrganizationUnitId", |
||||
|
column: x => x.OrganizationUnitId, |
||||
|
principalTable: "AbpOrganizationUnits", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserOrganizationUnits_AbpUsers_UserId", |
||||
|
column: x => x.UserId, |
||||
|
principalTable: "AbpUsers", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserRoles", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserRoles", x => new { x.UserId, x.RoleId }); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserRoles_AbpRoles_RoleId", |
||||
|
column: x => x.RoleId, |
||||
|
principalTable: "AbpRoles", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserRoles_AbpUsers_UserId", |
||||
|
column: x => x.UserId, |
||||
|
principalTable: "AbpUsers", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserTokens", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
|
LoginProvider = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false), |
||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
||||
|
Value = table.Column<string>(type: "nvarchar(max)", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_AbpUserTokens_AbpUsers_UserId", |
||||
|
column: x => x.UserId, |
||||
|
principalTable: "AbpUsers", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpLinkUsers_SourceUserId_SourceTenantId_TargetUserId_TargetTenantId", |
||||
|
table: "AbpLinkUsers", |
||||
|
columns: new[] { "SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId" }, |
||||
|
unique: true, |
||||
|
filter: "[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId", |
||||
|
table: "AbpOrganizationUnitRoles", |
||||
|
columns: new[] { "RoleId", "OrganizationUnitId" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpOrganizationUnits_Code", |
||||
|
table: "AbpOrganizationUnits", |
||||
|
column: "Code"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpOrganizationUnits_ParentId", |
||||
|
table: "AbpOrganizationUnits", |
||||
|
column: "ParentId"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpPermissionGrants_TenantId_Name_ProviderName_ProviderKey", |
||||
|
table: "AbpPermissionGrants", |
||||
|
columns: new[] { "TenantId", "Name", "ProviderName", "ProviderKey" }, |
||||
|
unique: true, |
||||
|
filter: "[TenantId] IS NOT NULL"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpPermissionGroups_Name", |
||||
|
table: "AbpPermissionGroups", |
||||
|
column: "Name", |
||||
|
unique: true); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpPermissions_GroupName", |
||||
|
table: "AbpPermissions", |
||||
|
column: "GroupName"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpPermissions_Name", |
||||
|
table: "AbpPermissions", |
||||
|
column: "Name", |
||||
|
unique: true); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpRoleClaims_RoleId", |
||||
|
table: "AbpRoleClaims", |
||||
|
column: "RoleId"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpRoles_NormalizedName", |
||||
|
table: "AbpRoles", |
||||
|
column: "NormalizedName"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpSecurityLogs_TenantId_Action", |
||||
|
table: "AbpSecurityLogs", |
||||
|
columns: new[] { "TenantId", "Action" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpSecurityLogs_TenantId_ApplicationName", |
||||
|
table: "AbpSecurityLogs", |
||||
|
columns: new[] { "TenantId", "ApplicationName" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpSecurityLogs_TenantId_Identity", |
||||
|
table: "AbpSecurityLogs", |
||||
|
columns: new[] { "TenantId", "Identity" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpSecurityLogs_TenantId_UserId", |
||||
|
table: "AbpSecurityLogs", |
||||
|
columns: new[] { "TenantId", "UserId" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpSettingDefinitionRecords_Name", |
||||
|
table: "AbpSettingDefinitionRecords", |
||||
|
column: "Name", |
||||
|
unique: true); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpSettings_Name_ProviderName_ProviderKey", |
||||
|
table: "AbpSettings", |
||||
|
columns: new[] { "Name", "ProviderName", "ProviderKey" }, |
||||
|
unique: true, |
||||
|
filter: "[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUserClaims_UserId", |
||||
|
table: "AbpUserClaims", |
||||
|
column: "UserId"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUserLogins_LoginProvider_ProviderKey", |
||||
|
table: "AbpUserLogins", |
||||
|
columns: new[] { "LoginProvider", "ProviderKey" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUserOrganizationUnits_UserId_OrganizationUnitId", |
||||
|
table: "AbpUserOrganizationUnits", |
||||
|
columns: new[] { "UserId", "OrganizationUnitId" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUserRoles_RoleId_UserId", |
||||
|
table: "AbpUserRoles", |
||||
|
columns: new[] { "RoleId", "UserId" }); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUsers_Email", |
||||
|
table: "AbpUsers", |
||||
|
column: "Email"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUsers_NormalizedEmail", |
||||
|
table: "AbpUsers", |
||||
|
column: "NormalizedEmail"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUsers_NormalizedUserName", |
||||
|
table: "AbpUsers", |
||||
|
column: "NormalizedUserName"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUsers_UserName", |
||||
|
table: "AbpUsers", |
||||
|
column: "UserName"); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpClaimTypes"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpLinkUsers"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpOrganizationUnitRoles"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpPermissionGrants"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpPermissionGroups"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpPermissions"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpRoleClaims"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpSecurityLogs"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpSettingDefinitionRecords"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpSettings"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserClaims"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserDelegations"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserLogins"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserOrganizationUnits"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserRoles"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserTokens"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpOrganizationUnits"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpRoles"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUsers"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public class SettingDefinitionRecordConsts |
||||
|
{ |
||||
|
public static int MaxNameLength { get; set; } = 128; |
||||
|
|
||||
|
public static int MaxDisplayNameLength { get; set; } = 256; |
||||
|
|
||||
|
public static int MaxDescriptionLength { get; set; } = 512; |
||||
|
|
||||
|
public static int MaxProvidersLength { get; set; } = 128; |
||||
|
} |
||||
@ -0,0 +1,162 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.Immutable; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.Caching.Distributed; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.DistributedLocking; |
||||
|
using Volo.Abp.Settings; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
public class DynamicSettingDefinitionStore : IDynamicSettingDefinitionStore, ITransientDependency |
||||
|
{ |
||||
|
protected ISettingDefinitionRecordRepository SettingRepository { get; } |
||||
|
protected ISettingDefinitionSerializer SettingDefinitionSerializer { get; } |
||||
|
protected IDynamicSettingDefinitionStoreInMemoryCache StoreCache { get; } |
||||
|
protected IDistributedCache DistributedCache { get; } |
||||
|
protected IAbpDistributedLock DistributedLock { get; } |
||||
|
public SettingManagementOptions SettingManagementOptions { get; } |
||||
|
protected AbpDistributedCacheOptions CacheOptions { get; } |
||||
|
|
||||
|
public DynamicSettingDefinitionStore( |
||||
|
ISettingDefinitionRecordRepository textSettingRepository, |
||||
|
ISettingDefinitionSerializer textSettingDefinitionSerializer, |
||||
|
IDynamicSettingDefinitionStoreInMemoryCache storeCache, |
||||
|
IDistributedCache distributedCache, |
||||
|
IOptions<AbpDistributedCacheOptions> cacheOptions, |
||||
|
IOptions<SettingManagementOptions> settingManagementOptions, |
||||
|
IAbpDistributedLock distributedLock) |
||||
|
{ |
||||
|
SettingRepository = textSettingRepository; |
||||
|
SettingDefinitionSerializer = textSettingDefinitionSerializer; |
||||
|
StoreCache = storeCache; |
||||
|
DistributedCache = distributedCache; |
||||
|
DistributedLock = distributedLock; |
||||
|
SettingManagementOptions = settingManagementOptions.Value; |
||||
|
CacheOptions = cacheOptions.Value; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<SettingDefinition> GetAsync(string name) |
||||
|
{ |
||||
|
var setting = await GetOrNullAsync(name); |
||||
|
if (setting == null) |
||||
|
{ |
||||
|
throw new AbpException("Undefined setting: " + name); |
||||
|
} |
||||
|
|
||||
|
return setting; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<SettingDefinition> GetOrNullAsync(string name) |
||||
|
{ |
||||
|
if (!SettingManagementOptions.IsDynamicSettingStoreEnabled) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
using (await StoreCache.SyncSemaphore.LockAsync()) |
||||
|
{ |
||||
|
await EnsureCacheIsUptoDateAsync(); |
||||
|
return StoreCache.GetSettingOrNull(name); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IReadOnlyList<SettingDefinition>> GetAllAsync() |
||||
|
{ |
||||
|
if (!SettingManagementOptions.IsDynamicSettingStoreEnabled) |
||||
|
{ |
||||
|
return Array.Empty<SettingDefinition>(); |
||||
|
} |
||||
|
|
||||
|
using (await StoreCache.SyncSemaphore.LockAsync()) |
||||
|
{ |
||||
|
await EnsureCacheIsUptoDateAsync(); |
||||
|
return StoreCache.GetSettings().ToImmutableList(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task EnsureCacheIsUptoDateAsync() |
||||
|
{ |
||||
|
if (StoreCache.LastCheckTime.HasValue && |
||||
|
DateTime.Now.Subtract(StoreCache.LastCheckTime.Value).TotalSeconds < 30) |
||||
|
{ |
||||
|
/* We get the latest setting with a small delay for optimization */ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var stampInDistributedCache = await GetOrSetStampInDistributedCache(); |
||||
|
|
||||
|
if (stampInDistributedCache == StoreCache.CacheStamp) |
||||
|
{ |
||||
|
StoreCache.LastCheckTime = DateTime.Now; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await UpdateInMemoryStoreCache(); |
||||
|
|
||||
|
StoreCache.CacheStamp = stampInDistributedCache; |
||||
|
StoreCache.LastCheckTime = DateTime.Now; |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task UpdateInMemoryStoreCache() |
||||
|
{ |
||||
|
var settingRecords = await SettingRepository.GetListAsync(); |
||||
|
await StoreCache.FillAsync(settingRecords); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<string> GetOrSetStampInDistributedCache() |
||||
|
{ |
||||
|
var cacheKey = GetCommonStampCacheKey(); |
||||
|
|
||||
|
var stampInDistributedCache = await DistributedCache.GetStringAsync(cacheKey); |
||||
|
if (stampInDistributedCache != null) |
||||
|
{ |
||||
|
return stampInDistributedCache; |
||||
|
} |
||||
|
|
||||
|
await using (var commonLockHandle = await DistributedLock.TryAcquireAsync(GetCommonDistributedLockKey(), TimeSpan.FromMinutes(2))) |
||||
|
{ |
||||
|
if (commonLockHandle == null) |
||||
|
{ |
||||
|
/* This request will fail */ |
||||
|
throw new AbpException( |
||||
|
"Could not acquire distributed lock for setting definition common stamp check!" |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
stampInDistributedCache = await DistributedCache.GetStringAsync(cacheKey); |
||||
|
if (stampInDistributedCache != null) |
||||
|
{ |
||||
|
return stampInDistributedCache; |
||||
|
} |
||||
|
|
||||
|
stampInDistributedCache = Guid.NewGuid().ToString(); |
||||
|
|
||||
|
await DistributedCache.SetStringAsync( |
||||
|
cacheKey, |
||||
|
stampInDistributedCache, |
||||
|
new DistributedCacheEntryOptions |
||||
|
{ |
||||
|
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
|
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return stampInDistributedCache; |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetCommonStampCacheKey() |
||||
|
{ |
||||
|
return $"{CacheOptions.KeyPrefix}_AbpInMemorySettingCacheStamp"; |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetCommonDistributedLockKey() |
||||
|
{ |
||||
|
return $"{CacheOptions.KeyPrefix}_Common_AbpSettingUpdateLock"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,64 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Settings; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public class DynamicSettingDefinitionStoreInMemoryCache : IDynamicSettingDefinitionStoreInMemoryCache, ISingletonDependency |
||||
|
{ |
||||
|
public string CacheStamp { get; set; } |
||||
|
|
||||
|
protected IDictionary<string, SettingDefinition> SettingDefinitions { get; } |
||||
|
protected ILocalizableStringSerializer LocalizableStringSerializer { get; } |
||||
|
|
||||
|
public SemaphoreSlim SyncSemaphore { get; } = new(1, 1); |
||||
|
|
||||
|
public DateTime? LastCheckTime { get; set; } |
||||
|
|
||||
|
public DynamicSettingDefinitionStoreInMemoryCache(ILocalizableStringSerializer localizableStringSerializer) |
||||
|
{ |
||||
|
LocalizableStringSerializer = localizableStringSerializer; |
||||
|
SettingDefinitions = new Dictionary<string, SettingDefinition>(); |
||||
|
} |
||||
|
|
||||
|
public Task FillAsync(List<SettingDefinitionRecord> settingRecords) |
||||
|
{ |
||||
|
SettingDefinitions.Clear(); |
||||
|
|
||||
|
foreach (var record in settingRecords) |
||||
|
{ |
||||
|
var settingDefinition = new SettingDefinition( |
||||
|
record.Name, |
||||
|
record.DefaultValue, |
||||
|
LocalizableStringSerializer.Deserialize(record.DisplayName), |
||||
|
record.Description != null ? LocalizableStringSerializer.Deserialize(record.Description) : null, |
||||
|
record.IsVisibleToClients, |
||||
|
record.IsInherited, |
||||
|
record.IsEncrypted); |
||||
|
|
||||
|
foreach (var property in record.ExtraProperties) |
||||
|
{ |
||||
|
settingDefinition.WithProperty(property.Key, property.Value); |
||||
|
} |
||||
|
|
||||
|
SettingDefinitions[record.Name] = settingDefinition; |
||||
|
} |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public SettingDefinition GetSettingOrNull(string name) |
||||
|
{ |
||||
|
return SettingDefinitions.GetOrDefault(name); |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<SettingDefinition> GetSettings() |
||||
|
{ |
||||
|
return SettingDefinitions.Values.ToList(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Settings; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public interface IDynamicSettingDefinitionStoreInMemoryCache |
||||
|
{ |
||||
|
string CacheStamp { get; set; } |
||||
|
|
||||
|
SemaphoreSlim SyncSemaphore { get; } |
||||
|
|
||||
|
DateTime? LastCheckTime { get; set; } |
||||
|
|
||||
|
Task FillAsync(List<SettingDefinitionRecord> settingRecords); |
||||
|
|
||||
|
SettingDefinition GetSettingOrNull(string name); |
||||
|
|
||||
|
IReadOnlyList<SettingDefinition> GetSettings(); |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public interface ISettingDefinitionRecordRepository : IBasicRepository<SettingDefinitionRecord, Guid> |
||||
|
{ |
||||
|
Task<SettingDefinitionRecord> FindByNameAsync(string name, CancellationToken cancellationToken = default); |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Settings; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public interface ISettingDefinitionSerializer |
||||
|
{ |
||||
|
Task<SettingDefinitionRecord> SerializeAsync(SettingDefinition setting); |
||||
|
|
||||
|
Task<List<SettingDefinitionRecord>> SerializeAsync(IEnumerable<SettingDefinition> settings); |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public interface IStaticSettingSaver |
||||
|
{ |
||||
|
Task SaveAsync(); |
||||
|
} |
||||
@ -0,0 +1,188 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using JetBrains.Annotations; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public class SettingDefinitionRecord : BasicAggregateRoot<Guid>, IHasExtraProperties |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Unique name of the setting.
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
[NotNull] |
||||
|
public string DisplayName { get; set; } |
||||
|
|
||||
|
[CanBeNull] |
||||
|
public string Description { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Default value of the setting.
|
||||
|
/// </summary>
|
||||
|
[CanBeNull] |
||||
|
public string DefaultValue { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Can clients see this setting and it's value.
|
||||
|
/// It maybe dangerous for some settings to be visible to clients (such as an email server password).
|
||||
|
/// Default: false.
|
||||
|
/// </summary>
|
||||
|
public bool IsVisibleToClients { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Comma separated list of provider names.
|
||||
|
/// </summary>
|
||||
|
public string Providers { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Is this setting inherited from parent scopes.
|
||||
|
/// Default: True.
|
||||
|
/// </summary>
|
||||
|
public bool IsInherited { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Is this setting stored as encrypted in the data source.
|
||||
|
/// Default: False.
|
||||
|
/// </summary>
|
||||
|
public bool IsEncrypted { get; set; } |
||||
|
|
||||
|
public ExtraPropertyDictionary ExtraProperties { get; protected set; } |
||||
|
|
||||
|
public SettingDefinitionRecord() |
||||
|
{ |
||||
|
ExtraProperties = new ExtraPropertyDictionary(); |
||||
|
this.SetDefaultsForExtraProperties(); |
||||
|
} |
||||
|
|
||||
|
public SettingDefinitionRecord( |
||||
|
Guid id, |
||||
|
string name, |
||||
|
string displayName, |
||||
|
string description, |
||||
|
string defaultValue, |
||||
|
bool isVisibleToClients, |
||||
|
string providers, |
||||
|
bool isInherited, |
||||
|
bool isEncrypted) |
||||
|
: base(id) |
||||
|
{ |
||||
|
Name = Check.NotNullOrWhiteSpace(name, nameof(name), SettingDefinitionRecordConsts.MaxNameLength); |
||||
|
DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), SettingDefinitionRecordConsts.MaxDisplayNameLength); |
||||
|
Description = Check.Length(description, nameof(description), SettingDefinitionRecordConsts.MaxDescriptionLength); |
||||
|
DefaultValue = defaultValue; |
||||
|
IsVisibleToClients = isVisibleToClients; |
||||
|
Providers = Check.Length(providers, nameof(providers), SettingDefinitionRecordConsts.MaxProvidersLength); |
||||
|
IsInherited = isInherited; |
||||
|
IsEncrypted = isEncrypted; |
||||
|
ExtraProperties = new ExtraPropertyDictionary(); |
||||
|
this.SetDefaultsForExtraProperties(); |
||||
|
} |
||||
|
|
||||
|
public bool HasSameData(SettingDefinitionRecord otherRecord) |
||||
|
{ |
||||
|
if (Name != otherRecord.Name) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (DisplayName != otherRecord.DisplayName) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (Description != otherRecord.Description) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (DefaultValue != otherRecord.DefaultValue) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (IsVisibleToClients != otherRecord.IsVisibleToClients) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (Providers != otherRecord.Providers) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (IsInherited != otherRecord.IsInherited) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (IsEncrypted != otherRecord.IsEncrypted) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (!this.HasSameExtraProperties(otherRecord)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public void Patch(SettingDefinitionRecord otherRecord) |
||||
|
{ |
||||
|
if (Name != otherRecord.Name) |
||||
|
{ |
||||
|
Name = otherRecord.Name; |
||||
|
} |
||||
|
|
||||
|
if (DisplayName != otherRecord.DisplayName) |
||||
|
{ |
||||
|
DisplayName = otherRecord.DisplayName; |
||||
|
} |
||||
|
|
||||
|
if (Description != otherRecord.Description) |
||||
|
{ |
||||
|
Description = otherRecord.Description; |
||||
|
} |
||||
|
|
||||
|
if (DefaultValue != otherRecord.DefaultValue) |
||||
|
{ |
||||
|
DefaultValue = otherRecord.DefaultValue; |
||||
|
} |
||||
|
|
||||
|
if (IsVisibleToClients != otherRecord.IsVisibleToClients) |
||||
|
{ |
||||
|
IsVisibleToClients = otherRecord.IsVisibleToClients; |
||||
|
} |
||||
|
|
||||
|
if (Providers != otherRecord.Providers) |
||||
|
{ |
||||
|
Providers = otherRecord.Providers; |
||||
|
} |
||||
|
|
||||
|
if (IsInherited != otherRecord.IsInherited) |
||||
|
{ |
||||
|
IsInherited = otherRecord.IsInherited; |
||||
|
} |
||||
|
|
||||
|
if (IsEncrypted != otherRecord.IsEncrypted) |
||||
|
{ |
||||
|
IsEncrypted = otherRecord.IsEncrypted; |
||||
|
} |
||||
|
|
||||
|
if (!this.HasSameExtraProperties(otherRecord)) |
||||
|
{ |
||||
|
this.ExtraProperties.Clear(); |
||||
|
|
||||
|
foreach (var property in otherRecord.ExtraProperties) |
||||
|
{ |
||||
|
this.ExtraProperties.Add(property.Key, property.Value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Settings; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public class SettingDefinitionSerializer : ISettingDefinitionSerializer, ITransientDependency |
||||
|
{ |
||||
|
protected IGuidGenerator GuidGenerator { get; } |
||||
|
protected ILocalizableStringSerializer LocalizableStringSerializer { get; } |
||||
|
|
||||
|
public SettingDefinitionSerializer(IGuidGenerator guidGenerator, ILocalizableStringSerializer localizableStringSerializer) |
||||
|
{ |
||||
|
GuidGenerator = guidGenerator; |
||||
|
LocalizableStringSerializer = localizableStringSerializer; |
||||
|
} |
||||
|
|
||||
|
public virtual Task<SettingDefinitionRecord> SerializeAsync(SettingDefinition setting) |
||||
|
{ |
||||
|
using (CultureHelper.Use(CultureInfo.InvariantCulture)) |
||||
|
{ |
||||
|
var record = new SettingDefinitionRecord( |
||||
|
GuidGenerator.Create(), |
||||
|
setting.Name, |
||||
|
LocalizableStringSerializer.Serialize(setting.DisplayName), |
||||
|
LocalizableStringSerializer.Serialize(setting.Description), |
||||
|
setting.DefaultValue, |
||||
|
setting.IsVisibleToClients, |
||||
|
SerializeProviders(setting.Providers), |
||||
|
setting.IsInherited, |
||||
|
setting.IsEncrypted); |
||||
|
|
||||
|
foreach (var property in setting.Properties) |
||||
|
{ |
||||
|
record.SetProperty(property.Key, property.Value); |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(record); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public virtual Task<List<SettingDefinitionRecord>> SerializeAsync(IEnumerable<SettingDefinition> settings) |
||||
|
{ |
||||
|
return Task.FromResult(settings.Select(SerializeAsync).Select(t => t.Result).ToList()); |
||||
|
} |
||||
|
|
||||
|
protected virtual string SerializeProviders(ICollection<string> providers) |
||||
|
{ |
||||
|
return providers.Any() |
||||
|
? providers.JoinAsString(",") |
||||
|
: null; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,240 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Text.Json; |
||||
|
using System.Text.Json.Serialization.Metadata; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.Caching.Distributed; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.DistributedLocking; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.Json.SystemTextJson.Modifiers; |
||||
|
using Volo.Abp.Settings; |
||||
|
using Volo.Abp.Threading; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement; |
||||
|
|
||||
|
public class StaticSettingSaver : IStaticSettingSaver, ITransientDependency |
||||
|
{ |
||||
|
protected IStaticSettingDefinitionStore StaticStore { get; } |
||||
|
protected ISettingDefinitionRecordRepository SettingRepository { get; } |
||||
|
protected ISettingDefinitionSerializer SettingSerializer { get; } |
||||
|
protected IDistributedCache Cache { get; } |
||||
|
protected IApplicationInfoAccessor ApplicationInfoAccessor { get; } |
||||
|
protected IAbpDistributedLock DistributedLock { get; } |
||||
|
protected AbpSettingOptions SettingOptions { get; } |
||||
|
protected ICancellationTokenProvider CancellationTokenProvider { get; } |
||||
|
protected AbpDistributedCacheOptions CacheOptions { get; } |
||||
|
protected IUnitOfWorkManager UnitOfWorkManager { get; } |
||||
|
protected IGuidGenerator GuidGenerator { get; } |
||||
|
|
||||
|
public StaticSettingSaver( |
||||
|
IStaticSettingDefinitionStore staticStore, |
||||
|
ISettingDefinitionRecordRepository settingRepository, |
||||
|
ISettingDefinitionSerializer settingSerializer, |
||||
|
IDistributedCache cache, |
||||
|
IOptions<AbpDistributedCacheOptions> cacheOptions, |
||||
|
IApplicationInfoAccessor applicationInfoAccessor, |
||||
|
IAbpDistributedLock distributedLock, |
||||
|
IOptions<AbpSettingOptions> settingOptions, |
||||
|
ICancellationTokenProvider cancellationTokenProvider, |
||||
|
IUnitOfWorkManager unitOfWorkManager, |
||||
|
IGuidGenerator guidGenerator) |
||||
|
{ |
||||
|
StaticStore = staticStore; |
||||
|
SettingRepository = settingRepository; |
||||
|
SettingSerializer = settingSerializer; |
||||
|
Cache = cache; |
||||
|
ApplicationInfoAccessor = applicationInfoAccessor; |
||||
|
DistributedLock = distributedLock; |
||||
|
CancellationTokenProvider = cancellationTokenProvider; |
||||
|
SettingOptions = settingOptions.Value; |
||||
|
CacheOptions = cacheOptions.Value; |
||||
|
UnitOfWorkManager = unitOfWorkManager; |
||||
|
GuidGenerator = guidGenerator; |
||||
|
} |
||||
|
|
||||
|
[UnitOfWork] |
||||
|
public async Task SaveAsync() |
||||
|
{ |
||||
|
await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( |
||||
|
GetApplicationDistributedLockKey() |
||||
|
); |
||||
|
|
||||
|
if (applicationLockHandle == null) |
||||
|
{ |
||||
|
/* Another application instance is already doing it */ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var cacheKey = GetApplicationHashCacheKey(); |
||||
|
var cachedHash = await Cache.GetStringAsync(cacheKey, CancellationTokenProvider.Token); |
||||
|
|
||||
|
var settingRecords = await SettingSerializer.SerializeAsync(await StaticStore.GetAllAsync()); |
||||
|
var currentHash = CalculateHash(settingRecords, SettingOptions.DeletedSettings); |
||||
|
|
||||
|
if (cachedHash == currentHash) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await using (var commonLockHandle = await DistributedLock.TryAcquireAsync( |
||||
|
GetCommonDistributedLockKey(), |
||||
|
TimeSpan.FromMinutes(5))) |
||||
|
{ |
||||
|
if (commonLockHandle == null) |
||||
|
{ |
||||
|
/* It will re-try */ |
||||
|
throw new AbpException("Could not acquire distributed lock for saving static Settings!"); |
||||
|
} |
||||
|
|
||||
|
using (var unitOfWork = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true)) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
var hasChangesInSettings = await UpdateChangedSettingsAsync(settingRecords); |
||||
|
|
||||
|
if (hasChangesInSettings) |
||||
|
{ |
||||
|
await Cache.SetStringAsync( |
||||
|
GetCommonStampCacheKey(), |
||||
|
Guid.NewGuid().ToString(), |
||||
|
new DistributedCacheEntryOptions { |
||||
|
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
|
||||
|
}, |
||||
|
CancellationTokenProvider.Token |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
await unitOfWork.RollbackAsync(); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
/* ignored */ |
||||
|
} |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
|
||||
|
await unitOfWork.CompleteAsync(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
await Cache.SetStringAsync( |
||||
|
cacheKey, |
||||
|
currentHash, |
||||
|
new DistributedCacheEntryOptions { |
||||
|
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
|
||||
|
}, |
||||
|
CancellationTokenProvider.Token |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
private async Task<bool> UpdateChangedSettingsAsync(List<SettingDefinitionRecord> SettingRecords) |
||||
|
{ |
||||
|
var newRecords = new List<SettingDefinitionRecord>(); |
||||
|
var changedRecords = new List<SettingDefinitionRecord>(); |
||||
|
|
||||
|
var settingRecordsInDatabase = (await SettingRepository.GetListAsync()).ToDictionary(x => x.Name); |
||||
|
|
||||
|
foreach (var record in SettingRecords) |
||||
|
{ |
||||
|
var settingRecordInDatabase = settingRecordsInDatabase.GetOrDefault(record.Name); |
||||
|
if (settingRecordInDatabase == null) |
||||
|
{ |
||||
|
/* New group */ |
||||
|
newRecords.Add(record); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (record.HasSameData(settingRecordInDatabase)) |
||||
|
{ |
||||
|
/* Not changed */ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
/* Changed */ |
||||
|
settingRecordInDatabase.Patch(record); |
||||
|
changedRecords.Add(settingRecordInDatabase); |
||||
|
} |
||||
|
|
||||
|
/* Deleted */ |
||||
|
var deletedRecords = new List<SettingDefinitionRecord>(); |
||||
|
|
||||
|
if (SettingOptions.DeletedSettings.Any()) |
||||
|
{ |
||||
|
deletedRecords.AddRange(settingRecordsInDatabase.Values.Where(x => SettingOptions.DeletedSettings.Contains(x.Name))); |
||||
|
} |
||||
|
|
||||
|
if (newRecords.Any()) |
||||
|
{ |
||||
|
await SettingRepository.InsertManyAsync(newRecords); |
||||
|
} |
||||
|
|
||||
|
if (changedRecords.Any()) |
||||
|
{ |
||||
|
await SettingRepository.UpdateManyAsync(changedRecords); |
||||
|
} |
||||
|
|
||||
|
if (deletedRecords.Any()) |
||||
|
{ |
||||
|
await SettingRepository.DeleteManyAsync(deletedRecords); |
||||
|
} |
||||
|
|
||||
|
return newRecords.Any() || changedRecords.Any() || deletedRecords.Any(); |
||||
|
} |
||||
|
|
||||
|
private string GetApplicationDistributedLockKey() |
||||
|
{ |
||||
|
return $"{CacheOptions.KeyPrefix}_{ApplicationInfoAccessor.ApplicationName}_AbpSettingUpdateLock"; |
||||
|
} |
||||
|
|
||||
|
private string GetCommonDistributedLockKey() |
||||
|
{ |
||||
|
return $"{CacheOptions.KeyPrefix}_Common_AbpSettingUpdateLock"; |
||||
|
} |
||||
|
|
||||
|
private string GetApplicationHashCacheKey() |
||||
|
{ |
||||
|
return $"{CacheOptions.KeyPrefix}_{ApplicationInfoAccessor.ApplicationName}_AbpSettingsHash"; |
||||
|
} |
||||
|
|
||||
|
private string GetCommonStampCacheKey() |
||||
|
{ |
||||
|
return $"{CacheOptions.KeyPrefix}_AbpInMemorySettingCacheStamp"; |
||||
|
} |
||||
|
|
||||
|
private string CalculateHash(List<SettingDefinitionRecord> settingRecords, IEnumerable<string> deletedSettings) |
||||
|
{ |
||||
|
var jsonSerializerOptions = new JsonSerializerOptions |
||||
|
{ |
||||
|
TypeInfoResolver = new DefaultJsonTypeInfoResolver |
||||
|
{ |
||||
|
Modifiers = |
||||
|
{ |
||||
|
new AbpIgnorePropertiesModifiers<SettingDefinitionRecord, Guid>().CreateModifyAction(x => x.Id), |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var stringBuilder = new StringBuilder(); |
||||
|
|
||||
|
stringBuilder.Append("SettingRecords:"); |
||||
|
stringBuilder.AppendLine(JsonSerializer.Serialize(settingRecords, jsonSerializerOptions)); |
||||
|
|
||||
|
stringBuilder.Append("DeletedSetting:"); |
||||
|
stringBuilder.Append(deletedSettings.JoinAsString(",")); |
||||
|
|
||||
|
return stringBuilder |
||||
|
.ToString() |
||||
|
.ToMd5(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement.EntityFrameworkCore; |
||||
|
|
||||
|
public class EfCoreSettingDefinitionRecordRepository : EfCoreRepository<ISettingManagementDbContext, SettingDefinitionRecord, Guid>, ISettingDefinitionRecordRepository |
||||
|
{ |
||||
|
public EfCoreSettingDefinitionRecordRepository(IDbContextProvider<ISettingManagementDbContext> dbContextProvider) |
||||
|
: base(dbContextProvider) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<SettingDefinitionRecord> FindByNameAsync(string name, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetDbSetAsync()) |
||||
|
.OrderBy(x => x.Id) |
||||
|
.FirstOrDefaultAsync(x => x.Name == name, cancellationToken); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using MongoDB.Driver.Linq; |
||||
|
using Volo.Abp.Domain.Repositories.MongoDB; |
||||
|
using Volo.Abp.MongoDB; |
||||
|
|
||||
|
namespace Volo.Abp.SettingManagement.MongoDB; |
||||
|
|
||||
|
public class MongoSettingDefinitionRecordRepository : MongoDbRepository<ISettingManagementMongoDbContext, SettingDefinitionRecord, Guid>, ISettingDefinitionRecordRepository |
||||
|
{ |
||||
|
public MongoSettingDefinitionRecordRepository(IMongoDbContextProvider<ISettingManagementMongoDbContext> dbContextProvider) |
||||
|
: base(dbContextProvider) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<SettingDefinitionRecord> FindByNameAsync(string name, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetMongoQueryableAsync(cancellationToken)) |
||||
|
.OrderBy(x => x.Id) |
||||
|
.FirstOrDefaultAsync(s => s.Name == name, GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue