public void UpdateMetadata(string name, RavenJObject metadata, Etag etag) { MetadataUpdateResult updateMetadata = null; Storage.Batch(accessor => { AssertMetadataUpdateOperationNotVetoed(name, metadata); Historian.UpdateLastModified(metadata); FileSystem.MetadataUpdateTriggers.Apply(trigger => trigger.OnUpdate(name, metadata)); updateMetadata = accessor.UpdateFileMetadata(name, metadata, etag); FileSystem.MetadataUpdateTriggers.Apply(trigger => trigger.AfterUpdate(name, metadata)); }); Search.Index(name, metadata, updateMetadata.Etag); FileSystem.Publisher.Publish(new FileChangeNotification { File = name, Action = FileChangeAction.Update }); Log.Debug("Metadata of a file '{0}' was updated", name); }
public void Delete(string fileName, IStorageActionsAccessor actionsAccessor = null) { RavenJObject metadata = null; MetadataUpdateResult updateResult = null; Action <IStorageActionsAccessor> delete = accessor => { accessor.DeleteConfig(RavenFileNameHelper.ConflictConfigNameForFile(fileName)); metadata = accessor.GetFile(fileName, 0, 0).Metadata; metadata.Remove(SynchronizationConstants.RavenSynchronizationConflict); metadata.Remove(SynchronizationConstants.RavenSynchronizationConflictResolution); updateResult = accessor.UpdateFileMetadata(fileName, metadata, null); }; if (actionsAccessor != null) { delete(actionsAccessor); } else { storage.Batch(delete); } if (metadata != null) { index.Index(fileName, metadata, updateResult.Etag); } }
public void Create(string fileName, ConflictItem conflict) { RavenJObject metadata = null; MetadataUpdateResult updateMetadata = null; storage.Batch( accessor => { metadata = accessor.GetFile(fileName, 0, 0).Metadata; accessor.SetConfig(RavenFileNameHelper.ConflictConfigNameForFile(fileName), JsonExtensions.ToJObject(conflict)); metadata[SynchronizationConstants.RavenSynchronizationConflict] = true; updateMetadata = accessor.UpdateFileMetadata(fileName, metadata, null); }); if (metadata != null) { index.Index(fileName, metadata, updateMetadata.Etag); } }
public MetadataUpdateResult PutFile(string filename, long?totalSize, RavenJObject metadata, bool tombstone = false) { MetadataUpdateResult result; using (var update = new Update(session, Files, JET_prep.Insert)) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["name"], filename, Encoding.Unicode); if (totalSize != null) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["total_size"], BitConverter.GetBytes(totalSize.Value)); } Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["uploaded_size"], BitConverter.GetBytes(0)); metadata.Remove(Constants.MetadataEtagField); var newEtag = uuidGenerator.CreateSequentialUuid(); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["etag"], newEtag.TransformToValueForEsentSorting()); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["metadata"], ToQueryString(metadata), Encoding.Unicode); update.Save(); result = new MetadataUpdateResult { PrevEtag = null, Etag = newEtag }; } if (!tombstone) { if (Api.TryMoveFirst(session, Details) == false) { throw new InvalidOperationException("Could not find system metadata row"); } Api.EscrowUpdate(session, Details, tableColumnsCache.DetailsColumns["file_count"], 1); } return(result); }
public async Task PutAsync(string name, Etag etag, RavenJObject metadata, Func <Task <Stream> > streamAsync, PutOperationOptions options) { try { FileSystem.MetricsCounters.FilesPerSecond.Mark(); name = FileHeader.Canonize(name); if (options.PreserveTimestamps) { if (!metadata.ContainsKey(Constants.RavenCreationDate)) { if (metadata.ContainsKey(Constants.CreationDate)) { metadata[Constants.RavenCreationDate] = metadata[Constants.CreationDate]; } else { throw new InvalidOperationException("Preserve Timestamps requires that the client includes the Raven-Creation-Date header."); } } Historian.UpdateLastModified(metadata, options.LastModified.HasValue ? options.LastModified.Value : DateTimeOffset.UtcNow); } else { metadata[Constants.RavenCreationDate] = DateTimeOffset.UtcNow; Historian.UpdateLastModified(metadata); } // TODO: To keep current filesystems working. We should remove when adding a new migration. metadata[Constants.CreationDate] = metadata[Constants.RavenCreationDate].Value <DateTimeOffset>().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ", CultureInfo.InvariantCulture); Historian.Update(name, metadata); long?size = -1; Storage.Batch(accessor => { FileSystem.Synchronizations.AssertFileIsNotBeingSynced(name); AssertPutOperationNotVetoed(name, metadata); SynchronizationTask.Cancel(name); var contentLength = options.ContentLength; var contentSize = options.ContentSize; if (contentLength == 0 || contentSize.HasValue == false) { size = contentLength; if (options.TransferEncodingChunked) { size = null; } } else { size = contentSize; } FileSystem.PutTriggers.Apply(trigger => trigger.OnPut(name, metadata)); using (FileSystem.DisableAllTriggersForCurrentThread()) { IndicateFileToDelete(name, etag); } var putResult = accessor.PutFile(name, size, metadata); FileSystem.PutTriggers.Apply(trigger => trigger.AfterPut(name, size, metadata)); Search.Index(name, metadata, putResult.Etag); }); Log.Debug("Inserted a new file '{0}' with ETag {1}", name, metadata.Value <string>(Constants.MetadataEtagField)); using (var contentStream = await streamAsync()) using (var readFileToDatabase = new ReadFileToDatabase(BufferPool, Storage, FileSystem.PutTriggers, contentStream, name, metadata)) { await readFileToDatabase.Execute(); if (readFileToDatabase.TotalSizeRead != size) { using (FileSystem.DisableAllTriggersForCurrentThread()) { IndicateFileToDelete(name, null); } throw new HttpResponseException(HttpStatusCode.BadRequest); } if (options.PreserveTimestamps == false) { Historian.UpdateLastModified(metadata); // update with the final file size. } Log.Debug("File '{0}' was uploaded. Starting to update file metadata and indexes", name); metadata["Content-MD5"] = readFileToDatabase.FileHash; MetadataUpdateResult updateMetadata = null; Storage.Batch(accessor => updateMetadata = accessor.UpdateFileMetadata(name, metadata, null)); int totalSizeRead = readFileToDatabase.TotalSizeRead; metadata["Content-Length"] = totalSizeRead.ToString(CultureInfo.InvariantCulture); Search.Index(name, metadata, updateMetadata.Etag); Publisher.Publish(new FileChangeNotification { Action = FileChangeAction.Add, File = name }); Log.Debug("Updates of '{0}' metadata and indexes were finished. New file ETag is {1}", name, metadata.Value <string>(Constants.MetadataEtagField)); } } catch (Exception ex) { Log.WarnException(string.Format("Failed to upload a file '{0}'", name), ex); throw; } }
public MetadataUpdateResult PutFile(string filename, long? totalSize, RavenJObject metadata, bool tombstone = false) { MetadataUpdateResult result; using (var update = new Update(session, Files, JET_prep.Insert)) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["name"], filename, Encoding.Unicode); if (totalSize != null) Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["total_size"], BitConverter.GetBytes(totalSize.Value)); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["uploaded_size"], BitConverter.GetBytes(0)); metadata.Remove(Constants.MetadataEtagField); var newEtag = uuidGenerator.CreateSequentialUuid(); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["etag"], newEtag.TransformToValueForEsentSorting()); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["metadata"], ToQueryString(metadata), Encoding.Unicode); update.Save(); result = new MetadataUpdateResult { PrevEtag = null, Etag = newEtag }; } if (!tombstone) { if (Api.TryMoveFirst(session, Details) == false) throw new InvalidOperationException("Could not find system metadata row"); Api.EscrowUpdate(session, Details, tableColumnsCache.DetailsColumns["file_count"], 1); } return result; }
private async Task ExecuteContentUpdate(RavenJObject localMetadata, SynchronizationReport report) { var tempFileName = RavenFileNameHelper.DownloadingFileName(fileName); using (var localFile = localMetadata != null ? StorageStream.Reading(fs.Storage, fileName) : null) { fs.PutTriggers.Apply(trigger => trigger.OnPut(tempFileName, metadata)); fs.Historian.UpdateLastModified(metadata); var synchronizingFile = SynchronizingFileStream.CreatingOrOpeningAndWriting(fs, tempFileName, metadata); fs.PutTriggers.Apply(trigger => trigger.AfterPut(tempFileName, null, metadata)); var provider = new MultipartSyncStreamProvider(synchronizingFile, localFile); Log.Debug("Starting to process/read multipart content of a file '{0}'", fileName); await MultipartContent.ReadAsMultipartAsync(provider); Log.Debug("Multipart content of a file '{0}' was processed/read", fileName); report.BytesCopied = provider.BytesCopied; report.BytesTransfered = provider.BytesTransfered; report.NeedListLength = provider.NumberOfFileParts; synchronizingFile.PreventUploadComplete = false; synchronizingFile.Flush(); synchronizingFile.Dispose(); metadata["Content-MD5"] = synchronizingFile.FileHash; MetadataUpdateResult updateResult = null; fs.Storage.Batch(accessor => updateResult = accessor.UpdateFileMetadata(tempFileName, metadata, null)); fs.Storage.Batch(accessor => { using (fs.DisableAllTriggersForCurrentThread()) { fs.Files.IndicateFileToDelete(fileName, null); } accessor.RenameFile(tempFileName, fileName); fs.Search.Delete(tempFileName); fs.Search.Index(fileName, metadata, updateResult.Etag); }); if (localFile == null) { Log.Debug("Temporary downloading file '{0}' was renamed to '{1}'. Indexes were updated.", tempFileName, fileName); } else { Log.Debug("Old file '{0}' was deleted. Indexes were updated.", fileName); } fs.Publisher.Publish(new FileChangeNotification { File = fileName, Action = localFile == null ? FileChangeAction.Add : FileChangeAction.Update }); } }