refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj, namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated. ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated. SQL roles/logins, LDAP domains, CLI command name, and CLI config dir (~/.scadalink → ~/.scadabridge) also renamed. Build green; 5 Host.Tests fail awaiting SQL login rename in next commit. Pre-existing StaleTagMonitor timing flakes unchanged. Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
Generated
+1222
File diff suppressed because it is too large
Load Diff
+943
@@ -0,0 +1,943 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialSchema : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ApiKeys",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
KeyValue = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "bit", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ApiKeys", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ApiMethods",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Script = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
ApprovedApiKeyIds = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ParameterDefinitions = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ReturnDefinition = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
TimeoutSeconds = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ApiMethods", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AuditLogEntries",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
User = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Action = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
EntityType = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
EntityId = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
EntityName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
AfterStateJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Timestamp = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AuditLogEntries", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DatabaseConnectionDefinitions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
ConnectionString = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: false),
|
||||
MaxRetries = table.Column<int>(type: "int", nullable: false),
|
||||
RetryDelay = table.Column<TimeSpan>(type: "time", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DatabaseConnectionDefinitions", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DataConnections",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Protocol = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
Configuration = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DataConnections", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DataProtectionKeys",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
FriendlyName = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Xml = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DataProtectionKeys", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ExternalSystemDefinitions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
EndpointUrl = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: false),
|
||||
AuthType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
AuthConfiguration = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
MaxRetries = table.Column<int>(type: "int", nullable: false),
|
||||
RetryDelay = table.Column<TimeSpan>(type: "time", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ExternalSystemDefinitions", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LdapGroupMappings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
LdapGroupName = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
|
||||
Role = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LdapGroupMappings", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "NotificationLists",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_NotificationLists", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SharedScripts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Code = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
ParameterDefinitions = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ReturnDefinition = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SharedScripts", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Sites",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
SiteIdentifier = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
Description = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Sites", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SmtpConfigurations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Host = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
|
||||
Port = table.Column<int>(type: "int", nullable: false),
|
||||
AuthType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
Credentials = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
TlsMode = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
|
||||
FromAddress = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
|
||||
ConnectionTimeoutSeconds = table.Column<int>(type: "int", nullable: false),
|
||||
MaxConcurrentConnections = table.Column<int>(type: "int", nullable: false),
|
||||
MaxRetries = table.Column<int>(type: "int", nullable: false),
|
||||
RetryDelay = table.Column<TimeSpan>(type: "time", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SmtpConfigurations", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SystemArtifactDeploymentRecords",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
ArtifactType = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
DeployedBy = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
DeployedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||
PerSiteStatus = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SystemArtifactDeploymentRecords", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Templates",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Description = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
|
||||
ParentTemplateId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Templates", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Templates_Templates_ParentTemplateId",
|
||||
column: x => x.ParentTemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ExternalSystemMethods",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
ExternalSystemDefinitionId = table.Column<int>(type: "int", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
HttpMethod = table.Column<string>(type: "nvarchar(10)", maxLength: 10, nullable: false),
|
||||
Path = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: false),
|
||||
ParameterDefinitions = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ReturnDefinition = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ExternalSystemMethods", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExternalSystemMethods_ExternalSystemDefinitions_ExternalSystemDefinitionId",
|
||||
column: x => x.ExternalSystemDefinitionId,
|
||||
principalTable: "ExternalSystemDefinitions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "NotificationRecipients",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
NotificationListId = table.Column<int>(type: "int", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
EmailAddress = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_NotificationRecipients", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_NotificationRecipients_NotificationLists_NotificationListId",
|
||||
column: x => x.NotificationListId,
|
||||
principalTable: "NotificationLists",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Areas",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
SiteId = table.Column<int>(type: "int", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
ParentAreaId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Areas", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Areas_Areas_ParentAreaId",
|
||||
column: x => x.ParentAreaId,
|
||||
principalTable: "Areas",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Areas_Sites_SiteId",
|
||||
column: x => x.SiteId,
|
||||
principalTable: "Sites",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SiteDataConnectionAssignments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
SiteId = table.Column<int>(type: "int", nullable: false),
|
||||
DataConnectionId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SiteDataConnectionAssignments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SiteDataConnectionAssignments_DataConnections_DataConnectionId",
|
||||
column: x => x.DataConnectionId,
|
||||
principalTable: "DataConnections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_SiteDataConnectionAssignments_Sites_SiteId",
|
||||
column: x => x.SiteId,
|
||||
principalTable: "Sites",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SiteScopeRules",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
LdapGroupMappingId = table.Column<int>(type: "int", nullable: false),
|
||||
SiteId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SiteScopeRules", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SiteScopeRules_LdapGroupMappings_LdapGroupMappingId",
|
||||
column: x => x.LdapGroupMappingId,
|
||||
principalTable: "LdapGroupMappings",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_SiteScopeRules_Sites_SiteId",
|
||||
column: x => x.SiteId,
|
||||
principalTable: "Sites",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TemplateAlarms",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TemplateId = table.Column<int>(type: "int", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Description = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
|
||||
PriorityLevel = table.Column<int>(type: "int", nullable: false),
|
||||
IsLocked = table.Column<bool>(type: "bit", nullable: false),
|
||||
TriggerType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
TriggerConfiguration = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
OnTriggerScriptId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TemplateAlarms", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TemplateAlarms_Templates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TemplateAttributes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TemplateId = table.Column<int>(type: "int", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Value = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
DataType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
IsLocked = table.Column<bool>(type: "bit", nullable: false),
|
||||
Description = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
|
||||
DataSourceReference = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TemplateAttributes", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TemplateAttributes_Templates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TemplateCompositions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TemplateId = table.Column<int>(type: "int", nullable: false),
|
||||
ComposedTemplateId = table.Column<int>(type: "int", nullable: false),
|
||||
InstanceName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TemplateCompositions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TemplateCompositions_Templates_ComposedTemplateId",
|
||||
column: x => x.ComposedTemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_TemplateCompositions_Templates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TemplateScripts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TemplateId = table.Column<int>(type: "int", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
IsLocked = table.Column<bool>(type: "bit", nullable: false),
|
||||
Code = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
TriggerType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
|
||||
TriggerConfiguration = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ParameterDefinitions = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ReturnDefinition = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
MinTimeBetweenRuns = table.Column<TimeSpan>(type: "time", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TemplateScripts", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TemplateScripts_Templates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Instances",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TemplateId = table.Column<int>(type: "int", nullable: false),
|
||||
SiteId = table.Column<int>(type: "int", nullable: false),
|
||||
AreaId = table.Column<int>(type: "int", nullable: true),
|
||||
UniqueName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
State = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Instances", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Instances_Areas_AreaId",
|
||||
column: x => x.AreaId,
|
||||
principalTable: "Areas",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_Instances_Sites_SiteId",
|
||||
column: x => x.SiteId,
|
||||
principalTable: "Sites",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Instances_Templates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "Templates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DeployedConfigSnapshots",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
InstanceId = table.Column<int>(type: "int", nullable: false),
|
||||
DeploymentId = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
RevisionHash = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
ConfigurationJson = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
DeployedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DeployedConfigSnapshots", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DeployedConfigSnapshots_Instances_InstanceId",
|
||||
column: x => x.InstanceId,
|
||||
principalTable: "Instances",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DeploymentRecords",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
InstanceId = table.Column<int>(type: "int", nullable: false),
|
||||
Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
DeploymentId = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
RevisionHash = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
|
||||
DeployedBy = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
DeployedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||
CompletedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
||||
ErrorMessage = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DeploymentRecords", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DeploymentRecords_Instances_InstanceId",
|
||||
column: x => x.InstanceId,
|
||||
principalTable: "Instances",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InstanceAttributeOverrides",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
InstanceId = table.Column<int>(type: "int", nullable: false),
|
||||
AttributeName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
OverrideValue = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InstanceAttributeOverrides", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InstanceAttributeOverrides_Instances_InstanceId",
|
||||
column: x => x.InstanceId,
|
||||
principalTable: "Instances",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InstanceConnectionBindings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
InstanceId = table.Column<int>(type: "int", nullable: false),
|
||||
AttributeName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
DataConnectionId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InstanceConnectionBindings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InstanceConnectionBindings_DataConnections_DataConnectionId",
|
||||
column: x => x.DataConnectionId,
|
||||
principalTable: "DataConnections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_InstanceConnectionBindings_Instances_InstanceId",
|
||||
column: x => x.InstanceId,
|
||||
principalTable: "Instances",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "LdapGroupMappings",
|
||||
columns: new[] { "Id", "LdapGroupName", "Role" },
|
||||
values: new object[] { 1, "SCADA-Admins", "Admin" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ApiKeys_KeyValue",
|
||||
table: "ApiKeys",
|
||||
column: "KeyValue",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ApiKeys_Name",
|
||||
table: "ApiKeys",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ApiMethods_Name",
|
||||
table: "ApiMethods",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Areas_ParentAreaId",
|
||||
table: "Areas",
|
||||
column: "ParentAreaId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Areas_SiteId_ParentAreaId_Name",
|
||||
table: "Areas",
|
||||
columns: new[] { "SiteId", "ParentAreaId", "Name" },
|
||||
unique: true,
|
||||
filter: "[ParentAreaId] IS NOT NULL");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogEntries_Action",
|
||||
table: "AuditLogEntries",
|
||||
column: "Action");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogEntries_EntityId",
|
||||
table: "AuditLogEntries",
|
||||
column: "EntityId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogEntries_EntityType",
|
||||
table: "AuditLogEntries",
|
||||
column: "EntityType");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogEntries_Timestamp",
|
||||
table: "AuditLogEntries",
|
||||
column: "Timestamp");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogEntries_User",
|
||||
table: "AuditLogEntries",
|
||||
column: "User");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DatabaseConnectionDefinitions_Name",
|
||||
table: "DatabaseConnectionDefinitions",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataConnections_Name",
|
||||
table: "DataConnections",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeployedConfigSnapshots_DeploymentId",
|
||||
table: "DeployedConfigSnapshots",
|
||||
column: "DeploymentId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeployedConfigSnapshots_InstanceId",
|
||||
table: "DeployedConfigSnapshots",
|
||||
column: "InstanceId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeploymentRecords_DeployedAt",
|
||||
table: "DeploymentRecords",
|
||||
column: "DeployedAt");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeploymentRecords_DeploymentId",
|
||||
table: "DeploymentRecords",
|
||||
column: "DeploymentId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeploymentRecords_InstanceId",
|
||||
table: "DeploymentRecords",
|
||||
column: "InstanceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExternalSystemDefinitions_Name",
|
||||
table: "ExternalSystemDefinitions",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExternalSystemMethods_ExternalSystemDefinitionId_Name",
|
||||
table: "ExternalSystemMethods",
|
||||
columns: new[] { "ExternalSystemDefinitionId", "Name" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InstanceAttributeOverrides_InstanceId_AttributeName",
|
||||
table: "InstanceAttributeOverrides",
|
||||
columns: new[] { "InstanceId", "AttributeName" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InstanceConnectionBindings_DataConnectionId",
|
||||
table: "InstanceConnectionBindings",
|
||||
column: "DataConnectionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InstanceConnectionBindings_InstanceId_AttributeName",
|
||||
table: "InstanceConnectionBindings",
|
||||
columns: new[] { "InstanceId", "AttributeName" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Instances_AreaId",
|
||||
table: "Instances",
|
||||
column: "AreaId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Instances_SiteId_UniqueName",
|
||||
table: "Instances",
|
||||
columns: new[] { "SiteId", "UniqueName" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Instances_TemplateId",
|
||||
table: "Instances",
|
||||
column: "TemplateId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_LdapGroupMappings_LdapGroupName",
|
||||
table: "LdapGroupMappings",
|
||||
column: "LdapGroupName",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NotificationLists_Name",
|
||||
table: "NotificationLists",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NotificationRecipients_NotificationListId",
|
||||
table: "NotificationRecipients",
|
||||
column: "NotificationListId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SharedScripts_Name",
|
||||
table: "SharedScripts",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteDataConnectionAssignments_DataConnectionId",
|
||||
table: "SiteDataConnectionAssignments",
|
||||
column: "DataConnectionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteDataConnectionAssignments_SiteId_DataConnectionId",
|
||||
table: "SiteDataConnectionAssignments",
|
||||
columns: new[] { "SiteId", "DataConnectionId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Sites_Name",
|
||||
table: "Sites",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Sites_SiteIdentifier",
|
||||
table: "Sites",
|
||||
column: "SiteIdentifier",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteScopeRules_LdapGroupMappingId_SiteId",
|
||||
table: "SiteScopeRules",
|
||||
columns: new[] { "LdapGroupMappingId", "SiteId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteScopeRules_SiteId",
|
||||
table: "SiteScopeRules",
|
||||
column: "SiteId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SystemArtifactDeploymentRecords_DeployedAt",
|
||||
table: "SystemArtifactDeploymentRecords",
|
||||
column: "DeployedAt");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TemplateAlarms_TemplateId_Name",
|
||||
table: "TemplateAlarms",
|
||||
columns: new[] { "TemplateId", "Name" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TemplateAttributes_TemplateId_Name",
|
||||
table: "TemplateAttributes",
|
||||
columns: new[] { "TemplateId", "Name" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TemplateCompositions_ComposedTemplateId",
|
||||
table: "TemplateCompositions",
|
||||
column: "ComposedTemplateId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TemplateCompositions_TemplateId_InstanceName",
|
||||
table: "TemplateCompositions",
|
||||
columns: new[] { "TemplateId", "InstanceName" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_Name",
|
||||
table: "Templates",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_ParentTemplateId",
|
||||
table: "Templates",
|
||||
column: "ParentTemplateId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TemplateScripts_TemplateId_Name",
|
||||
table: "TemplateScripts",
|
||||
columns: new[] { "TemplateId", "Name" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ApiKeys");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ApiMethods");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AuditLogEntries");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DatabaseConnectionDefinitions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DataProtectionKeys");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DeployedConfigSnapshots");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DeploymentRecords");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ExternalSystemMethods");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "InstanceAttributeOverrides");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "InstanceConnectionBindings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "NotificationRecipients");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SharedScripts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SiteDataConnectionAssignments");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SiteScopeRules");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SmtpConfigurations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SystemArtifactDeploymentRecords");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TemplateAlarms");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TemplateAttributes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TemplateCompositions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TemplateScripts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ExternalSystemDefinitions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Instances");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "NotificationLists");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DataConnections");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "LdapGroupMappings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Areas");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Templates");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Sites");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1248
File diff suppressed because it is too large
Load Diff
+42
@@ -0,0 +1,42 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddSiteNodeAddresses : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "NodeAAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(500)",
|
||||
maxLength: 500,
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "NodeBAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(500)",
|
||||
maxLength: 500,
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "NodeAAddress",
|
||||
table: "Sites");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "NodeBAddress",
|
||||
table: "Sites");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1254
File diff suppressed because it is too large
Load Diff
+38
@@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddGrpcNodeAddresses : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "GrpcNodeAAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "GrpcNodeBAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "GrpcNodeAAddress",
|
||||
table: "Sites");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "GrpcNodeBAddress",
|
||||
table: "Sites");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1227
File diff suppressed because it is too large
Load Diff
+184
@@ -0,0 +1,184 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddSiteIdToDataConnections : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Step 1: Drop old unique index on Name (allows duplicate names across sites)
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_DataConnections_Name",
|
||||
table: "DataConnections");
|
||||
|
||||
// Step 2: Add nullable SiteId column
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "SiteId",
|
||||
table: "DataConnections",
|
||||
type: "int",
|
||||
nullable: true);
|
||||
|
||||
// Step 3: Migrate data from SiteDataConnectionAssignments
|
||||
migrationBuilder.Sql(@"
|
||||
-- Phase A: Assign the first site to each existing DataConnection
|
||||
UPDATE dc
|
||||
SET dc.SiteId = a.SiteId
|
||||
FROM DataConnections dc
|
||||
INNER JOIN (
|
||||
SELECT DataConnectionId, MIN(SiteId) AS SiteId
|
||||
FROM SiteDataConnectionAssignments
|
||||
GROUP BY DataConnectionId
|
||||
) a ON dc.Id = a.DataConnectionId
|
||||
WHERE dc.SiteId IS NULL;
|
||||
|
||||
-- Phase B: For connections assigned to additional sites, create copies
|
||||
-- and update InstanceConnectionBindings to point to the new copy
|
||||
DECLARE @AssignSiteId INT, @AssignConnId INT, @NewConnId INT;
|
||||
DECLARE @OrigName NVARCHAR(200), @OrigProtocol NVARCHAR(50), @OrigConfig NVARCHAR(4000);
|
||||
|
||||
DECLARE assignment_cursor CURSOR FOR
|
||||
SELECT a.SiteId, a.DataConnectionId
|
||||
FROM SiteDataConnectionAssignments a
|
||||
INNER JOIN DataConnections dc ON a.DataConnectionId = dc.Id
|
||||
WHERE dc.SiteId <> a.SiteId;
|
||||
|
||||
OPEN assignment_cursor;
|
||||
FETCH NEXT FROM assignment_cursor INTO @AssignSiteId, @AssignConnId;
|
||||
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
SELECT @OrigName = Name, @OrigProtocol = Protocol, @OrigConfig = Configuration
|
||||
FROM DataConnections WHERE Id = @AssignConnId;
|
||||
|
||||
INSERT INTO DataConnections (SiteId, Name, Protocol, Configuration)
|
||||
VALUES (@AssignSiteId, @OrigName, @OrigProtocol, @OrigConfig);
|
||||
|
||||
SET @NewConnId = SCOPE_IDENTITY();
|
||||
|
||||
-- Update bindings for instances on this site to point to the new connection
|
||||
UPDATE icb
|
||||
SET icb.DataConnectionId = @NewConnId
|
||||
FROM InstanceConnectionBindings icb
|
||||
INNER JOIN Instances i ON icb.InstanceId = i.Id
|
||||
WHERE icb.DataConnectionId = @AssignConnId
|
||||
AND i.SiteId = @AssignSiteId;
|
||||
|
||||
FETCH NEXT FROM assignment_cursor INTO @AssignSiteId, @AssignConnId;
|
||||
END
|
||||
|
||||
CLOSE assignment_cursor;
|
||||
DEALLOCATE assignment_cursor;
|
||||
|
||||
-- Phase C: Handle any DataConnections not assigned to any site
|
||||
-- (assign to the first site as a fallback)
|
||||
UPDATE dc
|
||||
SET dc.SiteId = (SELECT TOP 1 Id FROM Sites ORDER BY Id)
|
||||
FROM DataConnections dc
|
||||
WHERE dc.SiteId IS NULL;
|
||||
");
|
||||
|
||||
// Step 4: Make SiteId non-nullable
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "SiteId",
|
||||
table: "DataConnections",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "int",
|
||||
oldNullable: true);
|
||||
|
||||
// Step 5: Add composite unique index and FK
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataConnections_SiteId_Name",
|
||||
table: "DataConnections",
|
||||
columns: new[] { "SiteId", "Name" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_DataConnections_Sites_SiteId",
|
||||
table: "DataConnections",
|
||||
column: "SiteId",
|
||||
principalTable: "Sites",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
// Step 6: Drop SiteDataConnectionAssignments table
|
||||
migrationBuilder.DropTable(
|
||||
name: "SiteDataConnectionAssignments");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Recreate SiteDataConnectionAssignments table
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SiteDataConnectionAssignments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
DataConnectionId = table.Column<int>(type: "int", nullable: false),
|
||||
SiteId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SiteDataConnectionAssignments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SiteDataConnectionAssignments_DataConnections_DataConnectionId",
|
||||
column: x => x.DataConnectionId,
|
||||
principalTable: "DataConnections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_SiteDataConnectionAssignments_Sites_SiteId",
|
||||
column: x => x.SiteId,
|
||||
principalTable: "Sites",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteDataConnectionAssignments_DataConnectionId",
|
||||
table: "SiteDataConnectionAssignments",
|
||||
column: "DataConnectionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteDataConnectionAssignments_SiteId_DataConnectionId",
|
||||
table: "SiteDataConnectionAssignments",
|
||||
columns: new[] { "SiteId", "DataConnectionId" },
|
||||
unique: true);
|
||||
|
||||
// Migrate data back
|
||||
migrationBuilder.Sql(@"
|
||||
INSERT INTO SiteDataConnectionAssignments (SiteId, DataConnectionId)
|
||||
SELECT SiteId, Id FROM DataConnections;
|
||||
");
|
||||
|
||||
// Remove FK and composite index
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_DataConnections_Sites_SiteId",
|
||||
table: "DataConnections");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_DataConnections_SiteId_Name",
|
||||
table: "DataConnections");
|
||||
|
||||
// Restore unique index on Name
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataConnections_Name",
|
||||
table: "DataConnections",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
// Drop SiteId column
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SiteId",
|
||||
table: "DataConnections");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1236
File diff suppressed because it is too large
Load Diff
+50
@@ -0,0 +1,50 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPrimaryBackupDataConnections : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "Configuration",
|
||||
table: "DataConnections",
|
||||
newName: "PrimaryConfiguration");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BackupConfiguration",
|
||||
table: "DataConnections",
|
||||
type: "nvarchar(4000)",
|
||||
maxLength: 4000,
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "FailoverRetryCount",
|
||||
table: "DataConnections",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 3);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BackupConfiguration",
|
||||
table: "DataConnections");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FailoverRetryCount",
|
||||
table: "DataConnections");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "PrimaryConfiguration",
|
||||
table: "DataConnections",
|
||||
newName: "Configuration");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1282
File diff suppressed because it is too large
Load Diff
+80
@@ -0,0 +1,80 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddTemplateFolders : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "FolderId",
|
||||
table: "Templates",
|
||||
type: "int",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TemplateFolders",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
ParentFolderId = table.Column<int>(type: "int", nullable: true),
|
||||
SortOrder = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TemplateFolders", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TemplateFolders_TemplateFolders_ParentFolderId",
|
||||
column: x => x.ParentFolderId,
|
||||
principalTable: "TemplateFolders",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_FolderId",
|
||||
table: "Templates",
|
||||
column: "FolderId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TemplateFolders_ParentFolderId_Name",
|
||||
table: "TemplateFolders",
|
||||
columns: new[] { "ParentFolderId", "Name" },
|
||||
unique: true,
|
||||
filter: "[ParentFolderId] IS NOT NULL");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Templates_TemplateFolders_FolderId",
|
||||
table: "Templates",
|
||||
column: "FolderId",
|
||||
principalTable: "TemplateFolders",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Templates_TemplateFolders_FolderId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TemplateFolders");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Templates_FolderId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FolderId",
|
||||
table: "Templates");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1300
File diff suppressed because it is too large
Load Diff
+83
@@ -0,0 +1,83 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddDerivedTemplateFields : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsInherited",
|
||||
table: "TemplateScripts",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "LockedInDerived",
|
||||
table: "TemplateScripts",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsDerived",
|
||||
table: "Templates",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "OwnerCompositionId",
|
||||
table: "Templates",
|
||||
type: "int",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsInherited",
|
||||
table: "TemplateAttributes",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "LockedInDerived",
|
||||
table: "TemplateAttributes",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsInherited",
|
||||
table: "TemplateScripts");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LockedInDerived",
|
||||
table: "TemplateScripts");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsDerived",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OwnerCompositionId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsInherited",
|
||||
table: "TemplateAttributes");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LockedInDerived",
|
||||
table: "TemplateAttributes");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1300
File diff suppressed because it is too large
Load Diff
+117
@@ -0,0 +1,117 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class MigrateCompositionsToDerived : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Re-shape every pre-Phase-2 TemplateComposition so it points at a
|
||||
// newly created derived template ("<parent>.<slot>") that inherits
|
||||
// from the original base. Attribute and script rows are copied with
|
||||
// IsInherited=1; the composition's ComposedTemplateId is repointed.
|
||||
//
|
||||
// Idempotent: only rows whose target is still IsDerived=0 are touched.
|
||||
// Aborts the migration if any derived name would collide with an
|
||||
// existing template, so the operator can resolve manually.
|
||||
migrationBuilder.Sql(@"
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @collisions NVARCHAR(MAX) = (
|
||||
SELECT STRING_AGG(owner.Name + N'.' + c.InstanceName, N', ')
|
||||
FROM TemplateCompositions c
|
||||
INNER JOIN Templates base_t ON base_t.Id = c.ComposedTemplateId
|
||||
INNER JOIN Templates owner ON owner.Id = c.TemplateId
|
||||
INNER JOIN Templates existing ON existing.Name = owner.Name + N'.' + c.InstanceName
|
||||
WHERE base_t.IsDerived = 0
|
||||
);
|
||||
IF @collisions IS NOT NULL
|
||||
BEGIN
|
||||
DECLARE @msg NVARCHAR(MAX) =
|
||||
N'MigrateCompositionsToDerived: cannot create derived templates — these names already exist: '
|
||||
+ @collisions
|
||||
+ N'. Rename the conflicting templates and retry the migration.';
|
||||
THROW 50000, @msg, 1;
|
||||
END
|
||||
|
||||
DECLARE @CompId INT, @BaseId INT, @OwnerName NVARCHAR(200), @SlotName NVARCHAR(200);
|
||||
DECLARE @NewId INT, @NewName NVARCHAR(200);
|
||||
|
||||
DECLARE map_cursor CURSOR FAST_FORWARD FOR
|
||||
SELECT c.Id, c.ComposedTemplateId, owner.Name, c.InstanceName
|
||||
FROM TemplateCompositions c
|
||||
INNER JOIN Templates base_t ON base_t.Id = c.ComposedTemplateId
|
||||
INNER JOIN Templates owner ON owner.Id = c.TemplateId
|
||||
WHERE base_t.IsDerived = 0;
|
||||
|
||||
OPEN map_cursor;
|
||||
FETCH NEXT FROM map_cursor INTO @CompId, @BaseId, @OwnerName, @SlotName;
|
||||
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
SET @NewName = @OwnerName + N'.' + @SlotName;
|
||||
|
||||
INSERT INTO Templates (Name, Description, ParentTemplateId, FolderId, IsDerived, OwnerCompositionId)
|
||||
SELECT @NewName, b.Description, b.Id, NULL, 1, @CompId
|
||||
FROM Templates b
|
||||
WHERE b.Id = @BaseId;
|
||||
|
||||
SET @NewId = SCOPE_IDENTITY();
|
||||
|
||||
INSERT INTO TemplateAttributes
|
||||
(TemplateId, Name, Value, DataType, IsLocked, Description, DataSourceReference, IsInherited, LockedInDerived)
|
||||
SELECT @NewId, a.Name, a.Value, a.DataType, a.IsLocked, a.Description, a.DataSourceReference, 1, 0
|
||||
FROM TemplateAttributes a
|
||||
WHERE a.TemplateId = @BaseId;
|
||||
|
||||
INSERT INTO TemplateScripts
|
||||
(TemplateId, Name, Code, IsLocked, TriggerType, TriggerConfiguration, ParameterDefinitions, ReturnDefinition, MinTimeBetweenRuns, IsInherited, LockedInDerived)
|
||||
SELECT @NewId, s.Name, s.Code, s.IsLocked, s.TriggerType, s.TriggerConfiguration, s.ParameterDefinitions, s.ReturnDefinition, s.MinTimeBetweenRuns, 1, 0
|
||||
FROM TemplateScripts s
|
||||
WHERE s.TemplateId = @BaseId;
|
||||
|
||||
UPDATE TemplateCompositions
|
||||
SET ComposedTemplateId = @NewId
|
||||
WHERE Id = @CompId;
|
||||
|
||||
FETCH NEXT FROM map_cursor INTO @CompId, @BaseId, @OwnerName, @SlotName;
|
||||
END
|
||||
|
||||
CLOSE map_cursor;
|
||||
DEALLOCATE map_cursor;
|
||||
");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Reverse: repoint each composition back to the derived template's
|
||||
// base, then drop the derived templates (with their copied rows).
|
||||
migrationBuilder.Sql(@"
|
||||
SET NOCOUNT ON;
|
||||
|
||||
UPDATE c
|
||||
SET c.ComposedTemplateId = d.ParentTemplateId
|
||||
FROM TemplateCompositions c
|
||||
INNER JOIN Templates d ON d.Id = c.ComposedTemplateId
|
||||
WHERE d.IsDerived = 1
|
||||
AND d.OwnerCompositionId = c.Id
|
||||
AND d.ParentTemplateId IS NOT NULL;
|
||||
|
||||
DELETE a FROM TemplateAttributes a
|
||||
INNER JOIN Templates t ON t.Id = a.TemplateId
|
||||
WHERE t.IsDerived = 1;
|
||||
|
||||
DELETE s FROM TemplateScripts s
|
||||
INNER JOIN Templates t ON t.Id = s.TemplateId
|
||||
WHERE t.IsDerived = 1;
|
||||
|
||||
DELETE FROM Templates WHERE IsDerived = 1;
|
||||
");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1300
File diff suppressed because it is too large
Load Diff
+196
@@ -0,0 +1,196 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class MigrateParametersToJsonSchema : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Convert legacy flat-shape parameter / return JSON in TemplateScripts,
|
||||
// SharedScripts, and ApiMethods to JSON Schema.
|
||||
//
|
||||
// Parameters [{name,type,required,itemType?}]
|
||||
// → {"type":"object","properties":{<name>:{"type":<jsType>}},"required":[...]}
|
||||
//
|
||||
// Return {type,itemType?}
|
||||
// → {"type":<jsType>} or {"type":"array","items":{"type":<inner>}}
|
||||
//
|
||||
// Idempotent: only rows whose value starts with '[' (parameters) or that
|
||||
// contain the legacy 'List' sentinel (return) are touched. Already-converted
|
||||
// rows are skipped.
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
IF OBJECT_ID('dbo.fn_LegacyTypeToJsonSchemaType', 'FN') IS NOT NULL
|
||||
DROP FUNCTION dbo.fn_LegacyTypeToJsonSchemaType;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE FUNCTION dbo.fn_LegacyTypeToJsonSchemaType(@legacy NVARCHAR(50))
|
||||
RETURNS NVARCHAR(50)
|
||||
AS
|
||||
BEGIN
|
||||
RETURN
|
||||
CASE LOWER(ISNULL(@legacy, 'string'))
|
||||
WHEN 'boolean' THEN 'boolean'
|
||||
WHEN 'bool' THEN 'boolean'
|
||||
WHEN 'integer' THEN 'integer'
|
||||
WHEN 'int' THEN 'integer'
|
||||
WHEN 'int32' THEN 'integer'
|
||||
WHEN 'int64' THEN 'integer'
|
||||
WHEN 'float' THEN 'number'
|
||||
WHEN 'double' THEN 'number'
|
||||
WHEN 'decimal' THEN 'number'
|
||||
WHEN 'number' THEN 'number'
|
||||
WHEN 'string' THEN 'string'
|
||||
WHEN 'datetime' THEN 'string'
|
||||
WHEN 'object' THEN 'object'
|
||||
WHEN 'list' THEN 'array'
|
||||
WHEN 'array' THEN 'array'
|
||||
ELSE 'string'
|
||||
END;
|
||||
END;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
IF OBJECT_ID('dbo.fn_LegacyParametersToJsonSchema', 'FN') IS NOT NULL
|
||||
DROP FUNCTION dbo.fn_LegacyParametersToJsonSchema;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE FUNCTION dbo.fn_LegacyParametersToJsonSchema(@legacy NVARCHAR(MAX))
|
||||
RETURNS NVARCHAR(MAX)
|
||||
AS
|
||||
BEGIN
|
||||
IF @legacy IS NULL OR LTRIM(@legacy) = '' RETURN NULL;
|
||||
IF LEFT(LTRIM(@legacy), 1) <> '[' RETURN @legacy; -- already schema-shaped
|
||||
|
||||
DECLARE @props NVARCHAR(MAX) = (
|
||||
SELECT STRING_AGG(
|
||||
CONCAT(
|
||||
'""',
|
||||
STRING_ESCAPE(JSON_VALUE(p.value, '$.name'), 'json'),
|
||||
'"":',
|
||||
CASE
|
||||
WHEN LOWER(ISNULL(JSON_VALUE(p.value, '$.type'), 'string')) IN ('list', 'array')
|
||||
THEN CONCAT(
|
||||
'{""type"":""array"",""items"":{""type"":""',
|
||||
dbo.fn_LegacyTypeToJsonSchemaType(JSON_VALUE(p.value, '$.itemType')),
|
||||
'""}}')
|
||||
ELSE CONCAT(
|
||||
'{""type"":""',
|
||||
dbo.fn_LegacyTypeToJsonSchemaType(JSON_VALUE(p.value, '$.type')),
|
||||
'""}')
|
||||
END),
|
||||
',')
|
||||
WITHIN GROUP (ORDER BY p.[key])
|
||||
FROM OPENJSON(@legacy) p
|
||||
WHERE JSON_VALUE(p.value, '$.name') IS NOT NULL
|
||||
AND JSON_VALUE(p.value, '$.name') <> ''
|
||||
);
|
||||
|
||||
DECLARE @required NVARCHAR(MAX) = (
|
||||
SELECT STRING_AGG(
|
||||
CONCAT('""', STRING_ESCAPE(JSON_VALUE(p.value, '$.name'), 'json'), '""'),
|
||||
',')
|
||||
WITHIN GROUP (ORDER BY p.[key])
|
||||
FROM OPENJSON(@legacy) p
|
||||
WHERE JSON_VALUE(p.value, '$.name') IS NOT NULL
|
||||
AND JSON_VALUE(p.value, '$.name') <> ''
|
||||
AND LOWER(ISNULL(JSON_VALUE(p.value, '$.required'), 'true')) <> 'false'
|
||||
);
|
||||
|
||||
RETURN
|
||||
'{""type"":""object"",""properties"":{' + ISNULL(@props, '') + '}'
|
||||
+ CASE WHEN @required IS NULL OR @required = '' THEN ''
|
||||
ELSE ',""required"":[' + @required + ']'
|
||||
END
|
||||
+ '}';
|
||||
END;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
IF OBJECT_ID('dbo.fn_LegacyReturnToJsonSchema', 'FN') IS NOT NULL
|
||||
DROP FUNCTION dbo.fn_LegacyReturnToJsonSchema;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE FUNCTION dbo.fn_LegacyReturnToJsonSchema(@legacy NVARCHAR(MAX))
|
||||
RETURNS NVARCHAR(MAX)
|
||||
AS
|
||||
BEGIN
|
||||
IF @legacy IS NULL OR LTRIM(@legacy) = '' RETURN NULL;
|
||||
IF LEFT(LTRIM(@legacy), 1) <> '{' RETURN @legacy;
|
||||
|
||||
DECLARE @legacyType NVARCHAR(50) = JSON_VALUE(@legacy, '$.type');
|
||||
IF @legacyType IS NULL RETURN @legacy;
|
||||
|
||||
-- Already JSON Schema (lowercase types, no itemType legacy sentinel): leave it.
|
||||
IF @legacyType IN ('boolean','integer','number','string','object','array')
|
||||
AND JSON_VALUE(@legacy, '$.itemType') IS NULL
|
||||
RETURN @legacy;
|
||||
|
||||
IF LOWER(@legacyType) = 'list'
|
||||
BEGIN
|
||||
DECLARE @inner NVARCHAR(50) =
|
||||
dbo.fn_LegacyTypeToJsonSchemaType(JSON_VALUE(@legacy, '$.itemType'));
|
||||
RETURN CONCAT('{""type"":""array"",""items"":{""type"":""', @inner, '""}}');
|
||||
END;
|
||||
|
||||
RETURN CONCAT('{""type"":""', dbo.fn_LegacyTypeToJsonSchemaType(@legacyType), '""}');
|
||||
END;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
UPDATE TemplateScripts
|
||||
SET ParameterDefinitions = dbo.fn_LegacyParametersToJsonSchema(ParameterDefinitions)
|
||||
WHERE ParameterDefinitions IS NOT NULL
|
||||
AND LEFT(LTRIM(ParameterDefinitions), 1) = '[';
|
||||
|
||||
UPDATE TemplateScripts
|
||||
SET ReturnDefinition = dbo.fn_LegacyReturnToJsonSchema(ReturnDefinition)
|
||||
WHERE ReturnDefinition IS NOT NULL
|
||||
AND LEFT(LTRIM(ReturnDefinition), 1) = '{';
|
||||
|
||||
UPDATE SharedScripts
|
||||
SET ParameterDefinitions = dbo.fn_LegacyParametersToJsonSchema(ParameterDefinitions)
|
||||
WHERE ParameterDefinitions IS NOT NULL
|
||||
AND LEFT(LTRIM(ParameterDefinitions), 1) = '[';
|
||||
|
||||
UPDATE SharedScripts
|
||||
SET ReturnDefinition = dbo.fn_LegacyReturnToJsonSchema(ReturnDefinition)
|
||||
WHERE ReturnDefinition IS NOT NULL
|
||||
AND LEFT(LTRIM(ReturnDefinition), 1) = '{';
|
||||
|
||||
UPDATE ApiMethods
|
||||
SET ParameterDefinitions = dbo.fn_LegacyParametersToJsonSchema(ParameterDefinitions)
|
||||
WHERE ParameterDefinitions IS NOT NULL
|
||||
AND LEFT(LTRIM(ParameterDefinitions), 1) = '[';
|
||||
|
||||
UPDATE ApiMethods
|
||||
SET ReturnDefinition = dbo.fn_LegacyReturnToJsonSchema(ReturnDefinition)
|
||||
WHERE ReturnDefinition IS NOT NULL
|
||||
AND LEFT(LTRIM(ReturnDefinition), 1) = '{';
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
DROP FUNCTION IF EXISTS dbo.fn_LegacyParametersToJsonSchema;
|
||||
DROP FUNCTION IF EXISTS dbo.fn_LegacyReturnToJsonSchema;
|
||||
DROP FUNCTION IF EXISTS dbo.fn_LegacyTypeToJsonSchemaType;
|
||||
");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Lossy: JSON Schema can express fields (descriptions, defaults, enums,
|
||||
// nested objects) that the legacy flat shape cannot represent. Reverse
|
||||
// migration is not supported.
|
||||
throw new System.NotSupportedException(
|
||||
"Reverse migration from JSON Schema to legacy flat shape is not supported because the conversion is lossy.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1342
File diff suppressed because it is too large
Load Diff
+49
@@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddInstanceAlarmOverrides : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InstanceAlarmOverrides",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
InstanceId = table.Column<int>(type: "int", nullable: false),
|
||||
AlarmCanonicalName = table.Column<string>(type: "nvarchar(400)", maxLength: 400, nullable: false),
|
||||
TriggerConfigurationOverride = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
PriorityLevelOverride = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InstanceAlarmOverrides", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InstanceAlarmOverrides_Instances_InstanceId",
|
||||
column: x => x.InstanceId,
|
||||
principalTable: "Instances",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InstanceAlarmOverrides_InstanceId_AlarmCanonicalName",
|
||||
table: "InstanceAlarmOverrides",
|
||||
columns: new[] { "InstanceId", "AlarmCanonicalName" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "InstanceAlarmOverrides");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1348
File diff suppressed because it is too large
Load Diff
+40
@@ -0,0 +1,40 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddDerivedAlarmFields : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsInherited",
|
||||
table: "TemplateAlarms",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "LockedInDerived",
|
||||
table: "TemplateAlarms",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsInherited",
|
||||
table: "TemplateAlarms");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LockedInDerived",
|
||||
table: "TemplateAlarms");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1348
File diff suppressed because it is too large
Load Diff
+82
@@ -0,0 +1,82 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EncryptSecretColumns : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Credentials",
|
||||
table: "SmtpConfigurations",
|
||||
type: "nvarchar(max)",
|
||||
maxLength: 8000,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(4000)",
|
||||
oldMaxLength: 4000,
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AuthConfiguration",
|
||||
table: "ExternalSystemDefinitions",
|
||||
type: "nvarchar(max)",
|
||||
maxLength: 8000,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(4000)",
|
||||
oldMaxLength: 4000,
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ConnectionString",
|
||||
table: "DatabaseConnectionDefinitions",
|
||||
type: "nvarchar(max)",
|
||||
maxLength: 8000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(4000)",
|
||||
oldMaxLength: 4000);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Credentials",
|
||||
table: "SmtpConfigurations",
|
||||
type: "nvarchar(4000)",
|
||||
maxLength: 4000,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldMaxLength: 8000,
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AuthConfiguration",
|
||||
table: "ExternalSystemDefinitions",
|
||||
type: "nvarchar(4000)",
|
||||
maxLength: 4000,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldMaxLength: 8000,
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ConnectionString",
|
||||
table: "DatabaseConnectionDefinitions",
|
||||
type: "nvarchar(4000)",
|
||||
maxLength: 4000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldMaxLength: 8000);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1350
File diff suppressed because it is too large
Load Diff
+58
@@ -0,0 +1,58 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BoundGrpcNodeAddressLength : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "GrpcNodeBAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(500)",
|
||||
maxLength: 500,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "GrpcNodeAAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(500)",
|
||||
maxLength: 500,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "GrpcNodeBAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(500)",
|
||||
oldMaxLength: 500,
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "GrpcNodeAAddress",
|
||||
table: "Sites",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(500)",
|
||||
oldMaxLength: 500,
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1350
File diff suppressed because it is too large
Load Diff
+77
@@ -0,0 +1,77 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// ConfigurationDatabase-012: replaces the plaintext <c>KeyValue</c> column with a
|
||||
/// <c>KeyHash</c> column holding a deterministic HMAC-SHA256 hash of the key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A hash is one-way: existing plaintext keys cannot be converted to hashes
|
||||
/// without the originals. This migration therefore deletes all existing API-key
|
||||
/// rows. <strong>Every existing API key must be re-issued</strong> after this
|
||||
/// migration is applied — create new keys via the CLI / Management API / Central
|
||||
/// UI, distribute the one-time plaintext to callers, and approve them on methods.
|
||||
/// </remarks>
|
||||
public partial class HashApiKeyValue : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Existing keys hold only plaintext, which cannot be hashed back. They
|
||||
// must be re-issued, so remove them before the column change to keep the
|
||||
// new unique KeyHash index satisfiable.
|
||||
migrationBuilder.Sql("DELETE FROM ApiKeys;");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ApiKeys_KeyValue",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "KeyValue",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "KeyHash",
|
||||
table: "ApiKeys",
|
||||
type: "nvarchar(256)",
|
||||
maxLength: 256,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ApiKeys_KeyHash",
|
||||
table: "ApiKeys",
|
||||
column: "KeyHash",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ApiKeys_KeyHash",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "KeyHash",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "KeyValue",
|
||||
table: "ApiKeys",
|
||||
type: "nvarchar(500)",
|
||||
maxLength: 500,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ApiKeys_KeyValue",
|
||||
table: "ApiKeys",
|
||||
column: "KeyValue",
|
||||
unique: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1351
File diff suppressed because it is too large
Load Diff
+81
@@ -0,0 +1,81 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Moves composition-derived templates to AVEVA-style contained names: a
|
||||
/// derived template stores only its slot name (e.g. <c>Pump</c>), not the
|
||||
/// dotted qualified path (<c>Motor Controller.Pump</c>). The qualified name
|
||||
/// is computed on read by walking the OwnerComposition chain. The unique
|
||||
/// index on Template.Name becomes filtered to base templates only —
|
||||
/// derived templates' uniqueness is the (TemplateId, InstanceName) index on
|
||||
/// TemplateComposition.
|
||||
/// </summary>
|
||||
public partial class ContainedDerivedTemplateNames : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Drop the global unique index first: derived rows are about to be
|
||||
// renamed to contained names that may duplicate one another or a
|
||||
// base template.
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Templates_Name",
|
||||
table: "Templates");
|
||||
|
||||
// Collapse every derived template's dotted name to its contained
|
||||
// name — the owning composition slot's InstanceName.
|
||||
migrationBuilder.Sql(@"
|
||||
UPDATE t
|
||||
SET t.Name = c.InstanceName
|
||||
FROM Templates t
|
||||
INNER JOIN TemplateCompositions c ON c.Id = t.OwnerCompositionId
|
||||
WHERE t.IsDerived = 1;");
|
||||
|
||||
// Recreate the uniqueness guarantee for base templates only.
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_Name",
|
||||
table: "Templates",
|
||||
column: "Name",
|
||||
unique: true,
|
||||
filter: "[IsDerived] = 0");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Templates_Name",
|
||||
table: "Templates");
|
||||
|
||||
// Rebuild the dotted qualified names so the global unique index can
|
||||
// be restored — derived templates' contained names are not globally
|
||||
// unique. The recursive CTE walks the OwnerComposition chain down
|
||||
// from each base template.
|
||||
migrationBuilder.Sql(@"
|
||||
WITH q AS (
|
||||
SELECT t.Id, CAST(t.Name AS NVARCHAR(MAX)) AS Qualified
|
||||
FROM Templates t
|
||||
WHERE t.IsDerived = 0
|
||||
UNION ALL
|
||||
SELECT t.Id, CAST(q.Qualified + N'.' + c.InstanceName AS NVARCHAR(MAX))
|
||||
FROM Templates t
|
||||
INNER JOIN TemplateCompositions c ON c.Id = t.OwnerCompositionId
|
||||
INNER JOIN q ON q.Id = c.TemplateId
|
||||
)
|
||||
UPDATE t
|
||||
SET t.Name = q.Qualified
|
||||
FROM Templates t
|
||||
INNER JOIN q ON q.Id = t.Id
|
||||
WHERE t.IsDerived = 1;");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_Name",
|
||||
table: "Templates",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1436
File diff suppressed because it is too large
Load Diff
+72
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddNotificationsTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Type",
|
||||
table: "NotificationLists",
|
||||
type: "nvarchar(32)",
|
||||
maxLength: 32,
|
||||
nullable: false,
|
||||
defaultValue: "Email");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Notifications",
|
||||
columns: table => new
|
||||
{
|
||||
NotificationId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false),
|
||||
Type = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: false),
|
||||
ListName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||
Subject = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: false),
|
||||
Body = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
TypeData = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Status = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: false),
|
||||
RetryCount = table.Column<int>(type: "int", nullable: false),
|
||||
LastError = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
|
||||
ResolvedTargets = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
SourceSiteId = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
SourceInstanceId = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
|
||||
SourceScript = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
|
||||
SiteEnqueuedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||
LastAttemptAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
||||
NextAttemptAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
||||
DeliveredAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Notifications", x => x.NotificationId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Notifications_SourceSiteId_CreatedAt",
|
||||
table: "Notifications",
|
||||
columns: new[] { "SourceSiteId", "CreatedAt" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Notifications_Status_NextAttemptAt",
|
||||
table: "Notifications",
|
||||
columns: new[] { "Status", "NextAttemptAt" });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Notifications");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Type",
|
||||
table: "NotificationLists");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1553
File diff suppressed because it is too large
Load Diff
+201
@@ -0,0 +1,201 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Bundle C (#23 M1): creates the centralized AuditLog table with monthly
|
||||
/// partitioning and the two access-control roles documented in alog.md §4.
|
||||
///
|
||||
/// Structure:
|
||||
/// 1. Partition function <c>pf_AuditLog_Month</c> (RANGE RIGHT) with 24
|
||||
/// monthly boundaries covering 2026-01-01 through 2027-12-01 UTC.
|
||||
/// 2. Partition scheme <c>ps_AuditLog_Month</c> mapping every partition to
|
||||
/// [PRIMARY] (dev/test parity; production may relocate via filegroups).
|
||||
/// 3. <c>AuditLog</c> table created via raw SQL so it is created directly
|
||||
/// on the partition scheme. The clustered PK is composite
|
||||
/// {EventId, OccurredAtUtc} — required because partition-aligned PKs
|
||||
/// must include the partition column.
|
||||
/// 4. Five reconciliation/query indexes from alog.md §4, plus the
|
||||
/// UX_AuditLog_EventId unique index that preserves single-column
|
||||
/// EventId uniqueness for InsertIfNotExistsAsync (M1-T8). All
|
||||
/// non-clustered indexes are partition-aligned on
|
||||
/// <c>ps_AuditLog_Month(OccurredAtUtc)</c>.
|
||||
/// 5. Two database roles:
|
||||
/// - <c>scadabridge_audit_writer</c>: INSERT + SELECT on AuditLog, with
|
||||
/// explicit DENY on UPDATE and DELETE so additive role membership
|
||||
/// (e.g. later db_datawriter) cannot accidentally re-enable mutation.
|
||||
/// - <c>scadabridge_audit_purger</c>: SELECT on AuditLog and ALTER on
|
||||
/// SCHEMA::dbo so the purger can run ALTER PARTITION FUNCTION SWITCH
|
||||
/// and SWITCH PARTITION when sliding the retention window.
|
||||
/// </summary>
|
||||
public partial class AddAuditLogTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// 1) Partition function (monthly boundaries Jan 2026 – Dec 2027 UTC).
|
||||
// RANGE RIGHT — the boundary value belongs to the right-hand partition,
|
||||
// matching the convention used by SQL Server partition-switch tooling.
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE PARTITION FUNCTION pf_AuditLog_Month (datetime2(7))
|
||||
AS RANGE RIGHT FOR VALUES (
|
||||
'2026-01-01T00:00:00', '2026-02-01T00:00:00', '2026-03-01T00:00:00', '2026-04-01T00:00:00',
|
||||
'2026-05-01T00:00:00', '2026-06-01T00:00:00', '2026-07-01T00:00:00', '2026-08-01T00:00:00',
|
||||
'2026-09-01T00:00:00', '2026-10-01T00:00:00', '2026-11-01T00:00:00', '2026-12-01T00:00:00',
|
||||
'2027-01-01T00:00:00', '2027-02-01T00:00:00', '2027-03-01T00:00:00', '2027-04-01T00:00:00',
|
||||
'2027-05-01T00:00:00', '2027-06-01T00:00:00', '2027-07-01T00:00:00', '2027-08-01T00:00:00',
|
||||
'2027-09-01T00:00:00', '2027-10-01T00:00:00', '2027-11-01T00:00:00', '2027-12-01T00:00:00'
|
||||
);");
|
||||
|
||||
// 2) Partition scheme mapping every partition to [PRIMARY].
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE PARTITION SCHEME ps_AuditLog_Month
|
||||
AS PARTITION pf_AuditLog_Month ALL TO ([PRIMARY]);");
|
||||
|
||||
// 3) Create the table directly on the partition scheme. Column shapes
|
||||
// are copied from AuditLogEntityTypeConfiguration so the live schema
|
||||
// matches the EF model exactly. The clustered PK is composite to
|
||||
// satisfy SQL Server's rule that partition-aligned clustered indexes
|
||||
// must include the partition column.
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE TABLE dbo.AuditLog (
|
||||
EventId uniqueidentifier NOT NULL,
|
||||
OccurredAtUtc datetime2(7) NOT NULL,
|
||||
IngestedAtUtc datetime2(7) NULL,
|
||||
Channel varchar(32) NOT NULL,
|
||||
Kind varchar(32) NOT NULL,
|
||||
CorrelationId uniqueidentifier NULL,
|
||||
SourceSiteId varchar(64) NULL,
|
||||
SourceInstanceId varchar(128) NULL,
|
||||
SourceScript varchar(128) NULL,
|
||||
Actor varchar(128) NULL,
|
||||
Target varchar(256) NULL,
|
||||
Status varchar(32) NOT NULL,
|
||||
HttpStatus int NULL,
|
||||
DurationMs int NULL,
|
||||
ErrorMessage nvarchar(1024) NULL,
|
||||
ErrorDetail nvarchar(max) NULL,
|
||||
RequestSummary nvarchar(max) NULL,
|
||||
ResponseSummary nvarchar(max) NULL,
|
||||
PayloadTruncated bit NOT NULL,
|
||||
Extra nvarchar(max) NULL,
|
||||
ForwardState varchar(32) NULL,
|
||||
CONSTRAINT PK_AuditLog PRIMARY KEY CLUSTERED (EventId, OccurredAtUtc)
|
||||
ON ps_AuditLog_Month(OccurredAtUtc)
|
||||
) ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
// 4) Reconciliation/query indexes from alog.md §4. All non-clustered
|
||||
// indexes are partition-aligned on ps_AuditLog_Month(OccurredAtUtc)
|
||||
// so partition-switch operations only touch a single partition. The
|
||||
// filtered indexes carry their NOT NULL predicates as documented.
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_OccurredAtUtc
|
||||
ON dbo.AuditLog (OccurredAtUtc DESC)
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_Site_Occurred
|
||||
ON dbo.AuditLog (SourceSiteId ASC, OccurredAtUtc DESC)
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_CorrelationId
|
||||
ON dbo.AuditLog (CorrelationId)
|
||||
WHERE CorrelationId IS NOT NULL
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_Channel_Status_Occurred
|
||||
ON dbo.AuditLog (Channel ASC, Status ASC, OccurredAtUtc DESC)
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_Target_Occurred
|
||||
ON dbo.AuditLog (Target ASC, OccurredAtUtc DESC)
|
||||
WHERE Target IS NOT NULL
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
// The EventId uniqueness index supports InsertIfNotExistsAsync
|
||||
// (M1-T8). It is INTENTIONALLY non-aligned (placed on [PRIMARY]
|
||||
// rather than ps_AuditLog_Month).
|
||||
//
|
||||
// SQL Server's rule for unique partition-aligned indexes is that the
|
||||
// partition column must be a SUBSET of the index key. Including
|
||||
// OccurredAtUtc in the key would change the uniqueness semantics
|
||||
// from "EventId is globally unique" to "(EventId, OccurredAtUtc)
|
||||
// is unique", which is the same guarantee the composite PK already
|
||||
// provides — it would not give us single-column EventId uniqueness.
|
||||
//
|
||||
// Trade-off: a non-aligned index disables ALTER TABLE … SWITCH
|
||||
// PARTITION on AuditLog. The M1 purge story (M2/M3) uses an
|
||||
// explicit rebuild path that drops and re-creates this index
|
||||
// around the switch, so the aligned-indexes pattern is preserved
|
||||
// for partition switching at purge time.
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE UNIQUE NONCLUSTERED INDEX UX_AuditLog_EventId
|
||||
ON dbo.AuditLog (EventId)
|
||||
ON [PRIMARY];");
|
||||
|
||||
// 5) DB roles. Both definitions are idempotent so the migration is
|
||||
// safe to re-apply against a database that already has the role.
|
||||
// The DENY UPDATE / DENY DELETE on the writer role is deliberate —
|
||||
// a future db_datawriter membership cannot quietly re-enable
|
||||
// mutation because DENY outranks GRANT.
|
||||
migrationBuilder.Sql(@"
|
||||
IF DATABASE_PRINCIPAL_ID('scadabridge_audit_writer') IS NULL
|
||||
EXEC sp_executesql N'CREATE ROLE scadabridge_audit_writer';
|
||||
GRANT INSERT ON dbo.AuditLog TO scadabridge_audit_writer;
|
||||
GRANT SELECT ON dbo.AuditLog TO scadabridge_audit_writer;
|
||||
DENY UPDATE ON dbo.AuditLog TO scadabridge_audit_writer;
|
||||
DENY DELETE ON dbo.AuditLog TO scadabridge_audit_writer;");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
IF DATABASE_PRINCIPAL_ID('scadabridge_audit_purger') IS NULL
|
||||
EXEC sp_executesql N'CREATE ROLE scadabridge_audit_purger';
|
||||
GRANT SELECT ON dbo.AuditLog TO scadabridge_audit_purger;
|
||||
GRANT ALTER ON SCHEMA::dbo TO scadabridge_audit_purger;");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Drop in reverse dependency order so each statement's prerequisites
|
||||
// still exist when it runs. Each DROP is guarded so a partial Up()
|
||||
// (or a re-applied Down()) cannot fail on missing objects.
|
||||
migrationBuilder.Sql(@"
|
||||
IF DATABASE_PRINCIPAL_ID('scadabridge_audit_purger') IS NOT NULL
|
||||
EXEC sp_executesql N'DROP ROLE scadabridge_audit_purger';
|
||||
IF DATABASE_PRINCIPAL_ID('scadabridge_audit_writer') IS NOT NULL
|
||||
EXEC sp_executesql N'DROP ROLE scadabridge_audit_writer';");
|
||||
|
||||
// Indexes are dropped implicitly when the table goes away, but
|
||||
// dropping them explicitly first keeps the Down() statement self-
|
||||
// describing and mirrors the Up() shape.
|
||||
migrationBuilder.Sql(@"
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'UX_AuditLog_EventId' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX UX_AuditLog_EventId ON dbo.AuditLog;
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Target_Occurred' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_Target_Occurred ON dbo.AuditLog;
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Channel_Status_Occurred' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_Channel_Status_Occurred ON dbo.AuditLog;
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_CorrelationId' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_CorrelationId ON dbo.AuditLog;
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Site_Occurred' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_Site_Occurred ON dbo.AuditLog;
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_OccurredAtUtc' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_OccurredAtUtc ON dbo.AuditLog;");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
IF OBJECT_ID('dbo.AuditLog', 'U') IS NOT NULL
|
||||
DROP TABLE dbo.AuditLog;");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
IF EXISTS (SELECT 1 FROM sys.partition_schemes WHERE name = 'ps_AuditLog_Month')
|
||||
DROP PARTITION SCHEME ps_AuditLog_Month;
|
||||
IF EXISTS (SELECT 1 FROM sys.partition_functions WHERE name = 'pf_AuditLog_Month')
|
||||
DROP PARTITION FUNCTION pf_AuditLog_Month;");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1619
File diff suppressed because it is too large
Load Diff
+56
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddSiteCallsTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SiteCalls",
|
||||
columns: table => new
|
||||
{
|
||||
TrackedOperationId = table.Column<string>(type: "varchar(36)", unicode: false, maxLength: 36, nullable: false),
|
||||
Channel = table.Column<string>(type: "varchar(32)", unicode: false, maxLength: 32, nullable: false),
|
||||
Target = table.Column<string>(type: "varchar(256)", unicode: false, maxLength: 256, nullable: false),
|
||||
SourceSite = table.Column<string>(type: "varchar(64)", unicode: false, maxLength: 64, nullable: false),
|
||||
Status = table.Column<string>(type: "varchar(32)", unicode: false, maxLength: 32, nullable: false),
|
||||
RetryCount = table.Column<int>(type: "int", nullable: false),
|
||||
LastError = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true),
|
||||
HttpStatus = table.Column<int>(type: "int", nullable: true),
|
||||
CreatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
UpdatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
TerminalAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||
IngestedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SiteCalls", x => x.TrackedOperationId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteCalls_Source_Created",
|
||||
table: "SiteCalls",
|
||||
columns: new[] { "SourceSite", "CreatedAtUtc" },
|
||||
descending: new[] { false, true });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SiteCalls_Status_Updated",
|
||||
table: "SiteCalls",
|
||||
columns: new[] { "Status", "UpdatedAtUtc" },
|
||||
descending: new[] { false, true });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "SiteCalls");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1626
File diff suppressed because it is too large
Load Diff
+57
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the universal <c>ExecutionId</c> correlation column to the centralized
|
||||
/// <c>AuditLog</c> table (#23). <c>ExecutionId</c> identifies the originating
|
||||
/// script execution / inbound request and is distinct from the per-operation
|
||||
/// <c>CorrelationId</c>.
|
||||
///
|
||||
/// The change is purely additive:
|
||||
/// 1. <c>ExecutionId uniqueidentifier NULL</c> is added with no default, so the
|
||||
/// operation is a metadata-only <c>ALTER TABLE … ADD</c> — it does NOT
|
||||
/// rewrite the monthly-partitioned <c>AuditLog</c> table, and historical
|
||||
/// rows stay <c>NULL</c> (no backfill).
|
||||
/// 2. <c>IX_AuditLog_Execution</c> is created via raw SQL so it lands on the
|
||||
/// <c>ps_AuditLog_Month(OccurredAtUtc)</c> partition scheme, matching every
|
||||
/// other <c>IX_AuditLog_*</c> index. Keeping it partition-aligned preserves
|
||||
/// the partition-switch purge path (see AuditLogRepository.SwitchOutPartitionAsync).
|
||||
/// </summary>
|
||||
public partial class AddAuditLogExecutionId : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ExecutionId",
|
||||
table: "AuditLog",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
|
||||
// Raw SQL so the index is created on the partition scheme — EF's
|
||||
// CreateIndex cannot express the ON ps_AuditLog_Month(OccurredAtUtc)
|
||||
// clause. Mirrors IX_AuditLog_CorrelationId (filtered, aligned).
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_Execution
|
||||
ON dbo.AuditLog (ExecutionId)
|
||||
WHERE ExecutionId IS NOT NULL
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(@"
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Execution' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_Execution ON dbo.AuditLog;");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExecutionId",
|
||||
table: "AuditLog");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1629
File diff suppressed because it is too large
Load Diff
+41
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <c>OriginExecutionId</c> correlation column to the central
|
||||
/// <c>Notifications</c> table (#21). It carries the originating script execution's
|
||||
/// <c>ExecutionId</c> from the site so the dispatcher can echo it onto the
|
||||
/// <c>NotifyDeliver</c> audit rows (#23), linking them to the site's <c>NotifySend</c>
|
||||
/// row for the same run.
|
||||
///
|
||||
/// The change is purely additive: <c>OriginExecutionId uniqueidentifier NULL</c> is
|
||||
/// added with no default, so the operation is a metadata-only <c>ALTER TABLE … ADD</c>.
|
||||
/// Unlike <c>AuditLog</c>, the <c>Notifications</c> table is NOT partitioned, so a
|
||||
/// plain <c>ADD</c> is fine. No index is created — the column is never a query
|
||||
/// predicate, only copied onto audit events. Historical rows stay <c>NULL</c>.
|
||||
/// </summary>
|
||||
public partial class AddNotificationOriginExecutionId : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "OriginExecutionId",
|
||||
table: "Notifications",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OriginExecutionId",
|
||||
table: "Notifications");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1636
File diff suppressed because it is too large
Load Diff
+59
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <c>ParentExecutionId</c> correlation column to the centralized
|
||||
/// <c>AuditLog</c> table (#23). <c>ParentExecutionId</c> carries the
|
||||
/// <c>ExecutionId</c> of the execution that spawned this run, letting a
|
||||
/// spawned execution point back at its spawner — a sibling to the universal
|
||||
/// per-run <c>ExecutionId</c>.
|
||||
///
|
||||
/// The change is purely additive:
|
||||
/// 1. <c>ParentExecutionId uniqueidentifier NULL</c> is added with no default,
|
||||
/// so the operation is a metadata-only <c>ALTER TABLE … ADD</c> — it does
|
||||
/// NOT rewrite the monthly-partitioned <c>AuditLog</c> table, and
|
||||
/// historical rows stay <c>NULL</c> (no backfill).
|
||||
/// 2. <c>IX_AuditLog_ParentExecution</c> is created via raw SQL so it lands on
|
||||
/// the <c>ps_AuditLog_Month(OccurredAtUtc)</c> partition scheme, matching
|
||||
/// every other <c>IX_AuditLog_*</c> index. Keeping it partition-aligned
|
||||
/// preserves the partition-switch purge path (see
|
||||
/// AuditLogRepository.SwitchOutPartitionAsync).
|
||||
/// </summary>
|
||||
public partial class AddAuditLogParentExecutionId : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ParentExecutionId",
|
||||
table: "AuditLog",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
|
||||
// Raw SQL so the index is created on the partition scheme — EF's
|
||||
// CreateIndex cannot express the ON ps_AuditLog_Month(OccurredAtUtc)
|
||||
// clause. Mirrors IX_AuditLog_Execution (filtered, aligned).
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_ParentExecution
|
||||
ON dbo.AuditLog (ParentExecutionId)
|
||||
WHERE ParentExecutionId IS NOT NULL
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(@"
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_ParentExecution' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_ParentExecution ON dbo.AuditLog;");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ParentExecutionId",
|
||||
table: "AuditLog");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1639
File diff suppressed because it is too large
Load Diff
+42
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <c>OriginParentExecutionId</c> correlation column to the central
|
||||
/// <c>Notifications</c> table (#21). It carries the originating routed script
|
||||
/// execution's <c>ParentExecutionId</c> from the site so the dispatcher can echo it
|
||||
/// onto the <c>NotifyDeliver</c> audit rows (#23), linking them to the routed run's
|
||||
/// parent. Sibling of <c>OriginExecutionId</c>.
|
||||
///
|
||||
/// The change is purely additive: <c>OriginParentExecutionId uniqueidentifier NULL</c>
|
||||
/// is added with no default, so the operation is a metadata-only
|
||||
/// <c>ALTER TABLE … ADD</c>. Unlike <c>AuditLog</c>, the <c>Notifications</c> table is
|
||||
/// NOT partitioned, so a plain <c>ADD</c> is fine. No index is created — the column is
|
||||
/// never a query predicate, only copied onto audit events. Historical rows stay
|
||||
/// <c>NULL</c>.
|
||||
/// </summary>
|
||||
public partial class AddNotificationOriginParentExecutionId : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "OriginParentExecutionId",
|
||||
table: "Notifications",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OriginParentExecutionId",
|
||||
table: "Notifications");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1647
File diff suppressed because it is too large
Load Diff
+60
@@ -0,0 +1,60 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <c>SourceNode</c> column to the centralized <c>AuditLog</c> table (#23,
|
||||
/// SourceNode-stamping). <c>SourceNode</c> identifies the cluster node that produced the
|
||||
/// audit row (e.g. <c>node-a</c>, <c>central-a</c>) — ASCII-only, so <c>varchar(64)</c>
|
||||
/// not <c>nvarchar</c>. <c>NULL</c> is valid (reconciled rows from a retired node,
|
||||
/// central direct-write rows pre-this-feature).
|
||||
///
|
||||
/// The change is purely additive:
|
||||
/// 1. <c>SourceNode varchar(64) NULL</c> is added with no default, so the operation
|
||||
/// is a metadata-only <c>ALTER TABLE … ADD</c> — it does NOT rewrite the
|
||||
/// monthly-partitioned <c>AuditLog</c> table, and historical rows stay <c>NULL</c>.
|
||||
/// 2. <c>IX_AuditLog_Node_Occurred (SourceNode, OccurredAtUtc)</c> is created via raw
|
||||
/// SQL so it lands on the <c>ps_AuditLog_Month(OccurredAtUtc)</c> partition scheme,
|
||||
/// matching every other <c>IX_AuditLog_*</c> index. Keeping it partition-aligned
|
||||
/// preserves the partition-switch purge path (see
|
||||
/// AuditLogRepository.SwitchOutPartitionAsync).
|
||||
/// </summary>
|
||||
public partial class AddAuditLogSourceNode : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "SourceNode",
|
||||
table: "AuditLog",
|
||||
type: "varchar(64)",
|
||||
unicode: false,
|
||||
maxLength: 64,
|
||||
nullable: true);
|
||||
|
||||
// Raw SQL so the index is created on the partition scheme — EF's
|
||||
// CreateIndex cannot express the ON ps_AuditLog_Month(OccurredAtUtc)
|
||||
// clause. Mirrors IX_AuditLog_ParentExecution (aligned, unfiltered here:
|
||||
// NULL SourceNode is a legitimate query target, e.g. "rows produced
|
||||
// before stamping shipped" — no HasFilter on this index).
|
||||
migrationBuilder.Sql(@"
|
||||
CREATE NONCLUSTERED INDEX IX_AuditLog_Node_Occurred
|
||||
ON dbo.AuditLog (SourceNode, OccurredAtUtc)
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(@"
|
||||
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Node_Occurred' AND object_id = OBJECT_ID('dbo.AuditLog'))
|
||||
DROP INDEX IX_AuditLog_Node_Occurred ON dbo.AuditLog;");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SourceNode",
|
||||
table: "AuditLog");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1652
File diff suppressed because it is too large
Load Diff
+42
@@ -0,0 +1,42 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <c>SourceNode</c> column to the central <c>Notifications</c> table (#21,
|
||||
/// SourceNode-stamping). <c>SourceNode</c> identifies the cluster node that produced the
|
||||
/// notification (e.g. <c>node-a</c>, <c>central-a</c>) — ASCII-only, so <c>varchar(64)</c>
|
||||
/// not <c>nvarchar</c>. <c>NULL</c> is valid for rows that pre-date this feature.
|
||||
///
|
||||
/// The change is purely additive: <c>SourceNode varchar(64) NULL</c> is added with no
|
||||
/// default, so the operation is a metadata-only <c>ALTER TABLE … ADD</c>. Unlike
|
||||
/// <c>AuditLog</c>, the <c>Notifications</c> table is NOT partitioned, so a plain
|
||||
/// <c>ADD</c> is fine. No index — Notification Outbox KPIs are per-site, not per-node,
|
||||
/// on this table; <c>SourceNode</c> is only echoed onto <c>NotifyDeliver</c> audit rows
|
||||
/// (#23) for cross-row correlation. Historical rows stay <c>NULL</c>.
|
||||
/// </summary>
|
||||
public partial class AddNotificationSourceNode : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "SourceNode",
|
||||
table: "Notifications",
|
||||
type: "varchar(64)",
|
||||
unicode: false,
|
||||
maxLength: 64,
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SourceNode",
|
||||
table: "Notifications");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1657
File diff suppressed because it is too large
Load Diff
+43
@@ -0,0 +1,43 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <c>SourceNode</c> column to the central <c>SiteCalls</c> table (#22,
|
||||
/// SourceNode-stamping). <c>SourceNode</c> identifies the cluster node that produced the
|
||||
/// row (e.g. <c>node-a</c>, <c>central-a</c>) — ASCII-only, so <c>varchar(64)</c> not
|
||||
/// <c>nvarchar</c>. <c>NULL</c> is valid for rows that pre-date this feature and for
|
||||
/// reconciled rows from a retired node.
|
||||
///
|
||||
/// The change is purely additive: <c>SourceNode varchar(64) NULL</c> is added with no
|
||||
/// default, so the operation is a metadata-only <c>ALTER TABLE … ADD</c>. The
|
||||
/// <c>SiteCalls</c> table is NOT partitioned (operational state, not audit), so a plain
|
||||
/// <c>ADD</c> is fine. No index — Site Call Audit KPIs are per-site, not per-node, on
|
||||
/// this table; <c>SourceNode</c> is operational metadata, never a query predicate here.
|
||||
/// Historical rows stay <c>NULL</c>.
|
||||
/// </summary>
|
||||
public partial class AddSiteCallSourceNode : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "SourceNode",
|
||||
table: "SiteCalls",
|
||||
type: "varchar(64)",
|
||||
unicode: false,
|
||||
maxLength: 64,
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SourceNode",
|
||||
table: "SiteCalls");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1663
File diff suppressed because it is too large
Load Diff
+38
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBundleImportIdToAuditLog : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "BundleImportId",
|
||||
table: "AuditLogEntries",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogEntries_BundleImportId",
|
||||
table: "AuditLogEntries",
|
||||
column: "BundleImportId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AuditLogEntries_BundleImportId",
|
||||
table: "AuditLogEntries");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BundleImportId",
|
||||
table: "AuditLogEntries");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1660
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user