Добавьте файлы проекта.
This commit is contained in:
141
Services/DatabaseInitializer.cs
Normal file
141
Services/DatabaseInitializer.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace CRAWLER.Services;
|
||||
|
||||
internal sealed class DatabaseInitializer
|
||||
{
|
||||
private readonly IDatabaseConnectionFactory _connectionFactory;
|
||||
|
||||
public DatabaseInitializer(IDatabaseConnectionFactory connectionFactory)
|
||||
{
|
||||
_connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
public async Task EnsureCreatedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await EnsureDatabaseExistsAsync(cancellationToken);
|
||||
await EnsureSchemaAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private async Task EnsureDatabaseExistsAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateMasterConnection();
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var safeDatabaseName = _connectionFactory.Options.Database.Replace("]", "]]");
|
||||
var sql = $@"
|
||||
IF DB_ID(N'{safeDatabaseName}') IS NULL
|
||||
BEGIN
|
||||
CREATE DATABASE [{safeDatabaseName}];
|
||||
END";
|
||||
|
||||
await using var command = new SqlCommand(sql, connection)
|
||||
{
|
||||
CommandTimeout = _connectionFactory.Options.CommandTimeoutSeconds
|
||||
};
|
||||
await command.ExecuteNonQueryAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private async Task EnsureSchemaAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var scripts = new[]
|
||||
{
|
||||
@"
|
||||
IF OBJECT_ID(N'dbo.Instruments', N'U') IS NULL
|
||||
BEGIN
|
||||
CREATE TABLE dbo.Instruments
|
||||
(
|
||||
Id BIGINT IDENTITY(1,1) NOT NULL CONSTRAINT PK_Instruments PRIMARY KEY,
|
||||
RegistryNumber NVARCHAR(64) NULL,
|
||||
Name NVARCHAR(512) NOT NULL,
|
||||
TypeDesignation NVARCHAR(512) NULL,
|
||||
Manufacturer NVARCHAR(2000) NULL,
|
||||
VerificationInterval NVARCHAR(512) NULL,
|
||||
CertificateOrSerialNumber NVARCHAR(512) NULL,
|
||||
AllowsBatchVerification NVARCHAR(256) NULL,
|
||||
HasPeriodicVerification NVARCHAR(256) NULL,
|
||||
TypeInfo NVARCHAR(256) NULL,
|
||||
Purpose NVARCHAR(MAX) NULL,
|
||||
Description NVARCHAR(MAX) NULL,
|
||||
Software NVARCHAR(MAX) NULL,
|
||||
MetrologicalCharacteristics NVARCHAR(MAX) NULL,
|
||||
Completeness NVARCHAR(MAX) NULL,
|
||||
Verification NVARCHAR(MAX) NULL,
|
||||
RegulatoryDocuments NVARCHAR(MAX) NULL,
|
||||
Applicant NVARCHAR(MAX) NULL,
|
||||
TestCenter NVARCHAR(MAX) NULL,
|
||||
DetailUrl NVARCHAR(1024) NULL,
|
||||
SourceSystem NVARCHAR(64) NOT NULL CONSTRAINT DF_Instruments_SourceSystem DEFAULT N'Manual',
|
||||
LastImportedAt DATETIME2 NULL,
|
||||
CreatedAt DATETIME2 NOT NULL CONSTRAINT DF_Instruments_CreatedAt DEFAULT SYSUTCDATETIME(),
|
||||
UpdatedAt DATETIME2 NOT NULL CONSTRAINT DF_Instruments_UpdatedAt DEFAULT SYSUTCDATETIME()
|
||||
);
|
||||
END",
|
||||
@"
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM sys.indexes
|
||||
WHERE name = N'UX_Instruments_RegistryNumber'
|
||||
AND object_id = OBJECT_ID(N'dbo.Instruments')
|
||||
)
|
||||
BEGIN
|
||||
CREATE UNIQUE INDEX UX_Instruments_RegistryNumber
|
||||
ON dbo.Instruments (RegistryNumber)
|
||||
WHERE RegistryNumber IS NOT NULL AND RegistryNumber <> N'';
|
||||
END",
|
||||
@"
|
||||
IF OBJECT_ID(N'dbo.PdfAttachments', N'U') IS NULL
|
||||
BEGIN
|
||||
CREATE TABLE dbo.PdfAttachments
|
||||
(
|
||||
Id BIGINT IDENTITY(1,1) NOT NULL CONSTRAINT PK_PdfAttachments PRIMARY KEY,
|
||||
InstrumentId BIGINT NOT NULL,
|
||||
Kind NVARCHAR(128) NOT NULL,
|
||||
Title NVARCHAR(256) NULL,
|
||||
SourceUrl NVARCHAR(1024) NULL,
|
||||
LocalPath NVARCHAR(1024) NULL,
|
||||
IsManual BIT NOT NULL CONSTRAINT DF_PdfAttachments_IsManual DEFAULT (0),
|
||||
CreatedAt DATETIME2 NOT NULL CONSTRAINT DF_PdfAttachments_CreatedAt DEFAULT SYSUTCDATETIME(),
|
||||
CONSTRAINT FK_PdfAttachments_Instruments
|
||||
FOREIGN KEY (InstrumentId) REFERENCES dbo.Instruments(Id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
END",
|
||||
@"
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM sys.indexes
|
||||
WHERE name = N'IX_PdfAttachments_InstrumentId'
|
||||
AND object_id = OBJECT_ID(N'dbo.PdfAttachments')
|
||||
)
|
||||
BEGIN
|
||||
CREATE INDEX IX_PdfAttachments_InstrumentId
|
||||
ON dbo.PdfAttachments (InstrumentId, CreatedAt DESC);
|
||||
END",
|
||||
@"
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM sys.indexes
|
||||
WHERE name = N'UX_PdfAttachments_InstrumentId_SourceUrl'
|
||||
AND object_id = OBJECT_ID(N'dbo.PdfAttachments')
|
||||
)
|
||||
BEGIN
|
||||
CREATE UNIQUE INDEX UX_PdfAttachments_InstrumentId_SourceUrl
|
||||
ON dbo.PdfAttachments (InstrumentId, SourceUrl)
|
||||
WHERE SourceUrl IS NOT NULL AND SourceUrl <> N'';
|
||||
END"
|
||||
};
|
||||
|
||||
foreach (var script in scripts)
|
||||
{
|
||||
await using var command = new SqlCommand(script, connection)
|
||||
{
|
||||
CommandTimeout = _connectionFactory.Options.CommandTimeoutSeconds
|
||||
};
|
||||
await command.ExecuteNonQueryAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user