in src/Microsoft.Health.Fhir.SqlServer/Features/Storage/SqlServerFhirModel.cs [218:366]
private async Task InitializeBase(CancellationToken cancellationToken)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync(cancellationToken: cancellationToken))
{
connection.Open();
// Synchronous calls are used because this code is executed on startup and doesn't need to be async.
// Additionally, XUnit task scheduler constraints prevent async calls from being easily tested.
using (SqlCommand sqlCommand = connection.CreateCommand())
{
sqlCommand.CommandText = @"
SET XACT_ABORT ON
BEGIN TRANSACTION
INSERT INTO dbo.ResourceType (Name)
SELECT value FROM string_split(@resourceTypes, ',')
EXCEPT SELECT Name FROM dbo.ResourceType WITH (TABLOCKX);
-- result set 1
SELECT ResourceTypeId, Name FROM dbo.ResourceType;
INSERT INTO dbo.SearchParam (Uri)
SELECT * FROM OPENJSON (@searchParams)
WITH (Uri varchar(128) '$.Uri')
EXCEPT SELECT Uri FROM dbo.SearchParam;
-- result set 2
SELECT Uri, SearchParamId FROM dbo.SearchParam;
INSERT INTO dbo.ClaimType (Name)
SELECT value FROM string_split(@claimTypes, ',')
EXCEPT SELECT Name FROM dbo.ClaimType;
-- result set 3
SELECT ClaimTypeId, Name FROM dbo.ClaimType;
INSERT INTO dbo.CompartmentType (Name)
SELECT value FROM string_split(@compartmentTypes, ',')
EXCEPT SELECT Name FROM dbo.CompartmentType;
-- result set 4
SELECT CompartmentTypeId, Name FROM dbo.CompartmentType;
COMMIT TRANSACTION
-- result set 5
SELECT Value, SystemId from dbo.System;
-- result set 6
SELECT Value, QuantityCodeId FROM dbo.QuantityCode";
string searchParametersJson = JsonConvert.SerializeObject(_searchParameterDefinitionManager.AllSearchParameters.Select(p => new { Uri = p.Url }));
string commaSeparatedResourceTypes = string.Join(",", ModelInfoProvider.GetResourceTypeNames());
string commaSeparatedClaimTypes = string.Join(',', _securityConfiguration.PrincipalClaims);
string commaSeparatedCompartmentTypes = string.Join(',', ModelInfoProvider.GetCompartmentTypeNames());
sqlCommand.Parameters.AddWithValue("@searchParams", searchParametersJson);
sqlCommand.Parameters.AddWithValue("@resourceTypes", commaSeparatedResourceTypes);
sqlCommand.Parameters.AddWithValue("@claimTypes", commaSeparatedClaimTypes);
sqlCommand.Parameters.AddWithValue("@compartmentTypes", commaSeparatedCompartmentTypes);
using (SqlDataReader reader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess))
{
var resourceTypeToId = new Dictionary<string, short>(StringComparer.Ordinal);
var resourceTypeIdToTypeName = new Dictionary<short, string>();
var searchParamUriToId = new Dictionary<Uri, short>();
var systemToId = new ConcurrentDictionary<string, int>(StringComparer.OrdinalIgnoreCase);
var quantityCodeToId = new ConcurrentDictionary<string, int>(StringComparer.OrdinalIgnoreCase);
var claimNameToId = new Dictionary<string, byte>(StringComparer.Ordinal);
var compartmentTypeToId = new Dictionary<string, byte>();
// result set 1
short lowestResourceTypeId = short.MaxValue;
short highestResourceTypeId = short.MinValue;
while (reader.Read())
{
(short id, string resourceTypeName) = reader.ReadRow(VLatest.ResourceType.ResourceTypeId, VLatest.ResourceType.Name);
resourceTypeToId.Add(resourceTypeName, id);
if (id > highestResourceTypeId)
{
highestResourceTypeId = id;
}
if (id < lowestResourceTypeId)
{
lowestResourceTypeId = id;
}
resourceTypeIdToTypeName.Add(id, resourceTypeName);
}
// result set 2
reader.NextResult();
while (reader.Read())
{
(string uri, short searchParamId) = reader.ReadRow(VLatest.SearchParam.Uri, VLatest.SearchParam.SearchParamId);
searchParamUriToId.Add(new Uri(uri), searchParamId);
}
// result set 3
reader.NextResult();
while (reader.Read())
{
(byte id, string claimTypeName) = reader.ReadRow(VLatest.ClaimType.ClaimTypeId, VLatest.ClaimType.Name);
claimNameToId.Add(claimTypeName, id);
}
// result set 4
reader.NextResult();
while (reader.Read())
{
(byte id, string compartmentName) = reader.ReadRow(VLatest.CompartmentType.CompartmentTypeId, VLatest.CompartmentType.Name);
compartmentTypeToId.Add(compartmentName, id);
}
// result set 5
reader.NextResult();
while (reader.Read())
{
var (value, systemId) = reader.ReadRow(VLatest.System.Value, VLatest.System.SystemId);
systemToId.TryAdd(value, systemId);
}
// result set 6
reader.NextResult();
while (reader.Read())
{
(string value, int quantityCodeId) = reader.ReadRow(VLatest.QuantityCode.Value, VLatest.QuantityCode.QuantityCodeId);
quantityCodeToId.TryAdd(value, quantityCodeId);
}
_resourceTypeToId = resourceTypeToId;
_resourceTypeIdToTypeName = resourceTypeIdToTypeName;
_searchParamUriToId = searchParamUriToId;
_systemToId = systemToId;
_quantityCodeToId = quantityCodeToId;
_claimNameToId = claimNameToId;
_compartmentTypeToId = compartmentTypeToId;
_resourceTypeIdRange = (lowestResourceTypeId, highestResourceTypeId);
}
}
}
}