public async Task <IReadOnlyCollection <ExportJobOutcome> > AcquireExportJobsAsync(ushort maximumNumberOfConcurrentJobsAllowed, TimeSpan jobHeartbeatTimeoutThreshold, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { var jobHeartbeatTimeoutThresholdInSeconds = Convert.ToInt64(jobHeartbeatTimeoutThreshold.TotalSeconds); VLatest.AcquireExportJobs.PopulateCommand( sqlCommandWrapper, jobHeartbeatTimeoutThresholdInSeconds, maximumNumberOfConcurrentJobsAllowed); var acquiredJobs = new List <ExportJobOutcome>(); using (SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await sqlDataReader.ReadAsync(cancellationToken)) { (string rawJobRecord, byte[] rowVersion) = sqlDataReader.ReadRow(VLatest.ExportJob.RawJobRecord, VLatest.ExportJob.JobVersion); acquiredJobs.Add(CreateExportJobOutcome(rawJobRecord, rowVersion)); } } return(acquiredJobs); } }
public override async Task <IReadOnlyList <ExtendedQueryTagStoreEntry> > GetExtendedQueryTagsAsync(Guid operationId, CancellationToken cancellationToken = default) { var results = new List <ExtendedQueryTagStoreEntry>(); using (SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetExtendedQueryTagsByOperation.PopulateCommand(sqlCommandWrapper, operationId); using (SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, int tagLevel, int tagStatus, byte queryStatus, int errorCount) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount); results.Add(new ExtendedQueryTagStoreEntry(tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, (QueryStatus)queryStatus, errorCount)); } } } return(results); }
public override async Task <ExtendedQueryTagStoreJoinEntry> GetExtendedQueryTagAsync(string path, CancellationToken cancellationToken = default) { using (SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetExtendedQueryTag.PopulateCommand(sqlCommandWrapper, path); var executionTimeWatch = Stopwatch.StartNew(); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { if (!await reader.ReadAsync(cancellationToken)) { throw new ExtendedQueryTagNotFoundException(string.Format(DicomCoreResource.ExtendedQueryTagNotFound, path)); } (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, int tagLevel, int tagStatus, byte queryStatus, int errorCount, Guid? operationId) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount, VLatest.ExtendedQueryTagOperation.OperationId.AsNullable()); executionTimeWatch.Stop(); Logger.StoredProcedureSucceeded(nameof(VLatest.GetExtendedQueryTag), executionTimeWatch); return(new ExtendedQueryTagStoreJoinEntry(tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, (QueryStatus)queryStatus, errorCount, operationId)); } } }
private async Task <List <ExtendedQueryTagStoreJoinEntry> > GetAllExtendedQueryTagsAsync(CancellationToken cancellationToken = default) { var results = new List <ExtendedQueryTagStoreJoinEntry>(); using (SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { // V2 version allows NULL to get all tags V2.GetExtendedQueryTag.PopulateCommand(sqlCommandWrapper, null); var executionTimeWatch = Stopwatch.StartNew(); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, int tagLevel, int tagStatus) = reader.ReadRow( V2.ExtendedQueryTag.TagKey, V2.ExtendedQueryTag.TagPath, V2.ExtendedQueryTag.TagVR, V2.ExtendedQueryTag.TagPrivateCreator, V2.ExtendedQueryTag.TagLevel, V2.ExtendedQueryTag.TagStatus); results.Add(new ExtendedQueryTagStoreJoinEntry(tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, QueryStatus.Enabled, 0)); } executionTimeWatch.Stop(); Logger.StoredProcedureSucceeded(nameof(V2.GetExtendedQueryTag), executionTimeWatch); } } return(results); }
public override async Task <IEnumerable <PartitionEntry> > GetPartitionsAsync(CancellationToken cancellationToken) { var results = new List <PartitionEntry>(); using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetPartitions.PopulateCommand(sqlCommandWrapper); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (int rPartitionKey, string rPartitionName, DateTimeOffset rCreatedDate) = reader.ReadRow( VLatest.Partition.PartitionKey, VLatest.Partition.PartitionName, VLatest.Partition.CreatedDate); results.Add(new PartitionEntry( rPartitionKey, rPartitionName, rCreatedDate)); } } return(results); } }
public override async Task <PartitionEntry> GetPartitionAsync(string partitionName, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = await SqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetPartition.PopulateCommand(sqlCommandWrapper, partitionName); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { if (await reader.ReadAsync(cancellationToken)) { (int rPartitionKey, string rPartitionName, DateTimeOffset rCreatedDate) = reader.ReadRow( VLatest.Partition.PartitionKey, VLatest.Partition.PartitionName, VLatest.Partition.CreatedDate); return(new PartitionEntry( rPartitionKey, rPartitionName, rCreatedDate)); } } } return(null); }
private static async Task VerifyCommandResults(SqlConnectionWrapper connectionWrapper, string newId, bool shouldFind, string tableHints = "") { using (SqlCommandWrapper sqlCommandWrapper = connectionWrapper.CreateSqlCommand()) { sqlCommandWrapper.CommandText = $@" SELECT * FROM resource {tableHints} WHERE ResourceId = @newId"; sqlCommandWrapper.Parameters.Add(new SqlParameter { ParameterName = "newId", Value = newId }); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CancellationToken.None)) { if (shouldFind) { while (reader.Read()) { Assert.Equal(newId, reader["resourceId"]); } } else { Assert.False(reader.HasRows); } } } }
// TODO: Make cancellation token an input. public async Task <IReadOnlyCollection <ResourceSearchParameterStatus> > GetSearchParameterStatuses() { // If the search parameter table in SQL does not yet contain status columns if (_schemaInformation.Current < SchemaVersionConstants.SearchParameterStatusSchemaVersion) { // Get status information from file. return(await _filebasedSearchParameterStatusDataStore.GetSearchParameterStatuses()); } using (IScoped <SqlConnectionWrapperFactory> scopedSqlConnectionWrapperFactory = _scopedSqlConnectionWrapperFactory()) using (SqlConnectionWrapper sqlConnectionWrapper = await scopedSqlConnectionWrapperFactory.Value.ObtainSqlConnectionWrapperAsync(CancellationToken.None, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetSearchParamStatuses.PopulateCommand(sqlCommandWrapper); var parameterStatuses = new List <ResourceSearchParameterStatus>(); using (SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, CancellationToken.None)) { while (await sqlDataReader.ReadAsync()) { (string uri, string stringStatus, DateTimeOffset? lastUpdated, bool?isPartiallySupported) = sqlDataReader.ReadRow( VLatest.SearchParam.Uri, VLatest.SearchParam.Status, VLatest.SearchParam.LastUpdated, VLatest.SearchParam.IsPartiallySupported); if (string.IsNullOrEmpty(stringStatus) || lastUpdated == null || isPartiallySupported == null) { // These columns are nullable because they are added to dbo.SearchParam in a later schema version. // They should be populated as soon as they are added to the table and should never be null. throw new NullReferenceException(Resources.SearchParameterStatusShouldNotBeNull); } var status = Enum.Parse <SearchParameterStatus>(stringStatus, true); var resourceSearchParameterStatus = new ResourceSearchParameterStatus() { Uri = new Uri(uri), Status = status, IsPartiallySupported = (bool)isPartiallySupported, LastUpdated = (DateTimeOffset)lastUpdated, }; if (SqlServerSortingValidator.SupportedParameterUris.Contains(resourceSearchParameterStatus.Uri)) { resourceSearchParameterStatus.SortStatus = SortParameterStatus.Enabled; } else { resourceSearchParameterStatus.SortStatus = SortParameterStatus.Supported; } parameterStatuses.Add(resourceSearchParameterStatus); } } return(parameterStatuses); } }
public async Task UpsertStatuses(IReadOnlyCollection <ResourceSearchParameterStatus> statuses, CancellationToken cancellationToken) { EnsureArg.IsNotNull(statuses, nameof(statuses)); if (!statuses.Any()) { return; } if (_schemaInformation.Current < SchemaVersionConstants.SearchParameterStatusSchemaVersion) { throw new BadRequestException(Resources.SchemaVersionNeedsToBeUpgraded); } using (IScoped <SqlConnectionWrapperFactory> scopedSqlConnectionWrapperFactory = _scopedSqlConnectionWrapperFactory()) using (SqlConnectionWrapper sqlConnectionWrapper = await scopedSqlConnectionWrapperFactory.Value.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.UpsertSearchParams.PopulateCommand(sqlCommandWrapper, _updateSearchParamsTvpGenerator.Generate(statuses.ToList())); using (SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await sqlDataReader.ReadAsync(cancellationToken)) { // The upsert procedure returns the search parameters that were new. (short searchParamId, string searchParamUri) = sqlDataReader.ReadRow(VLatest.SearchParam.SearchParamId, VLatest.SearchParam.Uri); // Add the new search parameters to the FHIR model dictionary. _fhirModel.TryAddSearchParamIdToUriMapping(searchParamUri, searchParamId); } } } }
public override async Task <IReadOnlyList <int> > CompleteReindexingAsync(IReadOnlyCollection <int> queryTagKeys, CancellationToken cancellationToken = default) { EnsureArg.HasItems(queryTagKeys, nameof(queryTagKeys)); using SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); IEnumerable <ExtendedQueryTagKeyTableTypeV1Row> rows = queryTagKeys.Select(x => new ExtendedQueryTagKeyTableTypeV1Row(x)); VLatest.CompleteReindexing.PopulateCommand(sqlCommandWrapper, rows); try { var keys = new List <int>(); using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); while (await reader.ReadAsync(cancellationToken)) { keys.Add(reader.ReadRow(VLatest.ExtendedQueryTagString.TagKey)); } return(keys); } catch (SqlException ex) { throw new DataStoreException(ex); } }
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 async Task <TaskInfo> ResetAsync(string taskId, TaskResultData taskResultData, string runId, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { try { VLatest.ResetTask.PopulateCommand(sqlCommandWrapper, taskId, runId, JsonConvert.SerializeObject(taskResultData)); SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); if (!sqlDataReader.Read()) { return(null); } var taskInfoTable = VLatest.TaskInfo; _ = sqlDataReader.Read(taskInfoTable.TaskId, 0); string queueId = sqlDataReader.Read(taskInfoTable.QueueId, 1); short status = sqlDataReader.Read(taskInfoTable.Status, 2); short taskTypeId = sqlDataReader.Read(taskInfoTable.TaskTypeId, 3); string taskRunId = sqlDataReader.Read(taskInfoTable.RunId, 4); bool isCanceled = sqlDataReader.Read(taskInfoTable.IsCanceled, 5); short retryCount = sqlDataReader.Read(taskInfoTable.RetryCount, 6); short maxRetryCount = sqlDataReader.Read(taskInfoTable.MaxRetryCount, 7); DateTime?heartbeatDateTime = sqlDataReader.Read(taskInfoTable.HeartbeatDateTime, 8); string inputData = sqlDataReader.Read(taskInfoTable.InputData, 9); string taskContext = sqlDataReader.Read(taskInfoTable.TaskContext, 10); string result = sqlDataReader.Read(taskInfoTable.Result, 11); TaskStatus taskStatus = (TaskStatus)status; return(taskStatus == TaskStatus.Completed ? throw new TaskAlreadyCompletedException("Task already completed or reach max retry count.") : new TaskInfo() { TaskId = taskId, QueueId = queueId, Status = taskStatus, TaskTypeId = taskTypeId, RunId = taskRunId, IsCanceled = isCanceled, RetryCount = retryCount, MaxRetryCount = maxRetryCount, HeartbeatDateTime = heartbeatDateTime, InputData = inputData, Context = taskContext, Result = result, }); } catch (SqlException sqlEx) { if (sqlEx.Number == SqlErrorCodes.NotFound) { throw new TaskNotExistException(sqlEx.Message); } throw; } } }
public async Task <IReadOnlyCollection <TaskInfo> > GetNextMessagesAsync(short count, int taskHeartbeatTimeoutThresholdInSeconds, CancellationToken cancellationToken) { List <TaskInfo> output = new List <TaskInfo>(); try { using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { string queueId = _taskHostingConfiguration.QueueId; VLatest.GetNextTask.PopulateCommand(sqlCommandWrapper, queueId, count, taskHeartbeatTimeoutThresholdInSeconds); SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); var taskInfoTable = VLatest.TaskInfo; while (sqlDataReader.Read()) { string id = sqlDataReader.Read(taskInfoTable.TaskId, 0); _ = sqlDataReader.Read(taskInfoTable.QueueId, 1); short status = sqlDataReader.Read(taskInfoTable.Status, 2); short taskTypeId = sqlDataReader.Read(taskInfoTable.TaskTypeId, 3); string taskRunId = sqlDataReader.Read(taskInfoTable.RunId, 4); bool isCanceled = sqlDataReader.Read(taskInfoTable.IsCanceled, 5); short retryCount = sqlDataReader.Read(taskInfoTable.RetryCount, 6); short maxRetryCount = sqlDataReader.Read(taskInfoTable.MaxRetryCount, 7); DateTime?heartbeatDateTime = sqlDataReader.Read(taskInfoTable.HeartbeatDateTime, 8); string inputData = sqlDataReader.Read(taskInfoTable.InputData, 9); string taskContext = sqlDataReader.Read(taskInfoTable.TaskContext, 10); string result = sqlDataReader.Read(taskInfoTable.Result, 11); TaskInfo taskInfo = new TaskInfo() { TaskId = id, QueueId = queueId, Status = (TaskStatus)status, TaskTypeId = taskTypeId, RunId = taskRunId, IsCanceled = isCanceled, RetryCount = retryCount, MaxRetryCount = maxRetryCount, HeartbeatDateTime = heartbeatDateTime, InputData = inputData, Context = taskContext, Result = result, }; output.Add(taskInfo); } } } catch (SqlException e) when(e.Number == 2812) { _logger.LogWarning(e, "Schema is not initialized - {ex.Message}", e.Message); } return(output); }
public async Task <TaskInfo> CreateTaskAsync(TaskInfo task, bool isUniqueTaskByType, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { try { VLatest.CreateTask.PopulateCommand(sqlCommandWrapper, task.TaskId, task.QueueId, task.TaskTypeId, task.MaxRetryCount, task.InputData, isUniqueTaskByType); SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); if (!sqlDataReader.Read()) { return(null); } var taskInfoTable = VLatest.TaskInfo; string taskId = sqlDataReader.Read(taskInfoTable.TaskId, 0); string queueId = sqlDataReader.Read(taskInfoTable.QueueId, 1); short status = sqlDataReader.Read(taskInfoTable.Status, 2); short taskTypeId = sqlDataReader.Read(taskInfoTable.TaskTypeId, 3); string taskRunId = sqlDataReader.Read(taskInfoTable.RunId, 4); bool isCanceled = sqlDataReader.Read(taskInfoTable.IsCanceled, 5); short retryCount = sqlDataReader.Read(taskInfoTable.RetryCount, 6); short maxRetryCount = sqlDataReader.Read(taskInfoTable.MaxRetryCount, 7); DateTime?heartbeatDateTime = sqlDataReader.Read(taskInfoTable.HeartbeatDateTime, 8); string inputData = sqlDataReader.Read(taskInfoTable.InputData, 9); return(new TaskInfo() { TaskId = taskId, QueueId = queueId, Status = (TaskStatus)status, TaskTypeId = taskTypeId, RunId = taskRunId, IsCanceled = isCanceled, RetryCount = retryCount, MaxRetryCount = maxRetryCount, HeartbeatDateTime = heartbeatDateTime, InputData = inputData, }); } catch (SqlException sqlEx) { if (sqlEx.Number == SqlErrorCodes.Conflict) { throw new TaskConflictException(sqlEx.Message); } throw; } } }
private async Task<IList<Product>> GetProductsAsync() { var sqlCommandWrapper = new SqlCommandWrapper(connectionString, 900);// connection string and timeout var parameters = new SqlParameter[] { }; return (await sqlCommandWrapper.ExecuteReaderAsync(CommandType.Text, // For stored-procedures no need to pass CommandType param "Select * From items", r => new Product { Id = (int)r["Id"], FirstName = r["FirstName"].ToString(), }, parameters)).ToList(); }
public override async Task <IReadOnlyList <ExtendedQueryTagStoreEntry> > AssignReindexingOperationAsync( IReadOnlyCollection <int> queryTagKeys, Guid operationId, bool returnIfCompleted = false, CancellationToken cancellationToken = default) { EnsureArg.HasItems(queryTagKeys, nameof(queryTagKeys)); using SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); IEnumerable <ExtendedQueryTagKeyTableTypeV1Row> rows = queryTagKeys.Select(x => new ExtendedQueryTagKeyTableTypeV1Row(x)); VLatest.AssignReindexingOperation.PopulateCommand(sqlCommandWrapper, rows, operationId, returnIfCompleted); try { var queryTags = new List <ExtendedQueryTagStoreEntry>(); using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); while (await reader.ReadAsync(cancellationToken)) { (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, byte tagLevel, byte tagStatus, byte queryStatus, int errorCount) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount); queryTags.Add(new ExtendedQueryTagStoreEntry( tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, (QueryStatus)queryStatus, errorCount)); } return(queryTags); } catch (SqlException ex) { throw new DataStoreException(ex); } }
public override async Task <IReadOnlyList <ExtendedQueryTagStoreEntry> > AddExtendedQueryTagsAsync( IReadOnlyCollection <AddExtendedQueryTagEntry> extendedQueryTagEntries, int maxAllowedCount, bool ready = false, CancellationToken cancellationToken = default) { EnsureArg.IsNotNull(extendedQueryTagEntries, nameof(extendedQueryTagEntries)); EnsureArg.IsGt(maxAllowedCount, 0, nameof(maxAllowedCount)); using SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); IEnumerable <AddExtendedQueryTagsInputTableTypeV1Row> rows = extendedQueryTagEntries.Select(ToAddExtendedQueryTagsInputTableTypeV1Row); VLatest.AddExtendedQueryTags.PopulateCommand(sqlCommandWrapper, maxAllowedCount, ready, new VLatest.AddExtendedQueryTagsTableValuedParameters(rows)); try { var results = new List <ExtendedQueryTagStoreEntry>(); using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); while (await reader.ReadAsync(cancellationToken)) { (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, int tagLevel, int tagStatus, byte queryStatus, int errorCount) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount); results.Add(new ExtendedQueryTagStoreEntry(tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, (QueryStatus)queryStatus, errorCount)); } return(results); } catch (SqlException ex) { throw ex.Number switch { SqlErrorCodes.Conflict => ex.State == 1 ? new ExtendedQueryTagsExceedsMaxAllowedCountException(maxAllowedCount) : new ExtendedQueryTagsAlreadyExistsException(), _ => new DataStoreException(ex), }; } }
public async Task <List <CurrentVersionInformation> > GetCurrentVersionAsync(CancellationToken cancellationToken) { var currentVersions = new List <CurrentVersionInformation>(); using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken: cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { SchemaShared.SelectCurrentVersionsInformation.PopulateCommand(sqlCommandWrapper); try { using (var dataReader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken)) { if (dataReader.HasRows) { while (await dataReader.ReadAsync(cancellationToken)) { IList <string> instanceNames = new List <string>(); if (!dataReader.IsDBNull(2)) { string names = dataReader.GetString(2); instanceNames = names.Split(",").ToList(); } var status = (string)dataReader.GetValue(1); // To combine the complete and completed version since earlier status was marked in 'complete' status and now the fix has made to mark the status in completed state status = string.Equals(status, "complete", StringComparison.OrdinalIgnoreCase) ? "completed" : status; var schemaVersionStatus = (SchemaVersionStatus)Enum.Parse(typeof(SchemaVersionStatus), status, true); var currentVersion = new CurrentVersionInformation((int)dataReader.GetValue(0), schemaVersionStatus, instanceNames); currentVersions.Add(currentVersion); } } else { return(currentVersions); } } } catch (SqlException e) { _logger.LogError(e, "Error from SQL database on retrieving current version information"); throw; } } return(currentVersions); }
public async Task <TaskInfo> GetTaskAsync(string taskId, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetTaskDetails.PopulateCommand(sqlCommandWrapper, taskId); SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); if (!sqlDataReader.Read()) { return(null); } var taskInfoTable = VLatest.TaskInfo; string id = sqlDataReader.Read(taskInfoTable.TaskId, 0); string queueId = sqlDataReader.Read(taskInfoTable.QueueId, 1); short status = sqlDataReader.Read(taskInfoTable.Status, 2); short taskTypeId = sqlDataReader.Read(taskInfoTable.TaskTypeId, 3); string taskRunId = sqlDataReader.Read(taskInfoTable.RunId, 4); bool isCanceled = sqlDataReader.Read(taskInfoTable.IsCanceled, 5); short retryCount = sqlDataReader.Read(taskInfoTable.RetryCount, 6); short maxRetryCount = sqlDataReader.Read(taskInfoTable.MaxRetryCount, 7); DateTime?heartbeatDateTime = sqlDataReader.Read(taskInfoTable.HeartbeatDateTime, 8); string inputData = sqlDataReader.Read(taskInfoTable.InputData, 9); string taskContext = sqlDataReader.Read(taskInfoTable.TaskContext, 10); string result = sqlDataReader.Read(taskInfoTable.Result, 11); return(new TaskInfo() { TaskId = id, QueueId = queueId, Status = (TaskStatus)status, TaskTypeId = taskTypeId, RunId = taskRunId, IsCanceled = isCanceled, RetryCount = retryCount, MaxRetryCount = maxRetryCount, HeartbeatDateTime = heartbeatDateTime, InputData = inputData, Context = taskContext, Result = result, }); } }
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); }
public override async Task <IReadOnlyList <ExtendedQueryTagError> > GetExtendedQueryTagErrorsAsync(string tagPath, int limit, int offset, CancellationToken cancellationToken = default) { List <ExtendedQueryTagError> results = new List <ExtendedQueryTagError>(); using SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); VLatest.GetExtendedQueryTagErrorsV6.PopulateCommand(sqlCommandWrapper, tagPath, limit, offset); try { using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken); while (await reader.ReadAsync(cancellationToken)) { (int tagkey, short errorCode, DateTime createdTime, string partitionName, string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid) = reader.ReadRow( VLatest.ExtendedQueryTagError.TagKey, VLatest.ExtendedQueryTagError.ErrorCode, VLatest.ExtendedQueryTagError.CreatedTime, VLatest.Partition.PartitionName, VLatest.Instance.StudyInstanceUid, VLatest.Instance.SeriesInstanceUid, VLatest.Instance.SopInstanceUid); results.Add(new ExtendedQueryTagError(createdTime, studyInstanceUid, seriesInstanceUid, sopInstanceUid, ((ValidationErrorCode)errorCode).GetMessage(), partitionName)); } } catch (SqlException e) { if (e.Number == SqlErrorCodes.NotFound) { throw new ExtendedQueryTagNotFoundException( string.Format(CultureInfo.InvariantCulture, DicomSqlServerResource.ExtendedQueryTagNotFound, tagPath)); } throw new DataStoreException(e); } return(results); }
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 async Task <ExportJobOutcome> GetExportJobByIdAsync(string id, CancellationToken cancellationToken) { EnsureArg.IsNotNullOrWhiteSpace(id, nameof(id)); using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetExportJobById.PopulateCommand(sqlCommandWrapper, id); using (SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { if (!sqlDataReader.Read()) { throw new JobNotFoundException(string.Format(Core.Resources.JobNotFound, id)); } (string rawJobRecord, byte[] rowVersion) = sqlDataReader.ReadRow(VLatest.ExportJob.RawJobRecord, VLatest.ExportJob.JobVersion); return(CreateExportJobOutcome(rawJobRecord, rowVersion)); } } }
public async Task <ExportJobOutcome> GetExportJobByHashAsync(string hash, CancellationToken cancellationToken) { EnsureArg.IsNotNullOrWhiteSpace(hash, nameof(hash)); using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetExportJobByHash.PopulateCommand(sqlCommandWrapper, hash); using (SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { if (!sqlDataReader.Read()) { return(null); } (string rawJobRecord, byte[] rowVersion) = sqlDataReader.ReadRow(VLatest.ExportJob.RawJobRecord, VLatest.ExportJob.JobVersion); return(CreateExportJobOutcome(rawJobRecord, rowVersion)); } } }
public override async Task <IReadOnlyList <ExtendedQueryTagStoreJoinEntry> > GetExtendedQueryTagsAsync(IReadOnlyCollection <int> queryTagKeys, CancellationToken cancellationToken = default) { EnsureArg.HasItems(queryTagKeys, nameof(queryTagKeys)); var results = new List <ExtendedQueryTagStoreJoinEntry>(); using (SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { IEnumerable <ExtendedQueryTagKeyTableTypeV1Row> rows = queryTagKeys.Select(x => new ExtendedQueryTagKeyTableTypeV1Row(x)); VLatest.GetExtendedQueryTagsByKey.PopulateCommand(sqlCommandWrapper, rows); var executionTimeWatch = Stopwatch.StartNew(); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, int tagLevel, int tagStatus, byte queryStatus, int errorCount, Guid? operationId) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount, VLatest.ExtendedQueryTagOperation.OperationId.AsNullable()); results.Add(new ExtendedQueryTagStoreJoinEntry(tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, (QueryStatus)queryStatus, errorCount, operationId)); } executionTimeWatch.Stop(); Logger.StoredProcedureSucceeded(nameof(VLatest.GetExtendedQueryTagsByKey), executionTimeWatch); } } return(results); }
public override async Task <IReadOnlyList <ExtendedQueryTagStoreJoinEntry> > GetExtendedQueryTagsAsync(int limit, int offset = 0, CancellationToken cancellationToken = default) { EnsureArg.IsGte(limit, 1, nameof(limit)); EnsureArg.IsGte(offset, 0, nameof(offset)); var results = new List <ExtendedQueryTagStoreJoinEntry>(); using (SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.GetExtendedQueryTags.PopulateCommand(sqlCommandWrapper, limit, offset); var executionTimeWatch = Stopwatch.StartNew(); using (var reader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await reader.ReadAsync(cancellationToken)) { (int tagKey, string tagPath, string tagVR, string tagPrivateCreator, int tagLevel, int tagStatus, byte queryStatus, int errorCount, Guid? operationId) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount, VLatest.ExtendedQueryTagOperation.OperationId.AsNullable()); results.Add(new ExtendedQueryTagStoreJoinEntry(tagKey, tagPath, tagVR, tagPrivateCreator, (QueryTagLevel)tagLevel, (ExtendedQueryTagStatus)tagStatus, (QueryStatus)queryStatus, errorCount, operationId)); } executionTimeWatch.Stop(); Logger.StoredProcedureSucceeded(nameof(VLatest.GetExtendedQueryTags), executionTimeWatch); } } return(results); }
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)); }
///<inheritdoc/> public override async Task <ExtendedQueryTagStoreJoinEntry> UpdateQueryStatusAsync(string tagPath, QueryStatus queryStatus, CancellationToken cancellationToken) { EnsureArg.IsNotNullOrWhiteSpace(tagPath, nameof(tagPath)); EnsureArg.EnumIsDefined(queryStatus, nameof(queryStatus)); using SqlConnectionWrapper sqlConnectionWrapper = await ConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken); using SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand(); VLatest.UpdateExtendedQueryTagQueryStatus.PopulateCommand(sqlCommandWrapper, tagPath, (byte)queryStatus); try { using SqlDataReader reader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken); if (!await reader.ReadAsync(cancellationToken)) { throw new ExtendedQueryTagNotFoundException(string.Format(CultureInfo.InvariantCulture, DicomSqlServerResource.ExtendedQueryTagNotFound, tagPath)); } (int rTagKey, string rTagPath, string rTagVR, string rTagPrivateCreator, byte rTagLevel, byte rTagStatus, byte rQueryStatus, int errorCount, Guid? operationId) = reader.ReadRow( VLatest.ExtendedQueryTag.TagKey, VLatest.ExtendedQueryTag.TagPath, VLatest.ExtendedQueryTag.TagVR, VLatest.ExtendedQueryTag.TagPrivateCreator, VLatest.ExtendedQueryTag.TagLevel, VLatest.ExtendedQueryTag.TagStatus, VLatest.ExtendedQueryTag.QueryStatus, VLatest.ExtendedQueryTag.ErrorCount, VLatest.ExtendedQueryTagOperation.OperationId.AsNullable()); return(new ExtendedQueryTagStoreJoinEntry(rTagKey, rTagPath, rTagVR, rTagPrivateCreator, (QueryTagLevel)rTagLevel, (ExtendedQueryTagStatus)rTagStatus, (QueryStatus)rQueryStatus, errorCount, operationId)); } catch (SqlException ex) { throw new DataStoreException(ex); } }
public async Task <(bool found, string id)> CheckActiveReindexJobsAsync(CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.CheckActiveReindexJobs.PopulateCommand(sqlCommandWrapper); var activeJobs = new List <string>(); using (SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) { while (await sqlDataReader.ReadAsync(cancellationToken)) { string id = sqlDataReader.ReadRow(VLatest.ReindexJob.Id); activeJobs.Add(id); } } // Currently, there can only be one active reindex job at a time. return(activeJobs.Count > 0, activeJobs.Count > 0 ? activeJobs.FirstOrDefault() : string.Empty); } }
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); }