/// <summary> /// Called when this file is being copied. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New file name.</param> /// <param name="deep">Whether children items shall be copied. Ignored for files.</param> /// <param name="multistatus">Information about items that failed to copy.</param> public override async Task CopyToAsync(IItemCollectionAsync destFolder, string destName, bool deep, MultistatusException multistatus) { DavFolder targetFolder = (DavFolder)destFolder; if (!await context.DataLakeStoreService.ExistsAsync(targetFolder.Path)) { throw new DavException("Target directory doesn't exist", DavStatus.CONFLICT); } string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName); // If an item with the same name exists - remove it. try { if (await context.GetHierarchyItemAsync(targetPath) is { } item) { await item.DeleteAsync(multistatus); } } catch (DavException ex) { // Report exception to client and continue with other items by returning from recursion. multistatus.AddInnerException(targetPath, ex); return; } await context.DataLakeStoreService.CopyItemAsync(Path, targetFolder.Path, destName, ContentLength, dataCloudItem.Properties); await context.socketService.NotifyRefreshAsync(targetFolder.Path); }
/// <summary> /// Called when children of this folder are being listed. /// </summary> /// <param name="propNames">List of properties to retrieve with the children. They will be queried by the engine later.</param> /// <returns>Children of this folder.</returns> public virtual async Task <IEnumerable <IHierarchyItemAsync> > GetChildrenAsync(IList <PropertyName> propNames) { // Enumerates all child files and folders. // You can filter children items in this implementation and // return only items that you want to be visible for this // particular user. IList <IHierarchyItemAsync> children = new List <IHierarchyItemAsync>(); FileSystemInfo[] fileInfos = null; fileInfos = dirInfo.GetFileSystemInfos(); foreach (FileSystemInfo fileInfo in fileInfos) { string childPath = Path + EncodeUtil.EncodeUrlPart(fileInfo.Name); IHierarchyItemAsync child = await context.GetHierarchyItemAsync(childPath); if (child != null) { children.Add(child); } } return(children); }
/// <summary> /// Called when this folder is being moved or renamed. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New name of this folder.</param> /// <param name="multistatus">Information about child items that failed to move.</param> public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus) { // in this function we move item by item, because we want to check if each item is not locked. if (!(destFolder is DavFolder)) { throw new DavException("Target folder doesn't exist", DavStatus.CONFLICT); } DavFolder targetFolder = (DavFolder)destFolder; if (IsRecursive(targetFolder)) { throw new DavException("Cannot move folder to its subtree.", DavStatus.FORBIDDEN); } string newDirPath = System.IO.Path.Combine(targetFolder.FullPath, destName); string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName); try { // Remove item with the same name at destination if it exists. IHierarchyItemAsync item = await context.GetHierarchyItemAsync(targetPath); if (item != null) { await item.DeleteAsync(multistatus); } await targetFolder.CreateFolderAsync(destName); } catch (DavException ex) { // Continue the operation but report error with destination path to client. multistatus.AddInnerException(targetPath, ex); return; } // Move child items. bool movedSuccessfully = true; IFolderAsync createdFolder = (IFolderAsync)await context.GetHierarchyItemAsync(targetPath); foreach (DavHierarchyItem item in (await GetChildrenAsync(new PropertyName[0], null, null, new List <OrderProperty>())).Page) { try { await item.MoveToAsync(createdFolder, item.Name, multistatus); } catch (DavException ex) { // Continue the operation but report error with child item to client. multistatus.AddInnerException(item.Path, ex); movedSuccessfully = false; } } if (movedSuccessfully) { await DeleteAsync(multistatus); } }
/// <summary> /// Called when this file is being moved or renamed. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New name of this file.</param> /// <param name="multistatus">Information about items that failed to move.</param> public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus) { DavFolder targetFolder = (DavFolder)destFolder; if (targetFolder == null || !Directory.Exists(targetFolder.FullPath)) { throw new DavException("Target directory doesn't exist", DavStatus.CONFLICT); } string newDirPath = System.IO.Path.Combine(targetFolder.FullPath, destName); string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName); // If an item with the same name exists in target directory - remove it. try { IHierarchyItemAsync item = await context.GetHierarchyItemAsync(targetPath); if (item != null) { await item.DeleteAsync(multistatus); } } catch (DavException ex) { // Report exception to client and continue with other items by returning from recursion. multistatus.AddInnerException(targetPath, ex); return; } // Move the file. try { File.Move(fileSystemInfo.FullName, newDirPath); var newFileInfo = new FileInfo(newDirPath); if (FileSystemInfoExtension.IsUsingFileSystemAttribute) { await fileSystemInfo.MoveExtendedAttributes(newFileInfo); } // Locks should not be copied, delete them. if (await newFileInfo.HasExtendedAttributeAsync("Locks")) { await newFileInfo.DeleteExtendedAttributeAsync("Locks"); } } catch (UnauthorizedAccessException) { // Exception occurred with the item for which MoveTo was called - fail the operation. NeedPrivilegesException ex = new NeedPrivilegesException("Not enough privileges"); ex.AddRequiredPrivilege(targetPath, Privilege.Bind); string parentPath = System.IO.Path.GetDirectoryName(Path); ex.AddRequiredPrivilege(parentPath, Privilege.Unbind); throw ex; } }
/// <summary> /// Creates instance of User class. /// </summary> /// <param name="context">Instance of <see cref="DavContext"/> class.</param> /// <param name="userId">ID of this user</param> /// <param name="name">User name.</param> /// <param name="email">User e-mail.</param> /// <param name="created">Date when this item was created.</param> /// <param name="modified">Date when this item was modified.</param> public User(DavContext context, string userId, string name, string email, DateTime created, DateTime modified) : base(context) { this.Name = name; this.email = email; this.Path = UsersFolder.UsersFolderPath + EncodeUtil.EncodeUrlPart(userId); this.Created = created; this.Modified = modified; }
/// <summary> /// Called when this file is being copied. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New file name.</param> /// <param name="deep">Whether children items shall be copied. Ignored for files.</param> /// <param name="multistatus">Information about items that failed to copy.</param> public override async Task CopyToAsync(IItemCollectionAsync destFolder, string destName, bool deep, MultistatusException multistatus) { DavFolder targetFolder = (DavFolder)destFolder; if (targetFolder == null || !Directory.Exists(targetFolder.FullPath)) { throw new DavException("Target directory doesn't exist", DavStatus.CONFLICT); } string newFilePath = System.IO.Path.Combine(targetFolder.FullPath, destName); string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName); // If an item with the same name exists - remove it. try { IHierarchyItemAsync item = await context.GetHierarchyItemAsync(targetPath); if (item != null) { await item.DeleteAsync(multistatus); } } catch (DavException ex) { // Report error with other item to client. multistatus.AddInnerException(targetPath, ex); return; } // Copy the file togather with all extended attributes (custom props and locks). try { File.Copy(fileSystemInfo.FullName, newFilePath); var newFileSystemInfo = new FileInfo(newFilePath); if (FileSystemInfoExtension.IsUsingFileSystemAttribute) { await fileSystemInfo.CopyExtendedAttributes(newFileSystemInfo); } // Locks should not be copied, delete them. if (await fileSystemInfo.HasExtendedAttributeAsync("Locks")) { await newFileSystemInfo.DeleteExtendedAttributeAsync("Locks"); } } catch (UnauthorizedAccessException) { // Fail NeedPrivilegesException ex = new NeedPrivilegesException("Not enough privileges"); string parentPath = System.IO.Path.GetDirectoryName(Path); ex.AddRequiredPrivilege(parentPath, Privilege.Bind); throw ex; } await context.socketService.NotifyRefreshAsync(targetFolder.Path); }
internal static void AddContentDisposition(DavContext context, string name) { if (context.Request.UserAgent.Contains("MSIE")) // problem with file extensions in IE { var fileName = EncodeUtil.EncodeUrlPart(name); context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); } else context.Response.AddHeader("Content-Disposition", "attachment;"); }
/// <summary> /// Called when a new file is being created in this folder. /// </summary> /// <param name="name">Name of the new file.</param> /// <returns>The new file.</returns> public async Task <IFileAsync> CreateFileAsync(string name) { string fileName = System.IO.Path.Combine(fileSystemInfo.FullName, name); using (FileStream stream = new FileStream(fileName, FileMode.CreateNew)) { } return((IFileAsync)await context.GetHierarchyItemAsync(Path + EncodeUtil.EncodeUrlPart(name))); }
/// <summary> /// Creates file or folder with specified name inside this folder. /// </summary> /// <param name="name">File/folder name.</param> /// <param name="itemType">Type of item: file or folder.</param> /// <returns>Newly created item.</returns> private async Task <DavHierarchyItem> createChildAsync(string name, ItemType itemType) { Guid newID = Guid.NewGuid(); string commandText = @"INSERT INTO Item( ItemId , Name , Created , Modified , ParentItemId , ItemType , TotalContentLength , FileAttributes ) VALUES( @Identity , @Name , GETUTCDATE() , GETUTCDATE() , @Parent , @ItemType , 0 , @FileAttributes )"; await Context.ExecuteNonQueryAsync( commandText, "@Name", name, "@Parent", ItemId, "@ItemType", itemType, "@FileAttributes", (itemType == ItemType.Folder ? (int)FileAttributes.Directory : (int)FileAttributes.Normal), "@Identity", newID); //UpdateModified(); do not update time for folder as transaction will block concurrent files upload switch (itemType) { case ItemType.File: return(new DavFile( Context, newID, ItemId, name, Path + EncodeUtil.EncodeUrlPart(name), DateTime.UtcNow, DateTime.UtcNow, FileAttributes.Normal)); case ItemType.Folder: // do not need to return created folder return(null); default: return(null); } }
/// <summary> /// Called when this folder is being copied. /// </summary> /// <param name="destFolder">Destination parent folder.</param> /// <param name="destName">New folder name.</param> /// <param name="deep">Whether children items shall be copied.</param> /// <param name="multistatus">Information about child items that failed to copy.</param> public override async Task CopyToAsync(IItemCollectionAsync destFolder, string destName, bool deep, MultistatusException multistatus) { DavFolder targetFolder = destFolder as DavFolder; if (targetFolder == null) { throw new DavException("Target folder doesn't exist", DavStatus.CONFLICT); } if (IsRecursive(targetFolder)) { throw new DavException("Cannot copy to subfolder", DavStatus.FORBIDDEN); } string newDirLocalPath = System.IO.Path.Combine(targetFolder.FullPath, destName); string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName); // Create folder at the destination. try { if (!Directory.Exists(newDirLocalPath)) { await targetFolder.CreateFolderAsync(destName); } } catch (DavException ex) { // Continue, but report error to client for the target item. multistatus.AddInnerException(targetPath, ex); } // Copy children. IFolderAsync createdFolder = (IFolderAsync)await context.GetHierarchyItemAsync(targetPath); foreach (DavHierarchyItem item in await GetChildrenAsync(new PropertyName[0])) { if (!deep && item is DavFolder) { continue; } try { await item.CopyToAsync(createdFolder, item.Name, deep, multistatus); } catch (DavException ex) { // If a child item failed to copy we continue but report error to client. multistatus.AddInnerException(item.Path, ex); } } await context.socketService.NotifyRefreshAsync(targetFolder.Path); }
/// <summary> /// Called when a new file is being created in this folder. /// </summary> /// <param name="name">Name of the new file.</param> /// <returns>The new file.</returns> public async Task <IFileAsync> CreateFileAsync(string name) { await RequireHasTokenAsync(); string fileName = System.IO.Path.Combine(fileSystemInfo.FullName, name); using (FileStream stream = new FileStream(fileName, FileMode.CreateNew)) { } await context.socketService.NotifyRefreshAsync(Path); return((IFileAsync)await context.GetHierarchyItemAsync(Path + EncodeUtil.EncodeUrlPart(name))); }
/// <summary> /// Adds Content-Disposition header. /// </summary> /// <param name="name">File name to specified in Content-Disposition header.</param> private void AddContentDisposition(string name) { // Content-Disposition header must be generated differently in case if IE and other web browsers. if (context.Request.UserAgent.Contains("MSIE")) { string fileName = EncodeUtil.EncodeUrlPart(name); string attachment = string.Format("attachment filename=\"{0}\"", fileName); context.Response.AddHeader("Content-Disposition", attachment); } else { context.Response.AddHeader("Content-Disposition", "attachment"); } }
/// <summary> /// Called when a new file is being created in this folder. /// </summary> /// <param name="name">Name of the new file.</param> /// <returns>The new file.</returns> public async Task <IFileAsync> CreateFileAsync(string name) { await RequireHasTokenAsync(); try { await context.DataLakeStoreService.CreateFileAsync(Path, name); } catch (Exception e) { throw new DavException($"Cannot create file {name}", e); } await context.socketService.NotifyRefreshAsync(Path); return((IFileAsync)await context.GetHierarchyItemAsync(Path + EncodeUtil.EncodeUrlPart(name))); }
/// <summary> /// Reads <see cref="DavFile"/> or <see cref="DavFolder"/> depending on type /// <typeparamref name="T"/> from database. /// </summary> /// <typeparam name="T">Type of hierarchy item to read(file or folder).</typeparam> /// <param name="parentPath">Path to parent hierarchy item.</param> /// <param name="command">SQL expression which returns hierachy item records.</param> /// <param name="prms">Sequence: sql parameter1 name, sql parameter1 value, sql parameter2 name, /// sql parameter2 value...</param> /// <returns>List of requested items.</returns> public async Task <IList <T> > ExecuteItemAsync <T>(string parentPath, string command, params object[] prms) where T : class, IHierarchyItemAsync { IList <T> children = new List <T>(); using (SqlDataReader reader = await prepareCommand(command, prms).ExecuteReaderAsync()) { while (reader.Read()) { Guid itemId = (Guid)reader["ItemID"]; Guid parentId = (Guid)reader["ParentItemID"]; ItemType itemType = (ItemType)reader.GetInt32(reader.GetOrdinal("ItemType")); string name = reader.GetString(reader.GetOrdinal("Name")); DateTime created = reader.GetDateTime(reader.GetOrdinal("Created")); DateTime modified = reader.GetDateTime(reader.GetOrdinal("Modified")); FileAttributes fileAttributes = (FileAttributes)reader.GetInt32( reader.GetOrdinal("FileAttributes")); switch (itemType) { case ItemType.File: children.Add(new DavFile( this, itemId, parentId, name, parentPath + EncodeUtil.EncodeUrlPart(name), created, modified, fileAttributes) as T); break; case ItemType.Folder: children.Add(new DavFolder( this, itemId, parentId, name, (parentPath + EncodeUtil.EncodeUrlPart(name) + "/").TrimStart('/'), created, modified, fileAttributes) as T); break; } } } return(children); }
/// <summary> /// Creates file or folder with specified name inside this folder. /// </summary> /// <param name="name">File/folder name.</param> /// <param name="itemType">Type of item: file or folder.</param> /// <returns>Newly created item.</returns> private DavHierarchyItem createChild(string name, ItemType itemType) { Guid newID = Guid.NewGuid(); string commandText = itemType == ItemType.Folder ? @"INSERT INTO DMS_Folders(ID, Name, CreatedOn, ModifiedOn, ParentID, CreatorDisplayName, AutoVersion, AutoCheckedOut, TotalContentLength, Attributes) VALUES(@Identity, @Name, GETUTCDATE(), GETUTCDATE(), @Parent, @CreatorDisplayName, 0, 0, 0, @Attributes)" : @"INSERT INTO DMS_Documents(ID, Name, CreatedOn, ModifiedOn, ParentID, Comment, CreatorDisplayName, AutoVersion, AutoCheckedOut, TotalContentLength, Attributes) VALUES(@Identity, @Name, GETUTCDATE(), GETUTCDATE(), @Parent, '', @CreatorDisplayName, 0, 0, 0, @Attributes)"; Context.ExecuteNonQuery( commandText, "@Name", name, "@Parent", ItemId, "@CreatorDisplayName", CurrentUserName, "@Attributes", (itemType == ItemType.Folder ? (int)FileAttributes.Directory : (int)FileAttributes.Normal), "@Identity", newID); //UpdateModified(); do not update time for folder as transaction will block concurrent files upload switch (itemType) { case ItemType.File: return(new DavFile( Context, newID, ItemId, name, Path + EncodeUtil.EncodeUrlPart(name), DateTime.UtcNow, DateTime.UtcNow, FileAttributes.Normal)); case ItemType.Folder: // do not need to return created folder return(null); default: return(null); } }
/// <summary> /// Called when children of this folder with paging information are being listed. /// </summary> /// <param name="propNames">List of properties to retrieve with the children. They will be queried by the engine later.</param> /// <param name="offset">The number of children to skip before returning the remaining items. Start listing from from next item.</param> /// <param name="nResults">The number of items to return.</param> /// <param name="orderProps">List of order properties requested by the client.</param> /// <returns>Items requested by the client and a total number of items in this folder.</returns> public virtual async Task <PageResults> GetChildrenAsync(IList <PropertyName> propNames, long?offset, long?nResults, IList <OrderProperty> orderProps) { // Enumerates all child files and folders. // You can filter children items in this implementation and // return only items that you want to be visible for this // particular user. IList <IHierarchyItemAsync> children = new List <IHierarchyItemAsync>(); FileSystemInfo[] fileInfos = null; long totalItems = 0; fileInfos = dirInfo.GetFileSystemInfos(); totalItems = fileInfos.Length; // Apply sorting. fileInfos = SortChildren(fileInfos, orderProps); // Apply paging. if (offset.HasValue && nResults.HasValue) { fileInfos = fileInfos.Skip((int)offset.Value).Take((int)nResults.Value).ToArray(); } foreach (FileSystemInfo fileInfo in fileInfos) { string childPath = Path + EncodeUtil.EncodeUrlPart(fileInfo.Name); IHierarchyItemAsync child = await context.GetHierarchyItemAsync(childPath); if (child != null) { children.Add(child); } } return(new PageResults(children, totalItems)); }
/// <summary> /// Copies this file to another folder. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New file name in destination folder.</param> /// <param name="deep">Is not used.</param> /// <param name="multistatus">Container for errors with items other than this file.</param> public override async Task CopyToAsync( IItemCollectionAsync destFolder, string destName, bool deep, MultistatusException multistatus) { DavFolder destDavFolder = destFolder as DavFolder; if (destFolder == null) { throw new DavException("Destination folder doesn't exist.", DavStatus.CONFLICT); } if (!await destDavFolder.ClientHasTokenAsync()) { throw new LockedException("Doesn't have token for destination folder."); } DavHierarchyItem destItem = await destDavFolder.FindChildAsync(destName); if (destItem != null) { try { await destItem.DeleteAsync(multistatus); } catch (DavException ex) { multistatus.AddInnerException(destItem.Path, ex); return; } } await CopyThisItemAsync(destDavFolder, null, destName); await Context.socketService.NotifyCreatedAsync(destFolder.Path + EncodeUtil.EncodeUrlPart(destName)); }
/// <summary> /// Copy item to another destination. /// </summary> /// <param name="path">Path to item.</param> /// <param name="destFolder">Path to destination folder.</param> /// <param name="destName">Destination name.</param> /// <param name="contentLength">Size of item to copy.</param> /// <param name="sourceProps">Custom attributes to copy.</param> /// <returns></returns> public async Task CopyItemAsync(string path, string destFolder, string destName, long contentLength, IDictionary <string, string> sourceProps) { var sourceClient = GetFileClient(path); var targetFolder = GetDirectoryClient(destFolder); await CreateFileAsync(destFolder, destName); await using var memoryStream = new MemoryStream(); await sourceClient.ReadToAsync(memoryStream); memoryStream.Position = 0; string targetPath = targetFolder.Path + "/" + EncodeUtil.EncodeUrlPart(destName); await WriteItemAsync(targetPath, memoryStream, contentLength, sourceProps); await CopyExtendedAttributes(new DataCloudItem { Properties = sourceProps }, targetPath); var destItem = new DataCloudItem { Name = destName, Path = targetPath }; await DeleteExtendedAttributeAsync(destItem, "Locks"); }
internal DavFolder CopyThisItem(DavFolder destFolder, DavHierarchyItem destItem, string destName) { // returns created folder, if any, otherwise null DavFolder createdFolder = null; Guid destID; if (destItem == null) { // copy item string commandText = @"INSERT INTO DMS_Folders(ID, Name, CreatedOn, ModifiedOn, ParentID, CreatorDisplayName, AutoVersion, AutoCheckedOut, TotalContentLength, Attributes) SELECT @Identity, @Name, GETUTCDATE(), GETUTCDATE(), @Parent, CreatorDisplayName, AutoVersion, AutoCheckedOut, TotalContentLength, Attributes FROM DMS_Folders WHERE ID = @ItemId; INSERT INTO DMS_Documents(ID, Name, CreatedOn, ModifiedOn, ParentID, FileContent, ContentType, SerialNumber, CreatorDisplayName, Comment, AutoVersion, AutoCheckedOut, TotalContentLength, LastChunkSaved, Attributes) SELECT @Identity, @Name, GETUTCDATE(), GETUTCDATE(), @Parent, FileContent, ContentType, SerialNumber, CreatorDisplayName, Comment, AutoVersion, AutoCheckedOut, TotalContentLength, LastChunkSaved, Attributes FROM DMS_Documents WHERE ID = @ItemId"; destID = Guid.NewGuid(); Context.ExecuteNonQuery( commandText, "@Name", destName, "@Parent", destFolder.ItemId, "@ItemId", ItemId, "@Identity", destID); destFolder.UpdateModified(); if (this is IFolder) { createdFolder = new DavFolder( Context, destID, destFolder.ItemId, destName, destFolder.Path + EncodeUtil.EncodeUrlPart(destName) + "/", DateTime.UtcNow, DateTime.UtcNow, fileAttributes); } } else { // update existing destination destID = destItem.ItemId; string commandText = @"UPDATE DMS_Folders SET ModifiedOn = GETUTCDATE() FROM (SELECT * FROM DMS_Folders WHERE ID=@SrcID) src WHERE DMS_Folders.ID=@DestID ; UPDATE DMS_Documents SET ModifiedOn = GETUTCDATE() , ContentType = src.ContentType FROM (SELECT * FROM DMS_Documents WHERE ID=@SrcID) src WHERE DMS_Documents.ID=@DestID"; Context.ExecuteNonQuery( commandText, "@SrcID", ItemId, "@DestID", destID); // remove old properties from the destination Context.ExecuteNonQuery( "DELETE FROM DMS_DocumentProperties WHERE ItemId = @ItemId", "@ItemId", destID); } // copy properties string command = @"INSERT INTO DMS_DocumentProperties(ItemId, Name, Namespace, PropVal) SELECT @DestID, Name, Namespace, PropVal FROM DMS_DocumentProperties WHERE ItemId = @SrcID"; Context.ExecuteNonQuery( command, "@SrcID", ItemId, "@DestID", destID); return(createdFolder); }
/// <summary> /// Called when this folder is being moved or renamed. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New name of this folder.</param> /// <param name="multistatus">Information about child items that failed to move.</param> public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus) { await RequireHasTokenAsync(); DavFolder targetFolder = destFolder as DavFolder; if (targetFolder == null) { throw new DavException("Target folder doesn't exist", DavStatus.CONFLICT); } if (IsRecursive(targetFolder)) { throw new DavException("Cannot move folder to its subtree.", DavStatus.FORBIDDEN); } string newDirPath = System.IO.Path.Combine(targetFolder.FullPath, destName); string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName); try { // Remove item with the same name at destination if it exists. IHierarchyItemAsync item = await context.GetHierarchyItemAsync(targetPath); if (item != null) { await item.DeleteAsync(multistatus); } await targetFolder.CreateFolderAsync(destName); } catch (DavException ex) { // Continue the operation but report error with destination path to client. multistatus.AddInnerException(targetPath, ex); return; } // Move child items. bool movedSuccessfully = true; IFolderAsync createdFolder = (IFolderAsync)await context.GetHierarchyItemAsync(targetPath); foreach (DavHierarchyItem item in await GetChildrenAsync(new PropertyName[0])) { try { await item.MoveToAsync(createdFolder, item.Name, multistatus); } catch (DavException ex) { // Continue the operation but report error with child item to client. multistatus.AddInnerException(item.Path, ex); movedSuccessfully = false; } } if (movedSuccessfully) { await DeleteAsync(multistatus); } // Refresh client UI. await context.socketService.NotifyDeleteAsync(Path); await context.socketService.NotifyRefreshAsync(GetParentPath(targetPath)); }
internal async Task <DavFolder> CopyThisItemAsync(DavFolder destFolder, DavHierarchyItem destItem, string destName) { // returns created folder, if any, otherwise null DavFolder createdFolder = null; Guid destID; if (destItem == null) { // copy item string commandText = @"INSERT INTO Item( ItemId , Name , Created , Modified , ParentItemId , ItemType , Content , ContentType , SerialNumber , TotalContentLength , LastChunkSaved , FileAttributes ) SELECT @Identity , @Name , GETUTCDATE() , GETUTCDATE() , @Parent , ItemType , Content , ContentType , SerialNumber , TotalContentLength , LastChunkSaved , FileAttributes FROM Item WHERE ItemId = @ItemId"; destID = Guid.NewGuid(); await Context.ExecuteNonQueryAsync( commandText, "@Name", destName, "@Parent", destFolder.ItemId, "@ItemId", ItemId, "@Identity", destID); await destFolder.UpdateModifiedAsync(); if (this is IFolderAsync) { createdFolder = new DavFolder( Context, destID, destFolder.ItemId, destName, destFolder.Path + EncodeUtil.EncodeUrlPart(destName) + "/", DateTime.UtcNow, DateTime.UtcNow, fileAttributes); } } else { // update existing destination destID = destItem.ItemId; string commandText = @"UPDATE Item SET Modified = GETUTCDATE() , ItemType = src.ItemType , ContentType = src.ContentType FROM (SELECT * FROM Item WHERE ItemId=@SrcID) src WHERE Item.ItemId=@DestID"; await Context.ExecuteNonQueryAsync( commandText, "@SrcID", ItemId, "@DestID", destID); // remove old properties from the destination await Context.ExecuteNonQueryAsync( "DELETE FROM Property WHERE ItemID = @ItemID", "@ItemID", destID); } // copy properties string command = @"INSERT INTO Property(ItemID, Name, Namespace, PropVal) SELECT @DestID, Name, Namespace, PropVal FROM Property WHERE ItemID = @SrcID"; await Context.ExecuteNonQueryAsync( command, "@SrcID", ItemId, "@DestID", destID); return(createdFolder); }