/// <summary> /// Replaces the specified <see cref="Log" /> instance in the store. /// </summary> /// <param name="parser">The update parser.</param> /// <param name="dataObject">The data object to be replaced.</param> public override void Replace(WitsmlQueryParser parser, Log dataObject) { var uri = dataObject.GetUri(); using (var transaction = GetTransaction()) { transaction.SetContext(uri); // Remove previous log data ChannelDataChunkAdapter.Delete(uri); // Gather original mnemonics var originalMnemonics = GetMnemonics(uri); // Separate log header and log data var readers = ExtractDataReaders(dataObject); // Replace log header ReplaceEntity(dataObject, uri); if (CanSaveData()) { // Update log data and index ranges UpdateLogDataAndIndexRange(uri, readers, originalMnemonics); } // Validate log header result ValidateUpdatedEntity(Functions.PutObject, uri); // Commit transaction transaction.Commit(); } }
/// <summary> /// Deletes a data object by the specified identifier. /// </summary> /// <param name="uri">The data object URI.</param> public override void Delete(EtpUri uri) { using (var transaction = GetTransaction()) { transaction.SetContext(uri); base.Delete(uri); ChannelDataChunkAdapter.Delete(uri); // Commit transaction transaction.Commit(); } }
/// <summary> /// Partially delete the log data. /// </summary> /// <param name="uri">The URI.</param> /// <param name="parser">The parser.</param> /// <param name="channels">The current logCurve information.</param> /// <param name="currentRanges">The current channel index ranges.</param> protected override void PartialDeleteLogData(EtpUri uri, WitsmlQueryParser parser, List <LogCurveInfo> channels, Dictionary <string, Range <double?> > currentRanges) { var uidToMnemonics = channels.ToDictionary(c => c.Uid, c => c.Mnemonic.Value); var updatedRanges = new Dictionary <string, Range <double?> >(); WitsmlParser.RemoveEmptyElements(parser.Root); var delete = WitsmlParser.Parse <LogList>(parser.Root, false).Log.FirstOrDefault(); var current = GetEntity(uri); delete.IndexType = current.IndexType; delete.Direction = current.Direction; var indexRange = currentRanges[current.IndexCurve]; if (!indexRange.Start.HasValue || !ToDeleteLogData(delete, parser)) { return; } TimeSpan?offset = null; var indexCurve = current.IndexCurve; var indexChannel = current.LogCurveInfo.FirstOrDefault(l => l.Mnemonic.Value == indexCurve); if (DeleteAllLogData(current, delete, updatedRanges)) { ChannelDataChunkAdapter.Delete(uri); foreach (var curve in current.LogCurveInfo) { updatedRanges.Add(curve.Mnemonic.Value, new Range <double?>(null, null)); } } else { var deletedChannels = GetDeletedChannels(current, uidToMnemonics); var defaultDeleteRange = GetDefaultDeleteRange(current, delete); var isTimeLog = current.IsTimeLog(); var updateRanges = GetDeleteQueryIndexRange(delete, channels, uidToMnemonics, indexCurve, current.IsIncreasing(), isTimeLog); offset = currentRanges[indexCurve].Offset; var ranges = MergePartialDeleteRanges(deletedChannels, defaultDeleteRange, currentRanges, updateRanges, indexCurve, current.IsIncreasing()); ChannelDataChunkAdapter.PartialDeleteLogData(uri, indexCurve, current.IsIncreasing(), isTimeLog, deletedChannels, ranges, updatedRanges); } UpdateIndexRange(uri, current, updatedRanges, updatedRanges.Keys.ToList(), current.IsTimeLog(), indexChannel?.Unit, offset, false, true); }
/// <summary> /// Replaces the specified <see cref="Log" /> instance in the store. /// </summary> /// <param name="parser">The update parser.</param> /// <param name="dataObject">The data object to be replaced.</param> public override void Replace(WitsmlQueryParser parser, Log dataObject) { var uri = dataObject.GetUri(); using (var transaction = GetTransaction()) { transaction.SetContext(uri); // Remove previous log data ChannelDataChunkAdapter.Delete(uri); // Separate log header and log data var reader = ExtractDataReader(dataObject, GetEntity(uri)); // Replace log header ReplaceEntity(dataObject, uri); // Update log data and index ranges UpdateLogDataAndIndexRange(uri, new [] { reader }); // Validate log header result ValidateUpdatedEntity(Functions.PutObject, uri); // Commit transaction transaction.Commit(); } }
/// <summary> /// Partially delete the log data. /// </summary> /// <param name="uri">The URI.</param> /// <param name="parser">The parser.</param> /// <param name="channels">The current logCurve information.</param> /// <param name="currentRanges">The current channel index ranges.</param> protected override void PartialDeleteLogData(EtpUri uri, WitsmlQueryParser parser, List <LogCurveInfo> channels, Dictionary <string, Range <double?> > currentRanges) { var uidToMnemonics = channels.ToDictionary(c => c.Uid, c => c.Mnemonic.Value); var updatedRanges = new Dictionary <string, Range <double?> >(); WitsmlParser.RemoveEmptyElements(parser.Root); var delete = WitsmlParser.Parse <LogList>(parser.Root, false).Log.FirstOrDefault(); var current = GetEntity(uri); delete.IndexType = current.IndexType; delete.Direction = current.Direction; var indexRange = currentRanges[current.IndexCurve]; var headerOnlyDeletion = !indexRange.Start.HasValue || !ToDeleteLogData(delete, parser); // Audit if only the header is being updated if (headerOnlyDeletion) { AuditPartialDeleteHeaderOnly(delete, parser); UpdateGrowingObject(current, null); return; } TimeSpan?offset = null; var indexCurve = current.IndexCurve; var indexChannel = current.LogCurveInfo.FirstOrDefault(l => l.Mnemonic.Value == indexCurve); if (DeleteAllLogData(current, delete, updatedRanges)) { ChannelDataChunkAdapter.Delete(uri); foreach (var curve in current.LogCurveInfo) { updatedRanges.Add(curve.Mnemonic.Value, new Range <double?>(null, null)); } AuditPartialDelete(current, GetMnemonics(uri), indexRange.Start, indexRange.End); } else { var deletedChannels = GetDeletedChannels(current, uidToMnemonics); var defaultDeleteRange = GetDefaultDeleteRange(current, delete); var isTimeLog = current.IsTimeLog(); var updateRanges = GetDeleteQueryIndexRange(delete, channels, uidToMnemonics, indexCurve, current.IsIncreasing(), isTimeLog); offset = currentRanges[indexCurve].Offset; var ranges = MergePartialDeleteRanges(deletedChannels, defaultDeleteRange, currentRanges, updateRanges, indexCurve, current.IsIncreasing()); ChannelDataChunkAdapter.PartialDeleteLogData(uri, indexCurve, current.IsIncreasing(), isTimeLog, deletedChannels, ranges, updatedRanges); var affectedMnemonics = updatedRanges.Keys.Where(x => x != indexCurve).ToArray(); if (defaultDeleteRange.IsClosed()) { AuditPartialDelete(current, affectedMnemonics, defaultDeleteRange.Start, defaultDeleteRange.End); } else { // If full channels were deleted if (deletedChannels.Count > 0) { var minRange = channels.Where(x => deletedChannels.ContainsIgnoreCase(x.Mnemonic.Value)) .Min(x => x.GetIndexRange(current.IsIncreasing(), isTimeLog).Start); var maxRange = channels.Where(x => deletedChannels.ContainsIgnoreCase(x.Mnemonic.Value)) .Max(x => x.GetIndexRange(current.IsIncreasing(), isTimeLog).End); AuditPartialDelete(current, deletedChannels.ToArray(), minRange, maxRange, true); } else { AuditPartialDelete(current, affectedMnemonics, updateRanges.Min(x => x.Value.Start), updateRanges.Max(x => x.Value.End)); } } } var logHeaderUpdate = GetIndexRangeUpdate(uri, current, updatedRanges, updatedRanges.Keys.ToList(), current.IsTimeLog(), indexChannel?.Unit, offset, true); UpdateGrowingObject(current, logHeaderUpdate); }
/// <summary> /// Deletes a data object by the specified identifier. /// </summary> /// <param name="uri">The data object URI.</param> public override void Delete(EtpUri uri) { base.Delete(uri); ChannelDataChunkAdapter.Delete(uri); }