Skip to content

Commit

Permalink
Execute base schema script via tool (#76)
Browse files Browse the repository at this point in the history
* Code changes

* Adds fhir/dicom script separately

* Merge master

* Updated sqlServer dependency

* Code refactoring

* Removes base command

* Adds baseSchema to current command

* Removed base command name

* Addresses feedback

* Fixes the available version retry logic

* Avoid re-executing baseSchema
  • Loading branch information
rbans96 authored Sep 10, 2020
1 parent 5145ead commit a3e4bb0
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 585 deletions.
3 changes: 2 additions & 1 deletion nuget.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="packages" />
Expand All @@ -7,6 +7,7 @@
<!-- When <clear /> is present, previously defined sources are ignored -->
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="Microsoft Health OSS" value="https://microsofthealthoss.pkgs.visualstudio.com/FhirServer/_packaging/Public/nuget/v3/index.json" />
</packageSources>
<activePackageSource>
<add key="All" value="(Aggregate source)" />
Expand Down
25 changes: 10 additions & 15 deletions src/Microsoft.Health.SqlServer/Features/Schema/SchemaJobWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,10 @@ public async Task ExecuteAsync(SchemaInformation schemaInformation, string insta
{
_logger.LogInformation($"Polling started at {Clock.UtcNow}");

using (var scope = _serviceProvider.CreateScope())
{
var schemaDataStore = scope.ServiceProvider.GetRequiredService<ISchemaDataStore>();

// Ensure schemaInformation has the latest current version
schemaInformation.Current = await schemaDataStore.UpsertInstanceSchemaInformationAsync(instanceName, schemaInformation, cancellationToken);
}

while (!cancellationToken.IsCancellationRequested)
{
try
{
await Task.Delay(TimeSpan.FromSeconds(_sqlServerDataStoreConfiguration.SchemaOptions.JobPollingFrequencyInSeconds), cancellationToken);

using (var scope = _serviceProvider.CreateScope())
{
var schemaDataStore = scope.ServiceProvider.GetRequiredService<ISchemaDataStore>();
Expand All @@ -80,16 +70,21 @@ public async Task ExecuteAsync(SchemaInformation schemaInformation, string insta
await schemaDataStore.DeleteExpiredInstanceSchemaAsync(cancellationToken);
}
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
// Cancel requested.
break;
}
catch (Exception ex)
{
// The job failed.
_logger.LogError(ex, "Unhandled exception in the worker.");
}

try
{
await Task.Delay(TimeSpan.FromSeconds(_sqlServerDataStoreConfiguration.SchemaOptions.JobPollingFrequencyInSeconds), cancellationToken);
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
// Cancel requested.
break;
}
}
}
}
Expand Down
276 changes: 1 addition & 275 deletions test/Microsoft.Health.SqlServer.Web/Features/Schema/Migrations/1.sql
Original file line number Diff line number Diff line change
@@ -1,285 +1,11 @@
-- NOTE: This script DROPS AND RECREATES all database objects.
-- Style guide: please see: https://github.com/ktaranov/sqlserver-kit/blob/master/SQL%20Server%20Name%20Convention%20and%20T-SQL%20Programming%20Style.md


/*************************************************************
Drop existing objects
**************************************************************/

DECLARE @sql nvarchar(max) =''

SELECT @sql = @sql + 'DROP PROCEDURE ' + name + '; '
FROM sys.procedures

SELECT @sql = @sql + 'DROP TABLE ' + name + '; '
FROM sys.tables

SELECT @sql = @sql + 'DROP TYPE ' + name + '; '
FROM sys.table_types

SELECT @sql = @sql + 'DROP SEQUENCE ' + name + '; '
FROM sys.sequences

EXEC(@sql)

GO
-- Style guide: please see: https://github.com/ktaranov/sqlserver-kit/blob/master/SQL%20Server%20Name%20Convention%20and%20T-SQL%20Programming%20Style.md

/*************************************************************
Configure database
**************************************************************/

-- Enable RCSI
IF ((SELECT is_read_committed_snapshot_on FROM sys.databases WHERE database_id = DB_ID()) = 0) BEGIN
ALTER DATABASE CURRENT SET READ_COMMITTED_SNAPSHOT ON
END

-- Avoid blocking queries when statistics need to be rebuilt
IF ((SELECT is_auto_update_stats_async_on FROM sys.databases WHERE database_id = DB_ID()) = 0) BEGIN
ALTER DATABASE CURRENT SET AUTO_UPDATE_STATISTICS_ASYNC ON
END

-- Use ANSI behavior for null values
IF ((SELECT is_ansi_nulls_on FROM sys.databases WHERE database_id = DB_ID()) = 0) BEGIN
ALTER DATABASE CURRENT SET ANSI_NULLS ON
END

GO

/*************************************************************
Schema bootstrap
**************************************************************/
/*************************************************************
Schema Version
**************************************************************/
CREATE TABLE dbo.SchemaVersion
(
Version int PRIMARY KEY,
Status varchar(10)
)

INSERT INTO dbo.SchemaVersion
VALUES
(1, 'started')

GO

--
-- STORED PROCEDURE
-- UpsertSchemaVersion
--
-- DESCRIPTION
-- Creates or updates a new schema version entry
--
-- PARAMETERS
-- @version
-- * The version number
-- @status
-- * The status of the version
--
CREATE PROCEDURE dbo.UpsertSchemaVersion
@version int,
@status varchar(10)
AS
SET NOCOUNT ON

IF EXISTS(SELECT *
FROM dbo.SchemaVersion
WHERE Version = @version)
BEGIN
UPDATE dbo.SchemaVersion
SET Status = @status
WHERE Version = @version
END
ELSE
BEGIN
INSERT INTO dbo.SchemaVersion
(Version, Status)
VALUES
(@version, @status)
END
GO

/*************************************************************
Instance Schema
**************************************************************/
CREATE TABLE dbo.InstanceSchema
(
Name varchar(64) COLLATE Latin1_General_100_CS_AS NOT NULL,
CurrentVersion int NOT NULL,
MaxVersion int NOT NULL,
MinVersion int NOT NULL,
Timeout datetime2(0) NOT NULL
)

CREATE UNIQUE CLUSTERED INDEX IXC_InstanceSchema
ON dbo.InstanceSchema
(
Name
)

CREATE NONCLUSTERED INDEX IX_InstanceSchema_Timeout
ON dbo.InstanceSchema
(
Timeout
)

GO

--
-- STORED PROCEDURE
-- Gets schema information given its instance name.
--
-- DESCRIPTION
-- Retrieves the instance schema record from the InstanceSchema table that has the matching name.
--
-- PARAMETERS
-- @name
-- * The unique name for a particular instance
--
-- RETURN VALUE
-- The matching record.
--
CREATE PROCEDURE dbo.GetInstanceSchemaByName
@name varchar(64)
AS
SET NOCOUNT ON

SELECT CurrentVersion, MaxVersion, MinVersion, Timeout
FROM dbo.InstanceSchema
WHERE Name = @name
GO

--
-- STORED PROCEDURE
-- Update an instance schema.
--
-- DESCRIPTION
-- Modifies an existing record in the InstanceSchema table.
--
-- PARAMETERS
-- @name
-- * The unique name for a particular instance
-- @maxVersion
-- * The maximum supported schema version for the given instance
-- @minVersion
-- * The minimum supported schema version for the given instance
-- @addMinutesOnTimeout
-- * The minutes to add
--
CREATE PROCEDURE dbo.UpsertInstanceSchema
@name varchar(64),
@maxVersion int,
@minVersion int,
@addMinutesOnTimeout int

AS
SET NOCOUNT ON

DECLARE @timeout datetime2(0) = DATEADD(minute, @addMinutesOnTimeout, SYSUTCDATETIME())
DECLARE @currentVersion int = (SELECT COALESCE(MAX(Version), 0)
FROM dbo.SchemaVersion
WHERE Status = 'completed' OR Status = 'complete' AND Version <= @maxVersion)
IF EXISTS(SELECT *
FROM dbo.InstanceSchema
WHERE Name = @name)
BEGIN
UPDATE dbo.InstanceSchema
SET CurrentVersion = @currentVersion, MaxVersion = @maxVersion, Timeout = @timeout
WHERE Name = @name

SELECT @currentVersion
END
ELSE
BEGIN
INSERT INTO dbo.InstanceSchema
(Name, CurrentVersion, MaxVersion, MinVersion, Timeout)
VALUES
(@name, @currentVersion, @maxVersion, @minVersion, @timeout)

SELECT @currentVersion
END
GO

--
-- STORED PROCEDURE
-- Delete instance schema information.
--
-- DESCRIPTION
-- Delete all the expired records in the InstanceSchema table.
--
CREATE PROCEDURE dbo.DeleteInstanceSchema

AS
SET NOCOUNT ON

DELETE FROM dbo.InstanceSchema
WHERE Timeout < SYSUTCDATETIME()

GO

--
-- STORED PROCEDURE
-- SelectCompatibleSchemaVersions
--
-- DESCRIPTION
-- Selects the compatible schema versions
--
-- RETURNS
-- The maximum and minimum compatible versions
--
CREATE PROCEDURE dbo.SelectCompatibleSchemaVersions

AS
BEGIN
SET NOCOUNT ON

SELECT MAX(MinVersion), MIN(MaxVersion)
FROM dbo.InstanceSchema
WHERE Timeout > SYSUTCDATETIME()
END
GO

--
-- STORED PROCEDURE
-- SelectCurrentVersionsInformation
--
-- DESCRIPTION
-- Selects the current schema versions information
--
-- RETURNS
-- The current versions, status and server names using that version
--
CREATE PROCEDURE dbo.SelectCurrentVersionsInformation

AS
BEGIN
SET NOCOUNT ON

SELECT SV.Version, SV.Status, STRING_AGG(SCH.NAME, ',')
FROM dbo.SchemaVersion AS SV LEFT OUTER JOIN dbo.InstanceSchema AS SCH
ON SV.Version = SCH.CurrentVersion
GROUP BY Version, Status

END
GO

--
-- STORED PROCEDURE
-- SelectCurrentSchemaVersion
--
-- DESCRIPTION
-- Selects the current completed schema version
--
-- RETURNS
-- The current version as a result set
--
CREATE PROCEDURE dbo.SelectCurrentSchemaVersion
AS
BEGIN
SET NOCOUNT ON

SELECT MAX(Version)
FROM SchemaVersion
WHERE Status = 'completed'
END
GO
Loading

0 comments on commit a3e4bb0

Please sign in to comment.