/// <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);
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        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);
        }
Exemple #6
0
        /// <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);
        }
Exemple #8
0
        /// <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;
        }
Exemple #11
0
        /// <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);
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        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;
        }
Exemple #14
0
        /// <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));
        }
Exemple #15
0
        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;
        }
Exemple #16
0
        /// <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);
        }
Exemple #18
0
        /// <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);
        }
Exemple #20
0
        /// <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;
        }
Exemple #21
0
        /// <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);
        }
Exemple #22
0
        /// <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);
        }
Exemple #23
0
        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);
        }
Exemple #24
0
 /// <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));
        }
Exemple #27
0
        /// <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);
        }
Exemple #28
0
        /// <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);
        }
Exemple #29
0
 public IBlobFileMetadata CreateFile(IFolderMetadata folderMetadata, string fileName)
 {
     return(this.FileAdapter.CreateFile(folderMetadata, fileName));
 }
Exemple #30
0
 /// <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);
 }