public SqlIndexDataStoreV2( SqlConnectionWrapperFactory sqlConnectionWrapperFactory) : base(sqlConnectionWrapperFactory) { EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); _sqlConnectionFactoryWrapper = sqlConnectionWrapperFactory; }
public override async Task <IReadOnlyList <WatermarkRange> > GetInstanceBatchesAsync( int batchSize, int batchCount, IndexStatus indexStatus, long?maxWatermark = null, CancellationToken cancellationToken = default) { EnsureArg.IsGt(batchSize, 0, nameof(batchSize)); EnsureArg.IsGt(batchCount, 0, nameof(batchCount)); using SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); VLatest.GetInstanceBatches.PopulateCommand(sqlCommandWrapper, batchSize, batchCount, (byte)indexStatus, maxWatermark); try { var batches = new List <WatermarkRange>(); using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); while (await reader.ReadAsync(cancellationToken)) { batches.Add(new WatermarkRange(reader.GetInt64(0), reader.GetInt64(1))); } return(batches); } catch (SqlException ex) { throw new DataStoreException(ex); } }
public SqlServerSearchService( ISearchOptionsFactory searchOptionsFactory, IFhirDataStore fhirDataStore, SqlServerFhirModel model, SqlRootExpressionRewriter sqlRootExpressionRewriter, ChainFlatteningRewriter chainFlatteningRewriter, StringOverflowRewriter stringOverflowRewriter, SqlConnectionWrapperFactory sqlConnectionWrapperFactory, ILogger <SqlServerSearchService> logger) : base(searchOptionsFactory, fhirDataStore) { EnsureArg.IsNotNull(sqlRootExpressionRewriter, nameof(sqlRootExpressionRewriter)); EnsureArg.IsNotNull(chainFlatteningRewriter, nameof(chainFlatteningRewriter)); EnsureArg.IsNotNull(stringOverflowRewriter, nameof(stringOverflowRewriter)); EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(logger, nameof(logger)); _model = model; _sqlRootExpressionRewriter = sqlRootExpressionRewriter; _chainFlatteningRewriter = chainFlatteningRewriter; _stringOverflowRewriter = stringOverflowRewriter; _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _logger = logger; _isResultPartial = false; }
public SqlServerSearchService( ISearchOptionsFactory searchOptionsFactory, IFhirDataStore fhirDataStore, SqlServerFhirModel model, SqlRootExpressionRewriter sqlRootExpressionRewriter, ChainFlatteningRewriter chainFlatteningRewriter, SortRewriter sortRewriter, SqlConnectionWrapperFactory sqlConnectionWrapperFactory, SchemaInformation schemaInformation, ISortingValidator sortingValidator, IFhirRequestContextAccessor requestContextAccessor, ILogger <SqlServerSearchService> logger) : base(searchOptionsFactory, fhirDataStore) { EnsureArg.IsNotNull(sqlRootExpressionRewriter, nameof(sqlRootExpressionRewriter)); EnsureArg.IsNotNull(chainFlatteningRewriter, nameof(chainFlatteningRewriter)); EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(schemaInformation, nameof(schemaInformation)); EnsureArg.IsNotNull(sortingValidator, nameof(sortingValidator)); EnsureArg.IsNotNull(requestContextAccessor, nameof(requestContextAccessor)); EnsureArg.IsNotNull(logger, nameof(logger)); _model = model; _sqlRootExpressionRewriter = sqlRootExpressionRewriter; _sortRewriter = sortRewriter; _chainFlatteningRewriter = chainFlatteningRewriter; _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _logger = logger; _schemaInformation = schemaInformation; _sortingValidator = sortingValidator; _requestContextAccessor = requestContextAccessor; }
public SqlServerSearchService( ISearchOptionsFactory searchOptionsFactory, IFhirDataStore fhirDataStore, SqlServerFhirModel model, SqlRootExpressionRewriter sqlRootExpressionRewriter, ChainFlatteningRewriter chainFlatteningRewriter, StringOverflowRewriter stringOverflowRewriter, SortRewriter sortRewriter, SqlConnectionWrapperFactory sqlConnectionWrapperFactory, ILogger <SqlServerSearchService> logger, SchemaInformation schemaInformation) : base(searchOptionsFactory, fhirDataStore) { EnsureArg.IsNotNull(sqlRootExpressionRewriter, nameof(sqlRootExpressionRewriter)); EnsureArg.IsNotNull(chainFlatteningRewriter, nameof(chainFlatteningRewriter)); EnsureArg.IsNotNull(stringOverflowRewriter, nameof(stringOverflowRewriter)); EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(logger, nameof(logger)); EnsureArg.IsNotNull(schemaInformation, nameof(schemaInformation)); _model = model; _sqlRootExpressionRewriter = sqlRootExpressionRewriter; _sortRewriter = sortRewriter; _chainFlatteningRewriter = chainFlatteningRewriter; _stringOverflowRewriter = stringOverflowRewriter; _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _logger = logger; _isResultPartial = false; // Initialise supported sort params with SQL related values SearchParameterInfoExtensions.AppendSearchParameterInfoExtensions(SupportedSortParameterNames.Names); _schemaInformation = schemaInformation; }
public override async Task ReindexInstanceAsync(DicomDataset instance, long watermark, IEnumerable <QueryTag> queryTags, CancellationToken cancellationToken = default) { EnsureArg.IsNotNull(instance, nameof(instance)); EnsureArg.IsNotNull(queryTags, nameof(queryTags)); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { var rows = ExtendedQueryTagDataRowsBuilder.Build(instance, queryTags, Version); VLatest.IndexInstanceV2TableValuedParameters parameters = new VLatest.IndexInstanceV2TableValuedParameters( rows.StringRows, rows.LongRows, rows.DoubleRows, rows.DateTimeWithUtcRows, rows.PersonNameRows); VLatest.IndexInstanceV2.PopulateCommand(sqlCommandWrapper, watermark, parameters); try { await sqlCommandWrapper.ExecuteNonQueryAsync(cancellationToken); } catch (SqlException ex) { throw ex.Number switch { SqlErrorCodes.NotFound => new InstanceNotFoundException(), SqlErrorCodes.Conflict => new PendingInstanceException(), _ => new DataStoreException(ex), }; } } }
public SqlServerSearchService( ISearchOptionsFactory searchOptionsFactory, IFhirDataStore fhirDataStore, ISqlServerFhirModel model, SqlRootExpressionRewriter sqlRootExpressionRewriter, ChainFlatteningRewriter chainFlatteningRewriter, SortRewriter sortRewriter, PartitionEliminationRewriter partitionEliminationRewriter, SqlConnectionWrapperFactory sqlConnectionWrapperFactory, SchemaInformation schemaInformation, RequestContextAccessor <IFhirRequestContext> requestContextAccessor, ICompressedRawResourceConverter compressedRawResourceConverter, ILogger <SqlServerSearchService> logger) : base(searchOptionsFactory, fhirDataStore) { EnsureArg.IsNotNull(sqlRootExpressionRewriter, nameof(sqlRootExpressionRewriter)); EnsureArg.IsNotNull(chainFlatteningRewriter, nameof(chainFlatteningRewriter)); EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(schemaInformation, nameof(schemaInformation)); EnsureArg.IsNotNull(partitionEliminationRewriter, nameof(partitionEliminationRewriter)); EnsureArg.IsNotNull(requestContextAccessor, nameof(requestContextAccessor)); EnsureArg.IsNotNull(logger, nameof(logger)); _model = model; _sqlRootExpressionRewriter = sqlRootExpressionRewriter; _sortRewriter = sortRewriter; _partitionEliminationRewriter = partitionEliminationRewriter; _chainFlatteningRewriter = chainFlatteningRewriter; _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _logger = logger; _schemaInformation = schemaInformation; _requestContextAccessor = requestContextAccessor; _compressedRawResourceConverter = compressedRawResourceConverter; }
public SqlExtendedQueryTagErrorStoreV4( SqlConnectionWrapperFactory sqlConnectionWrapperFactory, ILogger <SqlExtendedQueryTagErrorStoreV4> logger) { ConnectionWrapperFactory = EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); Logger = EnsureArg.IsNotNull(logger, nameof(logger)); }
public SqlServerFhirStorageTestsFixture() { var initialConnectionString = Environment.GetEnvironmentVariable("SqlServer:ConnectionString") ?? LocalConnectionString; _databaseName = $"FHIRINTEGRATIONTEST_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}_{BigInteger.Abs(new BigInteger(Guid.NewGuid().ToByteArray()))}"; _masterConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = "master" }.ToString(); TestConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = _databaseName }.ToString(); var config = new SqlServerDataStoreConfiguration { ConnectionString = TestConnectionString, Initialize = true }; var schemaUpgradeRunner = new SchemaUpgradeRunner(config, NullLogger <SchemaUpgradeRunner> .Instance); var schemaInformation = new SchemaInformation(); _schemaInitializer = new SchemaInitializer(config, schemaUpgradeRunner, schemaInformation, NullLogger <SchemaInitializer> .Instance); var searchParameterDefinitionManager = Substitute.For <ISearchParameterDefinitionManager>(); searchParameterDefinitionManager.AllSearchParameters.Returns(new[] { new SearchParameter { Name = SearchParameterNames.Id, Type = SearchParamType.Token, Url = SearchParameterNames.IdUri.ToString() }.ToInfo(), new SearchParameter { Name = SearchParameterNames.LastUpdated, Type = SearchParamType.Date, Url = SearchParameterNames.LastUpdatedUri.ToString() }.ToInfo(), }); var securityConfiguration = new SecurityConfiguration { PrincipalClaims = { "oid" } }; var sqlServerFhirModel = new SqlServerFhirModel(config, schemaInformation, searchParameterDefinitionManager, Options.Create(securityConfiguration), NullLogger <SqlServerFhirModel> .Instance); var serviceCollection = new ServiceCollection(); serviceCollection.AddSqlServerTableRowParameterGenerators(); serviceCollection.AddSingleton(sqlServerFhirModel); ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); var upsertResourceTvpGenerator = serviceProvider.GetRequiredService <V1.UpsertResourceTvpGenerator <ResourceMetadata> >(); var searchParameterToSearchValueTypeMap = new SearchParameterToSearchValueTypeMap(searchParameterDefinitionManager); SqlTransactionHandler = new SqlTransactionHandler(); SqlConnectionWrapperFactory = new SqlConnectionWrapperFactory(config, SqlTransactionHandler); _fhirDataStore = new SqlServerFhirDataStore(config, sqlServerFhirModel, searchParameterToSearchValueTypeMap, upsertResourceTvpGenerator, Options.Create(new CoreFeatureConfiguration()), SqlConnectionWrapperFactory, NullLogger <SqlServerFhirDataStore> .Instance); _testHelper = new SqlServerFhirStorageTestHelper(TestConnectionString); }
// Only 1 public constructor is allowed for test fixture. internal SqlDataStoreTestsFixture(string databaseName) { EnsureArg.IsNotNullOrEmpty(databaseName, nameof(databaseName)); _databaseName = databaseName; string initialConnectionString = Environment.GetEnvironmentVariable("SqlServer:ConnectionString") ?? LocalConnectionString; _masterConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = "master" }.ToString(); TestConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = _databaseName }.ToString(); var config = new SqlServerDataStoreConfiguration { ConnectionString = TestConnectionString, Initialize = true, SchemaOptions = new SqlServerSchemaOptions { AutomaticUpdatesEnabled = true, }, }; var scriptProvider = new ScriptProvider <SchemaVersion>(); var baseScriptProvider = new BaseScriptProvider(); var mediator = Substitute.For <IMediator>(); var sqlConnectionStringProvider = new DefaultSqlConnectionStringProvider(config); var sqlConnectionFactory = new DefaultSqlConnectionFactory(sqlConnectionStringProvider); var schemaManagerDataStore = new SchemaManagerDataStore(sqlConnectionFactory); var schemaUpgradeRunner = new SchemaUpgradeRunner(scriptProvider, baseScriptProvider, mediator, NullLogger <SchemaUpgradeRunner> .Instance, sqlConnectionFactory, schemaManagerDataStore); var schemaInformation = new SchemaInformation(SchemaVersionConstants.Min, SchemaVersionConstants.Max); _schemaInitializer = new SchemaInitializer(config, schemaUpgradeRunner, schemaInformation, sqlConnectionFactory, sqlConnectionStringProvider, NullLogger <SchemaInitializer> .Instance); SqlTransactionHandler = new SqlTransactionHandler(); SqlConnectionWrapperFactory = new SqlConnectionWrapperFactory(SqlTransactionHandler, new SqlCommandWrapperFactory(), sqlConnectionFactory); SqlIndexDataStoreFactory = new SqlIndexDataStoreFactory( schemaInformation, new[] { new SqlIndexDataStoreV1(SqlConnectionWrapperFactory), new SqlIndexDataStoreV2(SqlConnectionWrapperFactory) }); InstanceStore = new SqlInstanceStore(SqlConnectionWrapperFactory); ExtendedQueryTagStore = new SqlExtendedQueryTagStore(SqlConnectionWrapperFactory, schemaInformation, NullLogger <SqlExtendedQueryTagStore> .Instance); TestHelper = new SqlIndexDataStoreTestHelper(TestConnectionString); }
public SqlDataStoreTestsFixture() { string initialConnectionString = Environment.GetEnvironmentVariable("SqlServer:ConnectionString") ?? LocalConnectionString; _databaseName = $"DICOMINTEGRATIONTEST_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}_{BigInteger.Abs(new BigInteger(Guid.NewGuid().ToByteArray()))}"; _masterConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = "master" }.ToString(); TestConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = _databaseName }.ToString(); var config = new SqlServerDataStoreConfiguration { ConnectionString = TestConnectionString, Initialize = true, SchemaOptions = new SqlServerSchemaOptions { AutomaticUpdatesEnabled = true, }, }; var scriptProvider = new ScriptProvider <SchemaVersion>(); var baseScriptProvider = new BaseScriptProvider(); var mediator = Substitute.For <IMediator>(); var sqlConnectionStringProvider = new DefaultSqlConnectionStringProvider(config); var sqlConnectionFactory = new DefaultSqlConnectionFactory(sqlConnectionStringProvider); var schemaManagerDataStore = new SchemaManagerDataStore(sqlConnectionFactory); var schemaUpgradeRunner = new SchemaUpgradeRunner(scriptProvider, baseScriptProvider, mediator, NullLogger <SchemaUpgradeRunner> .Instance, sqlConnectionFactory, schemaManagerDataStore); var schemaInformation = new SchemaInformation((int)SchemaVersion.V1, (int)SchemaVersion.V1); _schemaInitializer = new SchemaInitializer(config, schemaUpgradeRunner, schemaInformation, sqlConnectionFactory, sqlConnectionStringProvider, NullLogger <SchemaInitializer> .Instance); var dicomSqlIndexSchema = new SqlIndexSchema(schemaInformation, NullLogger <SqlIndexSchema> .Instance); SqlTransactionHandler = new SqlTransactionHandler(); SqlConnectionWrapperFactory = new SqlConnectionWrapperFactory(SqlTransactionHandler, new SqlCommandWrapperFactory(), sqlConnectionFactory); IndexDataStore = new SqlIndexDataStore( dicomSqlIndexSchema, SqlConnectionWrapperFactory); InstanceStore = new SqlInstanceStore(SqlConnectionWrapperFactory); TestHelper = new SqlIndexDataStoreTestHelper(TestConnectionString); }
public override async Task <long> BeginCreateInstanceIndexAsync(int partitionKey, DicomDataset instance, IEnumerable <QueryTag> queryTags, CancellationToken cancellationToken) { EnsureArg.IsNotNull(instance, nameof(instance)); EnsureArg.IsNotNull(queryTags, nameof(queryTags)); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { var rows = ExtendedQueryTagDataRowsBuilder.Build(instance, queryTags.Where(tag => tag.IsExtendedQueryTag), Version); VLatest.AddInstanceV6TableValuedParameters parameters = new VLatest.AddInstanceV6TableValuedParameters( rows.StringRows, rows.LongRows, rows.DoubleRows, rows.DateTimeWithUtcRows, rows.PersonNameRows ); VLatest.AddInstanceV6.PopulateCommand( sqlCommandWrapper, partitionKey, instance.GetString(DicomTag.StudyInstanceUID), instance.GetString(DicomTag.SeriesInstanceUID), instance.GetString(DicomTag.SOPInstanceUID), instance.GetSingleValueOrDefault <string>(DicomTag.PatientID), instance.GetSingleValueOrDefault <string>(DicomTag.PatientName), instance.GetSingleValueOrDefault <string>(DicomTag.ReferringPhysicianName), instance.GetStringDateAsDate(DicomTag.StudyDate), instance.GetSingleValueOrDefault <string>(DicomTag.StudyDescription), instance.GetSingleValueOrDefault <string>(DicomTag.AccessionNumber), instance.GetSingleValueOrDefault <string>(DicomTag.Modality), instance.GetStringDateAsDate(DicomTag.PerformedProcedureStepStartDate), instance.GetStringDateAsDate(DicomTag.PatientBirthDate), instance.GetSingleValueOrDefault <string>(DicomTag.ManufacturerModelName), (byte)IndexStatus.Creating, parameters); try { return((long)(await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken))); } catch (SqlException ex) { if (ex.Number == SqlErrorCodes.Conflict) { if (ex.State == (byte)IndexStatus.Creating) { throw new PendingInstanceException(); } throw new InstanceAlreadyExistsException(); } throw new DataStoreException(ex); } } }
public SqlExtendedQueryTagStoreV2( SqlConnectionWrapperFactory sqlConnectionWrapperFactory, ILogger <SqlExtendedQueryTagStoreV2> logger) { EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(logger, nameof(logger)); ConnectionWrapperFactory = sqlConnectionWrapperFactory; Logger = logger; }
public SqlIndexDataStore( SqlIndexSchema indexSchema, SqlConnectionWrapperFactory sqlConnectionWrapperFactory) { EnsureArg.IsNotNull(indexSchema, nameof(indexSchema)); EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); _sqlServerIndexSchema = indexSchema; _sqlConnectionFactoryWrapper = sqlConnectionWrapperFactory; }
/// <summary> /// Creates a new instance of the <see cref="SqlServerFhirResourceChangeDataStore"/> class. /// </summary> /// <param name="sqlConnectionWrapperFactory">The SQL Connection wrapper factory.</param> /// <param name="logger">The logger.</param> /// <param name="schemaInformation">The database schema information.</param> public SqlServerFhirResourceChangeDataStore(SqlConnectionWrapperFactory sqlConnectionWrapperFactory, ILogger <SqlServerFhirResourceChangeDataStore> logger, SchemaInformation schemaInformation) { EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(logger, nameof(logger)); EnsureArg.IsNotNull(schemaInformation, nameof(schemaInformation)); _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _logger = logger; _schemaInformation = schemaInformation; }
public SqlQueryStore( SqlConnectionWrapperFactory sqlConnectionWrapperFactory, ILogger <SqlQueryStore> logger) { EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(logger, nameof(logger)); _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _logger = logger; }
public SqlServerSchemaDataStore( SqlConnectionWrapperFactory sqlConnectionWrapperFactory, SqlServerDataStoreConfiguration sqlServerDataStoreConfiguration, ILogger <SqlServerSchemaDataStore> logger) { EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(sqlServerDataStoreConfiguration, nameof(sqlServerDataStoreConfiguration)); EnsureArg.IsNotNull(logger, nameof(logger)); _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _configuration = sqlServerDataStoreConfiguration; _logger = logger; }
public SqlServerBulkImportOperationTests() { var operationsConfiguration = Substitute.For <IOptions <OperationsConfiguration> >(); operationsConfiguration.Value.Returns(new OperationsConfiguration()); var schemaInformation = new SchemaInformation(SchemaVersionConstants.Min, SchemaVersionConstants.Max); SqlTransactionHandler sqlTransactionHandler = new SqlTransactionHandler(); SqlConnectionWrapperFactory sqlConnectionWrapperFactory = new SqlConnectionWrapperFactory(Substitute.For <SqlTransactionHandler>(), new SqlCommandWrapperFactory(), Substitute.For <ISqlConnectionFactory>()); var sqlServerTransient = Substitute.For <ISqlServerTransientFaultRetryPolicyFactory>(); _sqlServerFhirDataBulkOperation = new SqlImportOperation(sqlConnectionWrapperFactory, sqlServerTransient, Substitute.For <ISqlServerFhirModel>(), operationsConfiguration, schemaInformation, NullLogger <SqlImportOperation> .Instance); }
public SqlExtendedQueryTagStore( SqlConnectionWrapperFactory sqlConnectionWrapperFactory, SchemaInformation schemaInformation, ILogger <SqlExtendedQueryTagStore> logger) { EnsureArg.IsNotNull(sqlConnectionWrapperFactory, nameof(sqlConnectionWrapperFactory)); EnsureArg.IsNotNull(schemaInformation, nameof(schemaInformation)); EnsureArg.IsNotNull(logger, nameof(logger)); _sqlConnectionWrapperFactory = sqlConnectionWrapperFactory; _schemaInformation = schemaInformation; _logger = logger; }
public SqlServerFhirResourceChangeDataStore GetResourcChangeDataStoreWithGivenConnectionString(string connectionString) { var schemaOptions = new SqlServerSchemaOptions { AutomaticUpdatesEnabled = true }; var config = Options.Create(new SqlServerDataStoreConfiguration { ConnectionString = connectionString, Initialize = true, SchemaOptions = schemaOptions, StatementTimeout = TimeSpan.FromMinutes(10) }); var sqlConnectionStringProvider = new DefaultSqlConnectionStringProvider(config); var sqlConnectionBuilder = new DefaultSqlConnectionBuilder(sqlConnectionStringProvider, config); var sqlConnectionWrapperFactory = new SqlConnectionWrapperFactory(new SqlTransactionHandler(), new SqlCommandWrapperFactory(), sqlConnectionBuilder); var schemaInformation = new SchemaInformation(SchemaVersionConstants.Min, SchemaVersionConstants.Max); schemaInformation.Current = SchemaVersionConstants.Max; return(new SqlServerFhirResourceChangeDataStore(sqlConnectionWrapperFactory, NullLogger <SqlServerFhirResourceChangeDataStore> .Instance, schemaInformation)); }
public override async Task <IEnumerable <VersionedInstanceIdentifier> > RetrieveDeletedInstancesAsync(int batchSize, int maxRetries, CancellationToken cancellationToken = default) { var results = new List <VersionedInstanceIdentifier>(); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.RetrieveDeletedInstanceV6.PopulateCommand( sqlCommandWrapper, batchSize, maxRetries); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { try { while (await reader.ReadAsync(cancellationToken)) { (int partitionKey, string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, long watermark) = reader.ReadRow( VLatest.DeletedInstance.PartitionKey, VLatest.DeletedInstance.StudyInstanceUid, VLatest.DeletedInstance.SeriesInstanceUid, VLatest.DeletedInstance.SopInstanceUid, VLatest.DeletedInstance.Watermark); results.Add(new VersionedInstanceIdentifier( studyInstanceUid, seriesInstanceUid, sopInstanceUid, watermark, partitionKey)); } } catch (SqlException ex) { throw new DataStoreException(ex); } } } return(results); }
private async Task DeleteInstanceAsync(int partitionKey, string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, DateTimeOffset cleanupAfter, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.DeleteInstanceV6.PopulateCommand( sqlCommandWrapper, cleanupAfter, (byte)IndexStatus.Created, partitionKey, studyInstanceUid, seriesInstanceUid, sopInstanceUid); try { await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken); } catch (SqlException ex) { switch (ex.Number) { case SqlErrorCodes.NotFound: if (!string.IsNullOrEmpty(sopInstanceUid)) { throw new InstanceNotFoundException(); } if (!string.IsNullOrEmpty(seriesInstanceUid)) { throw new SeriesNotFoundException(); } throw new StudyNotFoundException(); default: throw new DataStoreException(ex); } } } }
private async Task <IEnumerable <VersionedInstanceIdentifier> > GetInstanceIdentifierImp( int partitionKey, string studyInstanceUid, CancellationToken cancellationToken, string seriesInstanceUid = null, string sopInstanceUid = null) { var results = new List <VersionedInstanceIdentifier>(); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetInstanceV6.PopulateCommand( sqlCommandWrapper, validStatus: (byte)IndexStatus.Created, partitionKey, studyInstanceUid, seriesInstanceUid, sopInstanceUid); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (string rStudyInstanceUid, string rSeriesInstanceUid, string rSopInstanceUid, long watermark) = reader.ReadRow( VLatest.Instance.StudyInstanceUid, VLatest.Instance.SeriesInstanceUid, VLatest.Instance.SopInstanceUid, VLatest.Instance.Watermark); results.Add(new VersionedInstanceIdentifier( rStudyInstanceUid, rSeriesInstanceUid, rSopInstanceUid, watermark)); } } } return(results); }
public override async Task <IReadOnlyCollection <ChangeFeedEntry> > GetChangeFeedAsync(long offset, int limit, CancellationToken cancellationToken) { var results = new List <ChangeFeedEntry>(); using SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); VLatest.GetChangeFeedV6.PopulateCommand(sqlCommandWrapper, limit, offset); using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken); while (await reader.ReadAsync(cancellationToken)) { (long rSeq, DateTimeOffset rTimestamp, int rAction, string rPartitionName, string rStudyInstanceUid, string rSeriesInstanceUid, string rSopInstanceUid, long oWatermark, long?cWatermark) = reader.ReadRow( VLatest.ChangeFeed.Sequence, VLatest.ChangeFeed.Timestamp, VLatest.ChangeFeed.Action, VLatest.Partition.PartitionName, VLatest.ChangeFeed.StudyInstanceUid, VLatest.ChangeFeed.SeriesInstanceUid, VLatest.ChangeFeed.SopInstanceUid, VLatest.ChangeFeed.OriginalWatermark, VLatest.ChangeFeed.CurrentWatermark); results.Add(new ChangeFeedEntry( rSeq, rTimestamp, (ChangeFeedAction)rAction, rStudyInstanceUid, rSeriesInstanceUid, rSopInstanceUid, oWatermark, cWatermark, ConvertWatermarkToCurrentState(oWatermark, cWatermark), rPartitionName)); } return(results); }
public override async Task EndCreateInstanceIndexAsync( int partitionKey, DicomDataset dicomDataset, long watermark, IEnumerable <QueryTag> queryTags, bool allowExpiredTags = false, CancellationToken cancellationToken = default) { EnsureArg.IsNotNull(dicomDataset, nameof(dicomDataset)); EnsureArg.IsNotNull(queryTags, nameof(queryTags)); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.UpdateInstanceStatusV6.PopulateCommand( sqlCommandWrapper, partitionKey, dicomDataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty), dicomDataset.GetSingleValueOrDefault(DicomTag.SeriesInstanceUID, string.Empty), dicomDataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty), watermark, (byte)IndexStatus.Created, allowExpiredTags ? null : ExtendedQueryTagDataRowsBuilder.GetMaxTagKey(queryTags)); try { await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken); } catch (SqlException ex) { throw ex.Number switch { SqlErrorCodes.NotFound => new InstanceNotFoundException(), SqlErrorCodes.Conflict when ex.State == 10 => new ExtendedQueryTagsOutOfDateException(), _ => new DataStoreException(ex), }; } } }
public override async Task <QueryResult> QueryAsync( int partitionKey, QueryExpression query, CancellationToken cancellationToken) { EnsureArg.IsNotNull(query, nameof(query)); var results = new List <VersionedInstanceIdentifier>(query.EvaluatedLimit); using SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); var stringBuilder = new IndentedStringBuilder(new StringBuilder()); var sqlQueryGenerator = new SqlQueryGenerator(stringBuilder, query, new SqlQueryParameterManager(sqlCommandWrapper.Parameters), Version, partitionKey); sqlCommandWrapper.CommandText = stringBuilder.ToString(); LogSqlCommand(sqlCommandWrapper); using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken); while (await reader.ReadAsync(cancellationToken)) { (string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, long watermark) = reader.ReadRow( VLatest.Instance.StudyInstanceUid, VLatest.Instance.SeriesInstanceUid, VLatest.Instance.SopInstanceUid, VLatest.Instance.Watermark); results.Add(new VersionedInstanceIdentifier( studyInstanceUid, seriesInstanceUid, sopInstanceUid, watermark)); } return(new QueryResult(results)); }
public override async Task DeleteDeletedInstanceAsync(VersionedInstanceIdentifier versionedInstanceIdentifier, CancellationToken cancellationToken = default) { using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.DeleteDeletedInstanceV6.PopulateCommand( sqlCommandWrapper, versionedInstanceIdentifier.PartitionKey, versionedInstanceIdentifier.StudyInstanceUid, versionedInstanceIdentifier.SeriesInstanceUid, versionedInstanceIdentifier.SopInstanceUid, versionedInstanceIdentifier.Version); try { await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken); } catch (SqlException ex) { throw new DataStoreException(ex); } } }
public override async Task <IReadOnlyList <VersionedInstanceIdentifier> > GetInstanceIdentifiersByWatermarkRangeAsync( WatermarkRange watermarkRange, IndexStatus indexStatus, CancellationToken cancellationToken = default) { var results = new List <VersionedInstanceIdentifier>(); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetInstancesByWatermarkRange.PopulateCommand( sqlCommandWrapper, watermarkRange.Start, watermarkRange.End, (byte)indexStatus); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (string rStudyInstanceUid, string rSeriesInstanceUid, string rSopInstanceUid, long watermark) = reader.ReadRow( VLatest.Instance.StudyInstanceUid, VLatest.Instance.SeriesInstanceUid, VLatest.Instance.SopInstanceUid, VLatest.Instance.Watermark); results.Add(new VersionedInstanceIdentifier( rStudyInstanceUid, rSeriesInstanceUid, rSopInstanceUid, watermark)); } } } return(results); }
public override async Task <int> IncrementDeletedInstanceRetryAsync(VersionedInstanceIdentifier versionedInstanceIdentifier, DateTimeOffset cleanupAfter, CancellationToken cancellationToken = default) { using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.IncrementDeletedInstanceRetryV6.PopulateCommand( sqlCommandWrapper, versionedInstanceIdentifier.PartitionKey, versionedInstanceIdentifier.StudyInstanceUid, versionedInstanceIdentifier.SeriesInstanceUid, versionedInstanceIdentifier.SopInstanceUid, versionedInstanceIdentifier.Version, cleanupAfter); try { return((int)(await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken))); } catch (SqlException ex) { throw new DataStoreException(ex); } } }
public SqlServerFhirStorageTestsFixture() { var initialConnectionString = Environment.GetEnvironmentVariable("SqlServer:ConnectionString") ?? LocalConnectionString; _databaseName = $"FHIRINTEGRATIONTEST_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}_{BigInteger.Abs(new BigInteger(Guid.NewGuid().ToByteArray()))}"; TestConnectionString = new SqlConnectionStringBuilder(initialConnectionString) { InitialCatalog = _databaseName }.ToString(); var schemaOptions = new SqlServerSchemaOptions { AutomaticUpdatesEnabled = true }; var config = new SqlServerDataStoreConfiguration { ConnectionString = TestConnectionString, Initialize = true, SchemaOptions = schemaOptions }; var schemaInformation = new SchemaInformation(SchemaVersionConstants.Min, SchemaVersionConstants.Max); var scriptProvider = new ScriptProvider <SchemaVersion>(); var baseScriptProvider = new BaseScriptProvider(); var mediator = Substitute.For <IMediator>(); var sqlConnectionFactory = new DefaultSqlConnectionFactory(config); var schemaUpgradeRunner = new SchemaUpgradeRunner(scriptProvider, baseScriptProvider, mediator, NullLogger <SchemaUpgradeRunner> .Instance, sqlConnectionFactory); _schemaInitializer = new SchemaInitializer(config, schemaUpgradeRunner, schemaInformation, sqlConnectionFactory, NullLogger <SchemaInitializer> .Instance); var searchParameterDefinitionManager = new SearchParameterDefinitionManager(ModelInfoProvider.Instance); _filebasedSearchParameterStatusDataStore = new FilebasedSearchParameterStatusDataStore(searchParameterDefinitionManager, ModelInfoProvider.Instance); var securityConfiguration = new SecurityConfiguration { PrincipalClaims = { "oid" } }; var sqlServerFhirModel = new SqlServerFhirModel( config, schemaInformation, searchParameterDefinitionManager, () => _filebasedSearchParameterStatusDataStore, Options.Create(securityConfiguration), NullLogger <SqlServerFhirModel> .Instance); var serviceCollection = new ServiceCollection(); serviceCollection.AddSqlServerTableRowParameterGenerators(); serviceCollection.AddSingleton(sqlServerFhirModel); ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); var upsertResourceTvpGenerator = serviceProvider.GetRequiredService <VLatest.UpsertResourceTvpGenerator <ResourceMetadata> >(); var upsertSearchParamsTvpGenerator = serviceProvider.GetRequiredService <VLatest.UpsertSearchParamsTvpGenerator <List <ResourceSearchParameterStatus> > >(); var searchParameterToSearchValueTypeMap = new SearchParameterToSearchValueTypeMap(new SupportedSearchParameterDefinitionManager(searchParameterDefinitionManager)); SqlTransactionHandler = new SqlTransactionHandler(); SqlConnectionWrapperFactory = new SqlConnectionWrapperFactory(SqlTransactionHandler, new SqlCommandWrapperFactory(), sqlConnectionFactory); SqlServerSearchParameterStatusDataStore = new SqlServerSearchParameterStatusDataStore( () => SqlConnectionWrapperFactory.CreateMockScope(), upsertSearchParamsTvpGenerator, () => _filebasedSearchParameterStatusDataStore, schemaInformation); _fhirDataStore = new SqlServerFhirDataStore(config, sqlServerFhirModel, searchParameterToSearchValueTypeMap, upsertResourceTvpGenerator, Options.Create(new CoreFeatureConfiguration()), SqlConnectionWrapperFactory, NullLogger <SqlServerFhirDataStore> .Instance, schemaInformation); _fhirOperationDataStore = new SqlServerFhirOperationDataStore(SqlConnectionWrapperFactory, NullLogger <SqlServerFhirOperationDataStore> .Instance); _testHelper = new SqlServerFhirStorageTestHelper(initialConnectionString, MasterDatabaseName, searchParameterDefinitionManager, sqlServerFhirModel, sqlConnectionFactory); }