public async Task <ExportJobOutcome> CreateExportJobAsync(ExportJobRecord jobRecord, CancellationToken cancellationToken) { using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true)) using (SqlCommand sqlCommand = sqlConnectionWrapper.CreateSqlCommand()) { VLatest.CreateExportJob.PopulateCommand( sqlCommand, jobRecord.Id, jobRecord.Hash, jobRecord.Status.ToString(), JsonConvert.SerializeObject(jobRecord, _jsonSerializerSettings)); var rowVersion = (int?)await sqlCommand.ExecuteScalarAsync(cancellationToken); if (rowVersion == null) { throw new OperationFailedException(string.Format(Core.Resources.OperationFailed, OperationsConstants.Export, "Failed to create export job because no row version was returned."), HttpStatusCode.InternalServerError); } return(new ExportJobOutcome(jobRecord, WeakETag.FromVersionId(rowVersion.ToString()))); } }
public async Task <UpsertOutcome> UpsertAsync(ResourceWrapper resource, WeakETag weakETag, bool allowCreate, bool keepHistory, CancellationToken cancellationToken) { int etag = 0; if (weakETag != null && !int.TryParse(weakETag.VersionId, out etag)) { // Set the etag to a sentinel value to enable expected failure paths when updating with both existing and nonexistent resources. etag = -1; } var resourceMetadata = new ResourceMetadata( resource.CompartmentIndices, resource.SearchIndices?.ToLookup(e => _searchParameterTypeMap.GetSearchValueType(e)), resource.LastModifiedClaims); using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true)) using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand()) using (var stream = new RecyclableMemoryStream(_memoryStreamManager)) using (var gzipStream = new GZipStream(stream, CompressionMode.Compress)) using (var writer = new StreamWriter(gzipStream, ResourceEncoding)) { writer.Write(resource.RawResource.Data); writer.Flush(); stream.Seek(0, 0); VLatest.UpsertResource.PopulateCommand( sqlCommandWrapper, baseResourceSurrogateId: ResourceSurrogateIdHelper.LastUpdatedToResourceSurrogateId(resource.LastModified.UtcDateTime), resourceTypeId: _model.GetResourceTypeId(resource.ResourceTypeName), resourceId: resource.ResourceId, eTag: weakETag == null ? null : (int?)etag, allowCreate: allowCreate, isDeleted: resource.IsDeleted, keepHistory: keepHistory, requestMethod: resource.Request.Method, rawResource: stream, tableValuedParameters: _upsertResourceTvpGeneratorVLatest.Generate(resourceMetadata)); try { var newVersion = (int?)await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken); if (newVersion == null) { // indicates a redundant delete return(null); } resource.Version = newVersion.ToString(); return(new UpsertOutcome(resource, newVersion == 1 ? SaveOutcomeType.Created : SaveOutcomeType.Updated)); } catch (SqlException e) { switch (e.Number) { case SqlErrorCodes.PreconditionFailed: throw new PreconditionFailedException(string.Format(Core.Resources.ResourceVersionConflict, weakETag?.VersionId)); case SqlErrorCodes.NotFound: if (weakETag != null) { throw new ResourceNotFoundException(string.Format(Core.Resources.ResourceNotFoundByIdAndVersion, resource.ResourceTypeName, resource.ResourceId, weakETag.VersionId)); } goto default; case SqlErrorCodes.MethodNotAllowed: throw new MethodNotAllowedException(Core.Resources.ResourceCreationNotAllowed); default: _logger.LogError(e, "Error from SQL database on upsert"); throw; } } } }