private void ProcessResults(IList <FileHeader> results, SaveChangesData data) { for (var i = 0; i < results.Count; i++) { var result = results[i]; var savedEntity = data.Entities[i]; object existingEntity; if (entitiesByKey.TryGetValue(savedEntity, out existingEntity) == false) { continue; } var existingFileHeader = (FileHeader)existingEntity; existingFileHeader.Metadata = result.Metadata; existingFileHeader.OriginalMetadata = (RavenJObject)result.Metadata.CloneToken(); existingFileHeader.Refresh(); if (savedEntity != result.FullPath) { if (!entitiesByKey.ContainsKey(result.FullPath)) { existingFileHeader.FullPath = result.FullPath; entitiesByKey.Add(result.FullPath, existingFileHeader); entitiesByKey.Remove(savedEntity); } } AddToCache(existingFileHeader.FullPath, existingFileHeader); } }
protected Dictionary <string, SaveChangesData> GetChangesToSavePerShard(SaveChangesData data) { var saveChangesPerShard = new Dictionary <string, SaveChangesData>(); foreach (var deferredCommands in deferredCommandsByShard) { var saveChangesData = saveChangesPerShard.GetOrAdd(deferredCommands.Key); saveChangesData.DeferredCommandsCount += deferredCommands.Value.Count; saveChangesData.Commands.AddRange(deferredCommands.Value); } deferredCommandsByShard.Clear(); for (int index = 0; index < data.Entities.Count; index++) { var entity = data.Entities[index]; var metadata = GetMetadataFor(entity); var shardId = metadata.Value <string>(Constants.RavenShardId); if (shardId == null) { throw new InvalidOperationException("Cannot save a document when the shard id isn't defined. Missing Raven-Shard-Id in the metadata"); } var shardSaveChangesData = saveChangesPerShard.GetOrAdd(shardId); shardSaveChangesData.Entities.Add(entity); shardSaveChangesData.Commands.Add(data.Commands[index]); } return(saveChangesPerShard); }
public async Task SaveChangesAsync() { var changes = new SaveChangesData(); var operationsToExecute = registeredOperations; registeredOperations = new Queue<IFilesOperation>(); PrepareForSaveChanges(changes, operationsToExecute.ToList()); try { var results = new List<FileHeader>(); foreach (var op in changes.Operations) { AssertConflictsAreNotAffectingOperation(op); var operationResult = await op.Execute((IAsyncFilesSession)this).ConfigureAwait(false); if (operationResult != null) results.Add(operationResult); } ProcessResults(results, changes); } finally { deletedEntities.Clear(); } }
/// <summary> /// Prepares for save changes. /// </summary> /// <returns></returns> protected SaveChangesData PrepareForSaveChanges() { var result = new SaveChangesData { Entities = new List <object>(), Commands = new List <ICommandData>() }; TryEnlistInAmbientTransaction(); DocumentMetadata value = null; foreach (var key in (from deletedEntity in deletedEntities where entitiesAndMetadata.TryGetValue(deletedEntity, out value) select value.Key)) { Guid? etag = null; object existingEntity; DocumentMetadata metadata = null; if (entitiesByKey.TryGetValue(key, out existingEntity)) { if (entitiesAndMetadata.TryGetValue(existingEntity, out metadata)) { etag = metadata.ETag; } entitiesAndMetadata.Remove(existingEntity); entitiesByKey.Remove(key); } etag = UseOptimisticConcurrency ? etag : null; result.Entities.Add(existingEntity); foreach (var deleteListener in deleteListeners) { deleteListener.BeforeDelete(key, existingEntity, metadata != null ? metadata.Metadata : null); } result.Commands.Add(new DeleteCommandData { Etag = etag, Key = key, }); } deletedEntities.Clear(); foreach (var entity in entitiesAndMetadata.Where(pair => EntityChanged(pair.Key, pair.Value))) { foreach (var documentStoreListener in storeListeners) { documentStoreListener.BeforeStore(entity.Value.Key, entity.Key, entity.Value.Metadata); } result.Entities.Add(entity.Key); if (entity.Value.Key != null) { entitiesByKey.Remove(entity.Value.Key); } result.Commands.Add(CreatePutEntityCommand(entity.Key, entity.Value)); } return(result); }
private void LogBatch(SaveChangesData data) { Debug.WriteLine(string.Format("Saving {0} changes to {1}", data.Commands.Count, StoreIdentifier)); foreach (var commandData in data.Commands) { Debug.WriteLine(string.Format("\t{0} {1}", commandData.Method, commandData.Key)); } }
private void PrepareForDeletion(SaveChangesData changes, IEnumerable <IFilesOperation> operations) { var deleteOperations = operations.OfType <DeleteFileOperation>().ToList(); foreach (var op in deleteOperations) { changes.Operations.Add(op); deletedEntities.Add(op.Filename); } }
private void PrepareForUpdate(SaveChangesData changes, IEnumerable <IFilesOperation> operations) { foreach (var key in entitiesByKey.Keys) { var fileHeader = entitiesByKey[key] as FileHeader; if (EntityChanged(fileHeader) && !UploadRegisteredForFile(fileHeader.FullPath, operations)) { changes.Operations.Add(new UpdateMetadataOperation(this, fileHeader, fileHeader.Metadata)); changes.Entities.Add(fileHeader.FullPath); } } }
private void PrepareForUpdate(SaveChangesData changes, List<IFilesOperation> operations) { foreach(var key in entitiesByKey.Keys) { var fileHeader = entitiesByKey[key]; if (EntityChanged(fileHeader) && !UploadRegisteredForFile(fileHeader.FullPath, operations)) { changes.Operations.Add(new UpdateMetadataOperation(this, fileHeader, fileHeader.Metadata, UseOptimisticConcurrency ? fileHeader.Etag : null)); changes.Entities.Add(fileHeader.FullPath); } } }
private void LogBatch(SaveChangesData data) { log.Debug(() => { var sb = new StringBuilder() .AppendFormat("Saving {0} changes to {1}", data.Commands.Count, StoreIdentifier) .AppendLine(); foreach (var commandData in data.Commands) { sb.AppendFormat("\t{0} {1}", commandData.Method, commandData.Key).AppendLine(); } return(sb.ToString()); }); }
private void PrepareForSaveChanges(SaveChangesData changes, List<IFilesOperation> operations) { PrepareForDeletion(changes, operations); PrepareForUpdate(changes, operations); operations.RemoveAll(x => x.GetType() == typeof(DeleteFileOperation) || x.GetType() == typeof(DeleteByQueryOperation)); // all other operations foreach (var op in operations) { changes.Entities.Add(op.FileName); changes.Operations.Add(op); } }
/// <summary> /// Prepares for save changes. /// </summary> /// <returns></returns> protected SaveChangesData PrepareForSaveChanges() { cachedJsonDocs.Clear(); var result = new SaveChangesData { Entities = new List <object>(), Commands = new List <ICommandData>() }; TryEnlistInAmbientTransaction(); PrepareForEntitiesDeletion(result); PrepareForEntitiesPuts(result); return(result); }
private void PrepareForEntitiesPuts(SaveChangesData result) { foreach (var entity in entitiesAndMetadata.Where(pair => EntityChanged(pair.Key, pair.Value)).ToArray()) { foreach (var documentStoreListener in listeners.StoreListeners) { if (documentStoreListener.BeforeStore(entity.Value.Key, entity.Key, entity.Value.Metadata, entity.Value.OriginalValue)) { cachedJsonDocs.Remove(entity.Key); } } result.Entities.Add(entity.Key); if (entity.Value.Key != null) { entitiesByKey.Remove(entity.Value.Key); } result.Commands.Add(CreatePutEntityCommand(entity.Key, entity.Value)); } }
private void PrepareForEntitiesDeletion(SaveChangesData result) { DocumentMetadata value = null; var keysToDelete = (from deletedEntity in deletedEntities where entitiesAndMetadata.TryGetValue(deletedEntity, out value) // skip deleting read only entities where !value.OriginalMetadata.ContainsKey(Constants.RavenReadOnly) || !value.OriginalMetadata.Value <bool>(Constants.RavenReadOnly) select value.Key).ToList(); foreach (var key in keysToDelete) { Guid? etag = null; object existingEntity; DocumentMetadata metadata = null; if (entitiesByKey.TryGetValue(key, out existingEntity)) { if (entitiesAndMetadata.TryGetValue(existingEntity, out metadata)) { etag = metadata.ETag; } entitiesAndMetadata.Remove(existingEntity); entitiesByKey.Remove(key); } etag = UseOptimisticConcurrency ? etag : null; result.Entities.Add(existingEntity); foreach (var deleteListener in listeners.DeleteListeners) { deleteListener.BeforeDelete(key, existingEntity, metadata != null ? metadata.Metadata : null); } result.Commands.Add(new DeleteCommandData { Etag = etag, Key = key, }); } deletedEntities.Clear(); }
/// <summary> /// Updates the batch results. /// </summary> protected void UpdateBatchResults(IList <BatchResult> batchResults, SaveChangesData saveChangesData) { for (var i = saveChangesData.DeferredCommandsCount; i < batchResults.Count; i++) { var batchResult = batchResults[i]; if (batchResult.Method != "PUT") { continue; } var entity = saveChangesData.Entities[i - saveChangesData.DeferredCommandsCount]; DocumentMetadata documentMetadata; if (entitiesAndMetadata.TryGetValue(entity, out documentMetadata) == false) { continue; } batchResult.Metadata["@etag"] = new RavenJValue(batchResult.Etag.ToString()); entitiesByKey[batchResult.Key] = entity; documentMetadata.ETag = batchResult.Etag; documentMetadata.Key = batchResult.Key; documentMetadata.OriginalMetadata = (RavenJObject)batchResult.Metadata.CloneToken(); documentMetadata.Metadata = batchResult.Metadata; documentMetadata.OriginalValue = ConvertEntityToJson(entity, documentMetadata.Metadata); TrySetIdentity(entity, batchResult.Key); foreach (var documentStoreListener in listeners.StoreListeners) { documentStoreListener.AfterStore(batchResult.Key, entity, batchResult.Metadata); } } var lastPut = batchResults.LastOrDefault(x => x.Method == "PUT"); if (lastPut == null) { return; } documentStore.UpdateLastWrittenEtag(lastPut.Etag); }
/// <summary> /// Prepares for save changes. /// </summary> /// <returns></returns> protected SaveChangesData PrepareForSaveChanges() { cachedJsonDocs.Clear(); var result = new SaveChangesData { Entities = new List <object>(), Commands = new List <ICommandData>(deferedCommands), DeferredCommandsCount = deferedCommands.Count }; deferedCommands.Clear(); #if !SILVERLIGHT if (documentStore.EnlistInDistributedTransactions) { TryEnlistInAmbientTransaction(); } #endif PrepareForEntitiesDeletion(result); PrepareForEntitiesPuts(result); return(result); }
protected Dictionary <string, SaveChangesData> GetChangesToSavePerShard(SaveChangesData data) { var saveChangesPerShard = new Dictionary <string, SaveChangesData>(); foreach (var deferredCommands in deferredCommandsByShard) { var saveChangesData = saveChangesPerShard.GetOrAdd(deferredCommands.Key); saveChangesData.DeferredCommandsCount += deferredCommands.Value.Count; saveChangesData.Commands.AddRange(deferredCommands.Value); } deferredCommandsByShard.Clear(); for (int index = 0; index < data.Entities.Count; index++) { var entity = data.Entities[index]; var metadata = GetMetadataFor(entity); var shardId = metadata.Value <string>(Constants.RavenShardId); var shardSaveChangesData = saveChangesPerShard.GetOrAdd(shardId); shardSaveChangesData.Entities.Add(entity); shardSaveChangesData.Commands.Add(data.Commands[index]); } return(saveChangesPerShard); }
protected async Task <Dictionary <string, SaveChangesData> > GetChangesToSavePerShardAsync(SaveChangesData data) { var saveChangesPerShard = CreateSaveChangesBatchPerShardFromDeferredCommands(); for (int index = 0; index < data.Entities.Count; index++) { var entity = data.Entities[index]; var metadata = await GetMetadataForAsync(entity).ConfigureAwait(false); var shardId = metadata.Value <string>(Constants.RavenShardId); if (shardId == null) { throw new InvalidOperationException("Cannot save a document when the shard id isn't defined. Missing Raven-Shard-Id in the metadata"); } var shardSaveChangesData = saveChangesPerShard.GetOrAdd(shardId); shardSaveChangesData.Entities.Add(entity); shardSaveChangesData.Commands.Add(data.Commands[index]); } return(saveChangesPerShard); }
private void ProcessResults(IList<FileHeader> results, SaveChangesData data) { for (var i = 0; i < results.Count; i++) { var result = results[i]; var savedEntity = data.Entities[i]; FileHeader existingEntity; if (entitiesByKey.TryGetValue(savedEntity, out existingEntity) == false) { var operation = data.Operations[i]; if (operation is UploadFileOperation || operation is RenameFileOperation) { AddToCache(result.Name, result); } continue; } var existingFileHeader = existingEntity; existingFileHeader.Metadata = result.Metadata; existingFileHeader.OriginalMetadata = (RavenJObject)result.Metadata.CloneToken(); existingFileHeader.Refresh(); if (savedEntity != result.FullPath) { if (!entitiesByKey.ContainsKey(result.FullPath)) { existingFileHeader.FullPath = result.FullPath; entitiesByKey.Add(result.FullPath, existingFileHeader); entitiesByKey.Remove(savedEntity); } } AddToCache(existingFileHeader.FullPath, existingFileHeader); } }
private void PrepareForUpdate(SaveChangesData changes, IEnumerable<IFilesOperation> operations) { foreach( var key in entitiesByKey.Keys) { var fileHeader = entitiesByKey[key] as FileHeader; if (EntityChanged(fileHeader) && !UploadRegisteredForFile(fileHeader.FullPath, operations)) { changes.Operations.Add(new UpdateMetadataOperation(this, fileHeader, fileHeader.Metadata)); changes.Entities.Add(fileHeader.FullPath); } } }
private void PrepareForDeletion(SaveChangesData changes, List<IFilesOperation> operations) { var deleteOperations = operations.OfType<DeleteFileOperation>().ToList(); foreach (var op in deleteOperations) { changes.Operations.Add(op); deletedEntities.Add(op.FileName); } var deleteByQueryOperations = operations.OfType<DeleteByQueryOperation>().ToList(); foreach (var op in deleteByQueryOperations) { changes.Operations.Add(op); } }