/// <summary> /// Удаляет файл. /// </summary> /// <param name="folderUrl">Адрес папки.</param> /// <param name="fileUniqueID">Уникальный идентификатор файла.</param> /// <returns></returns> public bool DeleteFile(IFolderMetadata folderMetadata, Guid fileUniqueID) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (fileUniqueID == Guid.Empty) { throw new ArgumentNullException("fileUniqueID"); } this.Logger.WriteFormatMessage("DeleteFile:Начало удаления файла, folder.Url: {0}, file.UniqueID: {1}", folderMetadata.Url, fileUniqueID); bool result = false; //физического удаления для файла в блобе не предусмотрено //удаление заключается в установке Deleted для метаданных файла. IBlobFileMetadata fileMetadata = this.BlobMetadataAdapter.GetFile(folderMetadata, fileUniqueID); if (fileMetadata != null) { this.BlobMetadataAdapter.DeleteFile(fileMetadata); result = fileMetadata.Deleted; } this.Logger.WriteFormatMessage("DeleteFile:Окончание удаления файла, folder.Url: {0}, file.UniqueID: {1}", folderMetadata.Url, fileUniqueID); return(result); }
/// <summary> /// Возвращает папку по имени. /// </summary> /// <param name="name">Имя папки.</param> /// <param name="parentFolder">Дочерняя папка.</param> /// <returns></returns> internal Folder EnsureFolder(string name, Folder parentFolder = null) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } this.Logger.WriteFormatMessage("EnsureFolder:Начало получения папки, name: {0}", name); FolderUri folderUri; if (parentFolder != null) { folderUri = new FolderUri(name, parentFolder.Url); } else { folderUri = new FolderUri(name, null); } string key = string.Format("EnsureFolder_{0}", folderUri.Url); Folder folder = this.Cache.GetObject <Folder>(key); if (folder == null) { IFolderMetadata folderMetadata = this.MetadataAdapter.EnsureFolder(folderUri.Url); folder = new Folder(this, folderMetadata, parentFolder); this.Cache.AddObject(key, folder, EngineConsts.Lifetimes.Folder); } this.Logger.WriteFormatMessage("EnsureFolder:Окончание получения папки, name: {0}", name); return(folder); }
public IReplicationFolderMetadata GetReplicationFolder(IFolderMetadata folder, IStorageMetadata storage) { if (folder == null) { throw new ArgumentNullException("folder"); } if (storage == null) { throw new ArgumentNullException("storage"); } string condition = string.Format("[StorageID] = {0} AND [FolderID] = {1}", storage.ID, folder.ID); IReplicationFolderMetadata result = null; DBCollection <ReplicationFolderMetadata> replicationFolders = this.ReplicationFolderAdapter.GetReplicationFolders(condition); if (replicationFolders != null && replicationFolders.Count > 0) { result = replicationFolders[0]; } return(result); }
public IFileVersionMetadata WriteRemoteFile(IFolderMetadata folderMetadata, IRemoteFile remoteFile) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (remoteFile == null) { throw new ArgumentNullException("remoteFile"); } if (string.IsNullOrEmpty(remoteFile.Name)) { throw new ArgumentNullException("remoteFile.Name"); } if (remoteFile.Stream == null) { throw new ArgumentNullException("remoteFile.Stream"); } IBlobFileMetadata blobFileMetadata = this.BlobMetadataAdapter.CreateFile(folderMetadata, remoteFile.Name); blobFileMetadata.Name = remoteFile.Name; //резервация параметров сохранения файла с blobFileMetadata.EnsureRemoteSaveProperties(remoteFile); //запись файла IFileVersionMetadata savedVersion = this.WriteInternal(blobFileMetadata, remoteFile.Stream, remoteFile.TimeCreated); return(savedVersion); }
/// <inheritdoc/> public async Task <byte[]> CreateFolderAsync(IFolderMetadata folderMetadata) { string userFileSystemNewItemPath = Path.Combine(UserFileSystemPath, folderMetadata.Name); Logger.LogMessage($"{nameof(IFolder)}.{nameof(CreateFolderAsync)}()", userFileSystemNewItemPath); DirectoryInfo remoteStorageItem = new DirectoryInfo(Path.Combine(RemoteStoragePath, folderMetadata.Name)); remoteStorageItem.Create(); // Update remote storage folder metadata. remoteStorageItem.Attributes = folderMetadata.Attributes; remoteStorageItem.CreationTimeUtc = folderMetadata.CreationTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = folderMetadata.LastWriteTime.UtcDateTime; remoteStorageItem.LastAccessTimeUtc = folderMetadata.LastAccessTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = folderMetadata.LastWriteTime.UtcDateTime; // Get ETag from server here and save it on the client. string newEtag = "1234567890"; ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemNewItemPath); customDataManager.IsNew = false; await customDataManager.ETagManager.SetETagAsync(newEtag); await customDataManager.SetCustomColumnsAsync(new[] { new FileSystemItemPropertyData((int)CustomColumnIds.ETag, newEtag) }); return(null); }
/// <summary> /// Возвращает метаданные файла по уникальному идентификатору. /// </summary> /// <param name="uniqueID">Уникальный идентификатор.</param> /// <param name="folderMetadata">Метаданные папки в которой располагается файл.</param> /// <returns></returns> internal FileMetadata GetFile(Guid uniqueID, IFolderMetadata folderMetadata) { if (uniqueID == Guid.Empty) { throw new ArgumentNullException("uniqueID"); } if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } FileMetadata metadata = null; string query = String.Format("[UniqueID] = '{0}' AND Deleted != 1", uniqueID); string tableName = this.GetTableName(uniqueID, folderMetadata); DBObjectDistributedTable table = this.MetadataAdapter.TableActivator.GetDistributedTable(this.DBSchemaAdapter, tableName); MetadataQueryBuilder queryBuilder = new MetadataQueryBuilder(table.TablePartition.Table, this.TypeDefinition); string resultQuery = @"{SelectQuery} WHERE {Query}" .ReplaceKey("SelectQuery", queryBuilder.SelectQuery) .ReplaceKey("Query", query); DataRow resultRow = this.DataAdapter.GetDataRow(resultQuery); if (resultRow != null) { metadata = new FileMetadata(resultRow, this, folderMetadata); } return(metadata); }
/// <summary> /// Записывает файл в хранилище. /// </summary> /// <param name="folderMetadata">Метаданные папки.</param> /// <param name="fileName">Имя файла.</param> /// <param name="stream">Содержимое файла.</param> /// <returns></returns> public IFileVersionMetadata WriteFile(IFolderMetadata folderMetadata, string fileName, Stream stream) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException("fileName"); } if (stream == null) { throw new ArgumentNullException("stream"); } IBlobFileMetadata blobFileMetadata = this.BlobMetadataAdapter.CreateFile(folderMetadata, fileName); blobFileMetadata.Name = fileName; //запись файла IFileVersionMetadata savedVersion = this.WriteInternal(blobFileMetadata, stream); return(savedVersion); }
/// <summary> /// Creates a new folder in the remote storage. /// </summary> /// <param name="folderInfo">Information about the new folder.</param> /// <returns>The new ETag returned from the remote storage.</returns> public async Task <string> CreateFolderAsync(IFolderMetadata folderInfo) { Uri newFolderUri = new Uri(new Uri(RemoteStorageUri), folderInfo.Name); await Program.DavClient.CreateFolderAsync(newFolderUri); return(null); // This implementation does not support ETags on folders. }
private void EnsureMetadata(IBlobMetadata blobMetadata, IFileHeader fileHeader, long fileAbsoluteStartPosition, long fileAbsoluteEndPosition) { if (blobMetadata == null) { throw new ArgumentNullException("blobMetadata"); } if (fileHeader == null) { throw new ArgumentNullException("fileHeader"); } if (fileAbsoluteStartPosition < 0) { throw new ArgumentNullException("fileAbsolutePosition"); } if (fileAbsoluteEndPosition < 0) { throw new ArgumentNullException("fileAbsoluteEndPosition"); } if (fileAbsoluteStartPosition >= fileAbsoluteEndPosition) { throw new Exception("fileAbsoluteStartPosition не может быть больше fileAbsoluteEndPosition"); } IFolderMetadata folderMetadata = this.DataAdapter.MetadataAdapter.EnsureFolder(fileHeader.FolderUrl); IBlobFileMetadata blobFileMetadata = this.DataAdapter.BlobMetadataAdapter.GetFile(folderMetadata, fileHeader.UniqueID); if (blobFileMetadata != null) { //файл есть, проверяем текущую версию, есть ли она ICollection <IBlobFileVersionMetadata> versions = this.DataAdapter.BlobMetadataAdapter.GetVersions(blobFileMetadata); bool versionExists = false; if (versions != null) { foreach (IBlobFileVersionMetadata version in versions) { if (version.UniqueID == fileHeader.VersionUniqueID) { versionExists = true; break; } } } if (!versionExists) { this.DataAdapter.BlobMetadataAdapter.AddExistsFileVersion(this.DataAdapter.MetadataAdapter.CurrentStorage, blobMetadata, folderMetadata, fileHeader, fileAbsoluteStartPosition, fileAbsoluteEndPosition); } } else { //файла нет, создаем метаданные файла this.DataAdapter.BlobMetadataAdapter.AddExistsFileVersion(this.DataAdapter.MetadataAdapter.CurrentStorage, blobMetadata, folderMetadata, fileHeader, fileAbsoluteStartPosition, fileAbsoluteEndPosition); } }
/// <inheritdoc/> public async Task WriteAsync(IFolderMetadata folderMetadata) { Logger.LogMessage($"{nameof(IFolder)}.{nameof(WriteAsync)}()", UserFileSystemPath); DirectoryInfo remoteStorageItem = new DirectoryInfo(RemoteStoragePath); // Update remote storage folder metadata. remoteStorageItem.Attributes = folderMetadata.Attributes; remoteStorageItem.CreationTimeUtc = folderMetadata.CreationTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = folderMetadata.LastWriteTime.UtcDateTime; remoteStorageItem.LastAccessTimeUtc = folderMetadata.LastAccessTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = folderMetadata.LastWriteTime.UtcDateTime; }
/// <inheritdoc/> public async Task <byte[]> CreateFolderAsync(IFolderMetadata folderMetadata) { string userFileSystemNewItemPath = Path.Combine(UserFileSystemPath, folderMetadata.Name); Logger.LogMessage($"{nameof(IFolder)}.{nameof(CreateFolderAsync)}()", userFileSystemNewItemPath); Uri newFolderUri = new Uri(new Uri(RemoteStoragePath), folderMetadata.Name); await Program.DavClient.CreateFolderAsync(newFolderUri); // Engine.CustomDataManager(userFileSystemNewItemPath).IsNew = false; return(null); }
public IReplicationFolderMetadata CreateReplicationFolder(IFolderMetadata folder, IStorageMetadata targetStorage) { if (folder == null) { throw new ArgumentNullException("folder"); } if (targetStorage == null) { throw new ArgumentNullException("targetStorage"); } ReplicationFolderMetadata metadata = new ReplicationFolderMetadata(folder, targetStorage); return(metadata); }
public Folder(StorageEngine storage, IFolderMetadata metadata, IFolder parentFolder) { if (storage == null) { throw new ArgumentNullException("storage"); } if (metadata == null) { throw new ArgumentNullException("metadata"); } this.TypedStorage = storage; this.Metadata = metadata; this.ParentFolder = parentFolder; }
/// <summary> /// Получение названия раздела таблицы по уникальному идентификатору файла и метаданным папки. /// </summary> /// <param name="uniqueID">Идентификатор файла.</param> /// <param name="folder">Метаданные папки.</param> /// <returns>Название раздела таблицы БД.</returns> internal string GetTableName(Guid uniqueID, IFolderMetadata folder) { if (uniqueID == Guid.Empty) { throw new ArgumentNullException("file"); } if (folder == null) { throw new ArgumentNullException("folder"); } int tableIndex = Math.Abs(uniqueID.GetHashCode() % 10); return(String.Format("{0}_{1}_{2}", this.DBSchemaAdapter.TableName, folder.Url.Trim("/".ToCharArray()).Replace('/', '_'), tableIndex != 0 ? tableIndex : 10)); }
internal ReplicationFolderMetadata(IFolderMetadata folder, IStorageMetadata storage) { if (folder == null) { throw new ArgumentNullException("folder"); } if (storage == null) { throw new ArgumentNullException("storage"); } this.SourceStorage = storage; this.Folder = folder; this.StorageID = storage.ID; this.FolderID = folder.ID; }
/// <inheritdoc/> public async Task <byte[]> CreateFolderAsync(IFolderMetadata folderMetadata) { Logger.LogMessage($"{nameof(IFolder)}.{nameof(CreateFolderAsync)}()", Path.Combine(UserFileSystemPath, folderMetadata.Name)); DirectoryInfo remoteStorageItem = new DirectoryInfo(Path.Combine(RemoteStoragePath, folderMetadata.Name)); remoteStorageItem.Create(); // Update remote storage folder metadata. remoteStorageItem.Attributes = folderMetadata.Attributes; remoteStorageItem.CreationTimeUtc = folderMetadata.CreationTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = folderMetadata.LastWriteTime.UtcDateTime; remoteStorageItem.LastAccessTimeUtc = folderMetadata.LastAccessTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = folderMetadata.LastWriteTime.UtcDateTime; // Return remote storage item ID. It will be passed later into IEngine.GetFileSystemItemAsync() method. return(WindowsFileSystemItem.GetItemIdByPath(remoteStorageItem.FullName)); }
/// <summary> /// Возвращает метаданные файла хранилища. /// </summary> /// <param name="folderMetadata">Метаданные папки.</param> /// <param name="fileUniqueID">Уникальный идентификатор файла.</param> /// <returns></returns> public IFileMetadata ReadFileMetadata(IFolderMetadata folderMetadata, Guid fileUniqueID) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (fileUniqueID == Guid.Empty) { throw new ArgumentNullException("fileUniqueID"); } this.Logger.WriteFormatMessage("ReadFileMetadata:Начало получения метаданных файла, folder.Url: {0}, fileUniqueID: {1}", folderMetadata.Url, fileUniqueID); IBlobFileMetadata fileMetadata = this.BlobMetadataAdapter.GetFile(folderMetadata, fileUniqueID); this.Logger.WriteFormatMessage("ReadFileMetadata:Окончание получения метаданных файла, folder.Url: {0}, fileUniqueID: {1}", folderMetadata.Url, fileUniqueID); return(fileMetadata); }
/// <summary> /// Creates or updates folder in the remote storage. /// </summary> /// <param name="remoteStoragePath">Path of the folder to be created or updated in the remote storage.</param> /// <param name="newInfo">New information about the folder, such as modification date, attributes, custom data, etc.</param> /// <param name="mode">Specifies if a new folder should be created or existing folder should be updated.</param> /// <param name="eTagOld">The ETag to be sent to the remote storage as part of the update request to make sure the content is not overwritten.</param> /// <param name="lockInfo">Information about the lock. Null if the item is not locked.</param> /// <returns>The new ETag returned from the remote storage.</returns> protected async Task <string> CreateOrUpdateFolderAsync( string remoteStoragePath, IFolderMetadata newInfo, FileMode mode, string eTagOld = null, ServerLockInfo lockInfo = null) { DirectoryInfo remoteStorageItem = new DirectoryInfo(remoteStoragePath); try { Program.VirtualDrive.RemoteStorageMonitor.Enabled = false; // Disable RemoteStorageMonitor to avoid circular calls. remoteStorageItem.Create(); string userFileSystemPath = Mapping.ReverseMapPath(remoteStoragePath); if (mode == FileMode.Open) { // Verify that the item in the remote storage is not modified since it was downloaded to the user file system. // In your real-life application you will send the ETag to the server as part of the update request. FileSystemItemMetadataExt itemInfo = Mapping.GetUserFileSysteItemMetadata(remoteStorageItem); if (!(await VirtualDrive.GetETagManager(userFileSystemPath).ETagEqualsAsync(itemInfo))) { throw new ConflictException(Modified.Server, "Item is modified in the remote storage, ETags not equal."); } } // Update ETag/LastWriteTime in user file system, so the synchronyzation or remote storage monitor would not start the new update. // This is only required to avoid circular updates because of the simplicity of this sample. // In your real-life application you will receive a new ETag from server in the update response. string eTagNew = newInfo.LastWriteTime.ToUniversalTime().ToString("o"); await VirtualDrive.GetETagManager(userFileSystemPath).SetETagAsync(eTagNew); remoteStorageItem.Attributes = newInfo.Attributes; remoteStorageItem.CreationTimeUtc = newInfo.CreationTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = newInfo.LastWriteTime.UtcDateTime; remoteStorageItem.LastAccessTimeUtc = newInfo.LastAccessTime.UtcDateTime; remoteStorageItem.LastWriteTimeUtc = newInfo.LastWriteTime.UtcDateTime; return(eTagNew); } finally { Program.VirtualDrive.RemoteStorageMonitor.Enabled = true; } }
/// <summary> /// Возвращает контейнер блобов для папки. /// </summary> /// <param name="folderMetadata">Метаданные папки.</param> /// <returns></returns> private BlobContainer GetBlobContainer(IFolderMetadata folderMetadata) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } this.Logger.WriteFormatMessage("GetBlobContainer:Начало получения контейнера, folder.Url: {0}", folderMetadata.Url); ICollection <IBlobContainerMetadata> blobContainers = this.BlobMetadataAdapter.GetBlobContainers(folderMetadata.ID); if (blobContainers == null || blobContainers.Count == 0) { blobContainers = this.BlobMetadataAdapter.DefaultContainers; } if (blobContainers == null || blobContainers.Count == 0) { throw new Exception(string.Format("Не удалось найти ни одного контейнера блобов для папки с именем {0}", folderMetadata.Name)); } IBlobContainerMetadata metadata = null; if (blobContainers.Count > 1) { //выбираем рандомный контейнер для записи. int index = Math.Abs(Guid.NewGuid().GetHashCode() % blobContainers.Count); metadata = blobContainers.ToList()[index]; } else { metadata = blobContainers.First(); } BlobContainer container = new BlobContainer(this, metadata); this.Logger.WriteFormatMessage("GetBlobContainer:Окончание получения контейнера, folder.Url: {0}", folderMetadata.Url); return(container); }
/// <summary> /// К-тор. /// </summary> /// <param name="row">Данные.</param> /// <param name="adapter">Адаптер метаданных файла.</param> /// <param name="folderMetadata">Метаданные папки.</param> internal FileMetadata(DataRow row, FileAdapter adapter, IFolderMetadata folderMetadata) { if (row == null) { throw new ArgumentNullException("row"); } if (adapter == null) { throw new ArgumentNullException("adapter"); } if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } this.FolderMetadata = folderMetadata; this.MetadataRow = row; this.Adapter = adapter; }
/// <summary> /// Возвращает метаданные папки репликации. Если ее не существует, то создает ее. /// </summary> /// <param name="folder">Папка.</param> /// <param name="sourceStorage">Узел источник для репликации.</param> /// <returns></returns> public IReplicationFolderMetadata EnsureReplicationFolder(IFolderMetadata folder, IStorageMetadata sourceStorage) { if (folder == null) { throw new ArgumentNullException("folder"); } if (sourceStorage == null) { throw new ArgumentNullException("sourceStorage"); } IReplicationFolderMetadata replicationFolder = this.GetReplicationFolder(folder, sourceStorage); if (replicationFolder == null) { replicationFolder = new ReplicationFolderMetadata(folder, sourceStorage); this.SaveReplicationFolder(replicationFolder); } return(replicationFolder); }
/// <summary> /// Создает новый экземпляр метаданных файлов. /// </summary> /// <param name="folderMetadata">Метаданные папки.</param> /// <param name="fileName">Название файла.</param> /// <returns></returns> internal FileMetadata CreateFile(IFolderMetadata folderMetadata, string fileName) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (String.IsNullOrEmpty(fileName)) { throw new ArgumentNullException("fileName"); } FileMetadata file = new FileMetadata(this); file.UniqueID = Guid.NewGuid(); file.VersionUniqueID = Guid.NewGuid(); file.FolderID = folderMetadata.ID; file.FolderMetadata = folderMetadata; file.Name = fileName; return(file); }
public Tuple <Guid, Guid>[] GetReplicationFiles(IStorageMetadata requestNode, IFolderMetadata folder, DateTime from) { if (requestNode == null) { throw new ArgumentNullException("requestNode"); } if (folder == null) { throw new ArgumentNullException("folder"); } List <Tuple <Guid, Guid> > files = new List <Tuple <Guid, Guid> >(); string folderDBName = folder.Url.Trim('/').Replace('/', '_'); string versionsPostfix = "Versions"; string searchPattern = string.Format("Files_{0}_%_{1}", folderDBName, versionsPostfix); Dictionary <string, bool> partitions = this.GetExistsTables(searchPattern); List <FileVersionData> allVersions = new List <FileVersionData>(); //идентификатор узла хранилища, который запрашивает файлы //т.е. для текущего узла, на который пришел запрос он будет являтся //узлом назначения для отправки файлов. int targetStorageID = requestNode.ID; if (partitions != null && partitions.Count > 0) { int n = MetadataConsts.Replication.BatchSize / partitions.Count; //1 - получить TOP(n) файлов из каждого partition string partitionsQuery = string.Empty; foreach (string partition in partitions.Keys) { if (!string.IsNullOrEmpty(partitionsQuery)) { partitionsQuery += string.Format(" {0}UNION ALL{0} ", Environment.NewLine); } string filesTableName = partition.TrimEnd(string.Format("_{0}", versionsPostfix).ToCharArray()); partitionsQuery += string.Format(@"SELECT TOP {0} f.UniqueID as FID, v.UniqueID as VID, v.TimeCreated FROM [{1}] v WITH(NOLOCK) INNER JOIN [{2}] f ON f.ID = v.FileID AND v.CreatedStorageID <> {3} AND v.TimeCreated > @startDate", n, partition, filesTableName, targetStorageID); } if (!string.IsNullOrEmpty(partitionsQuery)) { string resultQuery = string.Format("WITH AllPartitions AS ({0}) SELECT FID, VID, TimeCreated FROM AllPartitions ORDER BY TimeCreated ASC", partitionsQuery); DateTime startDate; if (from == DateTime.MinValue) { //пришла пустая дата //выдаем минимальную дату ms sql startDate = new DateTime(1753, 1, 1, 0, 0, 0, DateTimeKind.Utc); } else { //пришла дата startDate = new DateTime(from.Year, from.Month, from.Day, from.Hour, from.Minute, from.Second, 0, DateTimeKind.Utc); } SqlParameter startDateParam = new SqlParameter("startDate", startDate); DataTable resultTable = this.DataAdapter.GetDataTable(resultQuery, startDateParam); if (resultTable != null && resultTable.Rows != null) { using (resultTable) { foreach (DataRow row in resultTable.Rows) { //FID, VID, TimeCreated Guid fileID = DataRowReader.GetGuidValue(row, "FID"); if (fileID == Guid.Empty) { throw new Exception(string.Format("Не удалось получить идентификатор файла")); } Guid versionID = DataRowReader.GetGuidValue(row, "VID"); if (versionID == Guid.Empty) { throw new Exception(string.Format("Не удалось получить идентификатор версии файла")); } DateTime versionTime = DataRowReader.GetDateTimeValue(row, "TimeCreated"); if (versionTime == DateTime.MinValue) { throw new Exception(string.Format("Не удалось получить дату создания версии файла")); } FileVersionData fileVersionData = new FileVersionData(fileID, versionID, versionTime); allVersions.Add(fileVersionData); } } } //сортируем и формируем кортеж идентификаторов if (allVersions.Count > 1) { var sortedVersions = allVersions.OrderBy(v => v.VersionTime); foreach (FileVersionData version in allVersions) { files.Add(Tuple.Create <Guid, Guid>(version.FileID, version.VersionID)); } } } } Tuple <Guid, Guid>[] filesToReplication = files.ToArray(); return(filesToReplication); }
/// <inheritdoc/> public async Task WriteAsync(IFolderMetadata folderMetadata) { Logger.LogMessage($"{nameof(IFolder)}.{nameof(WriteAsync)}()", UserFileSystemPath); }
/// <summary> /// Updates folder in the remote storage. /// </summary> /// <param name="folderInfo">New folder information.</param> /// <param name="eTagOld">The ETag to be sent to the remote storage as part of the update request to make sure the content is not overwritten.</param> /// <param name="lockInfo">Information about the lock. Null if the item is not locked.</param> /// <returns>The new ETag returned from the remote storage.</returns> public async Task <string> UpdateAsync(IFolderMetadata folderInfo, string eTagOld = null, ServerLockInfo lockInfo = null) { return(await CreateOrUpdateFolderAsync(RemoteStoragePath, folderInfo, FileMode.Open, eTagOld, lockInfo)); }
/// <summary> /// Creates a folder in the remote storage. /// </summary> /// <param name="folderInfo">Information about the new folder.</param> /// <returns>New ETag returned from the remote storage.</returns> public async Task <string> CreateFolderAsync(IFolderMetadata folderInfo) { string itemPath = Path.Combine(RemoteStoragePath, folderInfo.Name); return(await CreateOrUpdateFolderAsync(itemPath, folderInfo, FileMode.CreateNew)); }
/// <summary> /// Возвращает папку по адресу. /// </summary> /// <param name="url">Адрес папки.</param> /// <param name="throwIfNotExists">Выбросить исключение, если папка не существует.</param> /// <returns></returns> internal Folder GetFolderInternal(string url, bool throwIfNotExists = true) { if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } this.Logger.WriteFormatMessage("GetFolderInternal:Начало получения папки, url: {0}", url); //построение и обход дерева сегментов url FolderUri folderUri = new FolderUri(url); List <FolderUri> segments = new List <FolderUri>(); FolderUri tmpFolderUri = folderUri; while (tmpFolderUri != null) { segments.Add(tmpFolderUri); tmpFolderUri = tmpFolderUri.ParentUri; } //сортировка для обхода с корневой папки IOrderedEnumerable <FolderUri> sortedSegments = segments.OrderBy(s => s.Url.Length); ICollection <IFolderMetadata> foldersMetadata = this.MetadataAdapter.GetFolders(sortedSegments.Select(s => s.Url).ToArray()); Dictionary <string, IFolderMetadata> foldersMetadataByUrl = new Dictionary <string, IFolderMetadata>(); if (foldersMetadata != null) { foreach (IFolderMetadata folderMetadata in foldersMetadata) { if (!foldersMetadataByUrl.ContainsKey(folderMetadata.Url)) { foldersMetadataByUrl.Add(folderMetadata.Url.ToLower(), folderMetadata); } } } Folder resultFolder = null; Folder lastSegmentFolder = null; foreach (FolderUri segment in sortedSegments) { IFolderMetadata folderMetadata = null; string urlLower = segment.Url.ToLower(); if (foldersMetadataByUrl.ContainsKey(urlLower)) { folderMetadata = foldersMetadataByUrl[urlLower]; } //цепочка оборвалась if (folderMetadata == null) { if (throwIfNotExists) { throw new Exception(string.Format("Не удалось найти папку по адресу {0}", segment.Url)); } else { lastSegmentFolder = null; break; } } else { lastSegmentFolder = new Folder(this, folderMetadata, lastSegmentFolder); } } resultFolder = lastSegmentFolder; this.Logger.WriteFormatMessage("GetFolderInternal:Окончание получения папки, url: {0}", url); return(resultFolder); }
/// <summary> /// Создает метаданные существующего файла. /// </summary> /// <param name="storageMetadata">Метаданные хранилища.</param> /// <param name="blobMetadata">Метаданные блоба.</param> /// <param name="folderMetadata">Метаданные папки.</param> /// <param name="fileHeader">Заголовок файла.</param> /// <param name="blobStartPosition">Начальная позиция файла в блобе.</param> /// <param name="blobEndPosition">Конечная позиция файла в блобе.</param> /// <returns></returns> public IBlobFileMetadata AddExistsFileVersion(IStorageMetadata storageMetadata, IBlobMetadata blobMetadata, IFolderMetadata folderMetadata, IFileHeader fileHeader, long blobStartPosition, long blobEndPosition) { if (storageMetadata == null) { throw new ArgumentNullException("storageMetadata"); } if (blobMetadata == null) { throw new ArgumentNullException("blobMetadata"); } if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (fileHeader == null) { throw new ArgumentNullException("fileHeader"); } if (blobStartPosition < 0) { throw new ArgumentNullException("blobStartPosition"); } IBlobFileHeader blobHeader = (IBlobFileHeader)((object)fileHeader); FileMetadata file = this.FileAdapter.GetFile(fileHeader.UniqueID, folderMetadata); bool justCreated = false; if (file == null) { justCreated = true; file = new FileMetadata(this.FileAdapter); file.UniqueID = fileHeader.UniqueID; file.VersionUniqueID = fileHeader.VersionUniqueID; file.FolderID = folderMetadata.ID; file.FolderMetadata = folderMetadata; file.Name = fileHeader.FileName; file.BlobID = blobMetadata.ID; file.BlobStartPosition = blobStartPosition; file.BlobEndPosition = blobEndPosition; file.Deleted = false; file.Size = blobHeader.ContentLength; file.TimeCreated = fileHeader.TimeCreated; file.TimeModified = fileHeader.TimeCreated; this.FileAdapter.UpdateFileTransparent(file); } else { if (file.Versions.Any(x => x.UniqueID == fileHeader.VersionUniqueID)) { throw new Exception(String.Format("Версия с идентификатором [{0}] уже существует.", fileHeader.VersionUniqueID.ToString())); } } //создание версии файла FileVersionMetadata version = new FileVersionMetadata(file); version.UniqueID = fileHeader.VersionUniqueID; version.BlobID = blobMetadata.ID; version.BlobStartPosition = blobStartPosition; version.BlobEndPosition = blobEndPosition; version.Size = blobHeader.ContentLength; version.TimeCreated = fileHeader.TimeCreated; version.CreatedStorageID = storageMetadata.ID; version.Name = fileHeader.FileName; //сохранение версии this.FileAdapter.VersionAdapter.InsertVerion(file, version); file.ResetVersions(); //обновление параметров существующего файла if (!justCreated) { bool fileUpdate = false; if (version.TimeCreated > file.TimeModified) { file.TimeModified = version.TimeCreated; file.VersionUniqueID = version.UniqueID; file.BlobID = version.BlobID; fileUpdate = true; } if (version.TimeCreated < file.TimeCreated) { file.TimeCreated = version.TimeCreated; fileUpdate = true; } //обновление файла if (fileUpdate) { this.FileAdapter.UpdateFileTransparent(file); } } return(file); }
public IBlobFileMetadata CreateFile(IFolderMetadata folderMetadata, string fileName) { return(this.FileAdapter.CreateFile(folderMetadata, fileName)); }
/// <summary> /// Updates this folder info in the remote storage. /// </summary> /// <param name="folderInfo">New folder information.</param> /// <param name="eTagOld">The ETag to be sent to the remote storage as part of the update request to make sure the content is not overwritten.</param> /// <param name="lockInfo">Information about the lock. Null is passed if the item is not locked.</param> /// <returns>The new ETag returned from the remote storage.</returns> public async Task <string> UpdateAsync(IFolderMetadata folderInfo, string eTagOld = null, ServerLockInfo lockInfo = null) { return(null); }