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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #5
0
 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);
                }
            }
        }
Example #8
0
        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);
                }
            }
        }
Example #9
0
 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());
     });
 }
Example #10
0
        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);
            }
        }
Example #11
0
        /// <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);
        }
Example #12
0
 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));
     }
 }
Example #13
0
        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();
        }
Example #14
0
        /// <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);
        }
Example #15
0
        /// <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);
        }
Example #16
0
        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);
			}
        }