add MoveHelper for moving winix files - copied from Mv function
This commit is contained in:
parent
1da240afb9
commit
04f0a2f808
|
@ -0,0 +1,669 @@
|
|||
/*
|
||||
* This file is a part of Winix
|
||||
* and is distributed under the 2-Clause BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2022, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "movehelper.h"
|
||||
|
||||
|
||||
|
||||
namespace Winix
|
||||
{
|
||||
|
||||
|
||||
|
||||
MoveHelper::MoveHelper(System * system, Functions * functions)
|
||||
{
|
||||
this->system = system;
|
||||
this->functions = functions;
|
||||
}
|
||||
|
||||
|
||||
// !! CHECK ME
|
||||
// check if everywhere correct messages are sent (prepare_to, modified item/dir)
|
||||
|
||||
|
||||
void MoveHelper::Clear()
|
||||
{
|
||||
out_dir_tab.clear();
|
||||
out_item.Clear();
|
||||
out_filename.clear();
|
||||
files_item_tab.clear();
|
||||
item_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
bool MoveHelper::ParseDirCheckLastName()
|
||||
{
|
||||
if( out_has_file )
|
||||
{
|
||||
log << log1 << "MoveHelper: incorrent path" << logend;
|
||||
//slog << logerror << T("mv_incorrect_path") << logend;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Item * dir = system->dirs.GetDir(out_filename, out_dir_tab.back()->id);
|
||||
|
||||
if( dir )
|
||||
{
|
||||
out_dir_tab.push_back(dir);
|
||||
out_filename.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
morm::Finder<Item> finder(model_connector);
|
||||
|
||||
out_item = finder.
|
||||
select().
|
||||
where().
|
||||
eq(L"parent_id", out_dir_tab.back()->id).
|
||||
eq(L"url", out_filename).
|
||||
get();
|
||||
|
||||
//if( db->GetItem(out_dir_tab.back()->id, out_filename, out_item) == WINIX_ERR_OK )
|
||||
if( out_item.found() )
|
||||
{
|
||||
out_has_file = true;
|
||||
out_filename.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
bool MoveHelper::ParseDir(const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
if( dst_path.empty() )
|
||||
return false;
|
||||
|
||||
// first we should remove the last name from the dst_path
|
||||
// (it may not exist in current file system and FollowAllLinks will fail)
|
||||
size_t last_slash = dst_path.find_last_of('/');
|
||||
out_path = dst_path;
|
||||
out_filename.clear();
|
||||
|
||||
if( last_slash != std::wstring::npos && last_slash + 1 < dst_path.size() )
|
||||
{
|
||||
out_path.erase(last_slash + 1); // leaving the slash at the end
|
||||
out_filename = dst_path.c_str() + last_slash + 1;
|
||||
}
|
||||
|
||||
std::vector<Item*> root_dir_tab;
|
||||
|
||||
Item * root_dir = system->dirs.GetRootDir();
|
||||
|
||||
if( root_dir )
|
||||
{
|
||||
root_dir_tab.push_back(root_dir);
|
||||
}
|
||||
|
||||
int res = system->FollowAllLinks(root_dir_tab, out_path, out_dir_tab, out_item, false, false, check_access);
|
||||
|
||||
if( res != 0 && res != 1 )
|
||||
{
|
||||
//slog << logerror << T("mv_incorrect_dst_path") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
out_has_file = (res == 1);
|
||||
|
||||
if( !out_filename.empty() )
|
||||
return ParseDirCheckLastName();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
bool MoveHelper::CanRemoveRenameChild(const Item & child)
|
||||
{
|
||||
Item * parent_dir = system->dirs.GetDir(child.parent_id);
|
||||
|
||||
if( !parent_dir || !system->CanRemoveRenameChild(*parent_dir, child.item_content.user_id) )
|
||||
{
|
||||
log << log1 << "MoveHelper: permission denied to: " << child.url << logend;
|
||||
//slog << logerror << T("mv_permission_denied_to") << ": " << child.url << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
bool MoveHelper::MoveStaticFile(const std::wstring & from, const std::wstring & to)
|
||||
{
|
||||
if( from == to )
|
||||
{
|
||||
log << log3 << "MoveHelper: the same path to a static file: " << to << " (skipped)" << logend;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( RenameFile(from, to) )
|
||||
{
|
||||
log << log2 << "MoveHelper: moved static file from: " << from << ", to: " << to << logend;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "MoveHelper: cannot move a static file from: " << from << ", to: " << to << logend;
|
||||
//slog << logerror << T("internal_error") << logend;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
void MoveHelper::MoveStaticFile(Item & item)
|
||||
{
|
||||
bool ok = true;
|
||||
//bool res1, res2, res3, res4, res5;
|
||||
|
||||
ok = ok && system->MakeFilePath(item, old_static_path, false);
|
||||
ok = ok && (!item.item_content.file_has_thumb || system->MakeFilePath(item, old_static_thumb_path, true));
|
||||
ok = ok && system->CreateNewFile(item);
|
||||
ok = ok && system->MakeFilePath(item, new_static_path, false, true, config->upload_dirs_chmod);
|
||||
ok = ok && (!item.item_content.file_has_thumb || system->MakeFilePath(item, new_static_thumb_path, true, true, config->upload_dirs_chmod));
|
||||
|
||||
if( !ok )
|
||||
{
|
||||
log << log1 << "MoveHelper: cannot create a static path" << logend;
|
||||
//slog << logerror << T("internal_error") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( MoveStaticFile(old_static_path, new_static_path) )
|
||||
{
|
||||
item.propagate_connector();
|
||||
|
||||
//if( db->EditFileById(item, item.id) != WINIX_ERR_OK )
|
||||
if( !item.item_content.update() )
|
||||
{
|
||||
log << log1 << "MoveHelper: cannot move static file (database problem)" << logend;
|
||||
//slog << logerror << T("internal_error") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( item.item_content.file_has_thumb )
|
||||
MoveStaticFile(old_static_thumb_path, new_static_thumb_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
void MoveHelper::MoveFilesPrepareTreeGo(const Item & src_dir)
|
||||
{
|
||||
DirContainer::ParentIterator i = system->dirs.FindFirstChild(src_dir.id);
|
||||
|
||||
// go through all directories
|
||||
for( ; i != system->dirs.ParentEnd() ; i = system->dirs.NextChild(i) )
|
||||
MoveFilesPrepareTreeGo(*(i->second));
|
||||
|
||||
//files_iq.WhereParentId(src_dir.id);
|
||||
//db->GetItems(files_item_tab, files_iq);
|
||||
|
||||
morm::Finder<Item> finder(model_connector);
|
||||
|
||||
finder.
|
||||
select().
|
||||
where().
|
||||
eq(L"parent_id", src_dir.id).
|
||||
neq(L"type", static_cast<int>(Item::dir)).
|
||||
get_vector(files_item_tab);
|
||||
|
||||
for(size_t i=0 ; i<files_item_tab.size() ; ++i)
|
||||
plugin->Call(WINIX_FILE_PREPARE_TO_MOVE, &files_item_tab[i]);
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
void MoveHelper::MoveFilesPrepareTree(const Item & src_dir)
|
||||
{
|
||||
// we only calling plugins here
|
||||
// so if there is no WINIX_FILE_PREPARE_TO_MOVE message
|
||||
// we can immediately return and the database will not be bothered
|
||||
if( plugin->HasMessage(WINIX_FILE_PREPARE_TO_MOVE) )
|
||||
{
|
||||
MoveFilesPrepareTreeGo(src_dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
void MoveHelper::MoveFilesTree(const Item & dir)
|
||||
{
|
||||
DirContainer::ParentIterator i = system->dirs.FindFirstChild(dir.id);
|
||||
|
||||
// go through all directories
|
||||
for( ; i != system->dirs.ParentEnd() ; i = system->dirs.NextChild(i) )
|
||||
MoveFilesTree(*(i->second));
|
||||
|
||||
morm::Finder<Item> finder(model_connector);
|
||||
|
||||
finder.
|
||||
select().
|
||||
where().
|
||||
eq(L"parent_id", dir.id).
|
||||
neq(L"type", static_cast<int>(Item::dir)).
|
||||
get_vector(files_item_tab);
|
||||
|
||||
//files_iq.WhereParentId(dir.id);
|
||||
//db->GetItems(files_item_tab, files_iq);
|
||||
|
||||
for(size_t i=0 ; i<files_item_tab.size() ; ++i)
|
||||
{
|
||||
if( files_item_tab[i].item_content.file_type != WINIX_ITEM_FILETYPE_NONE )
|
||||
{
|
||||
plugin->Call(WINIX_FILE_PREPARE_TO_MOVE, &files_item_tab[i]);
|
||||
MoveStaticFile(files_item_tab[i]);
|
||||
plugin->Call(WINIX_FILE_MOVED, &files_item_tab[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
// uses: out_dir_tab, out_filename
|
||||
bool MoveHelper::MoveDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, const std::wstring & dst_name)
|
||||
{
|
||||
long dst_dir_id = dst_dir_tab.back()->id;
|
||||
old_url = src_dir.url;
|
||||
|
||||
if( dst_dir_id == src_dir.id || system->dirs.HasParent(dst_dir_id, src_dir.id) )
|
||||
{
|
||||
log << log1 << "MoveHelper: cannot move directory to inside it" << logend;
|
||||
//slog << logerror << T("mv_cannot_move_to_inside");
|
||||
return false;
|
||||
}
|
||||
|
||||
MoveFilesPrepareTree(src_dir);
|
||||
|
||||
if( !system->dirs.ChangeParent(src_dir.id, dst_dir_id) )
|
||||
return false;
|
||||
|
||||
src_dir.parent_id = dst_dir_id;
|
||||
old_url = src_dir.url;
|
||||
|
||||
if( !dst_name.empty() )
|
||||
{
|
||||
src_dir.url = dst_name;
|
||||
functions->PrepareUrl(src_dir);
|
||||
}
|
||||
|
||||
//Error status = db->EditParentUrlById(src_dir, src_dir.id);
|
||||
if( src_dir.update(false) )
|
||||
{
|
||||
log << log3 << "MoveHelper: directory: " << old_url << " was moved to: ";
|
||||
system->dirs.LogDir(dst_dir_tab);
|
||||
log << src_dir.url << logend;
|
||||
|
||||
MoveFilesTree(src_dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// public
|
||||
bool MoveHelper::MoveDir(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
bool res = MoveDir2(src_dir, dst_dir_id, new_url, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
bool MoveHelper::MoveDir2(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
if( src_dir.type != Item::dir )
|
||||
{
|
||||
log << "MoveHelper: a directory required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( src_dir.parent_id == -1 )
|
||||
{
|
||||
log << log1 << "MoveHelper: the root directory cannot be moved anywhere" << logend;
|
||||
//slog << logerror << T("mv_cant_move_root_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_dir) )
|
||||
return false;
|
||||
|
||||
if( src_dir.id == dst_dir_id )
|
||||
{
|
||||
if( new_url.empty() || src_dir.url == new_url )
|
||||
return true; // the same directory -- there is nothing to do
|
||||
}
|
||||
|
||||
if( !system->dirs.CreateDirTab(dst_dir_id, out_dir_tab) )
|
||||
{
|
||||
log << log1 << "MoveHelper: incorrect directory" << logend;
|
||||
//slog << logerror << T("mv_incorrect_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
return MoveDir(src_dir, out_dir_tab, new_url);
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// public
|
||||
bool MoveHelper::MoveDir(Item & src_dir, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
bool res = MoveDir2(src_dir, dst_path, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
bool MoveHelper::MoveDir2(Item & src_dir, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
if( src_dir.type != Item::dir )
|
||||
{
|
||||
log << "MoveHelper: a directory required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( src_dir.parent_id == -1 )
|
||||
{
|
||||
log << log1 << "MoveHelper: the root directory cannot be moved anywhere" << logend;
|
||||
//slog << logerror << T("mv_cant_move_root_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_dir) )
|
||||
return false;
|
||||
|
||||
if( !ParseDir(dst_path, check_access) )
|
||||
return false;
|
||||
|
||||
if( out_has_file )
|
||||
{
|
||||
log << log1 << "MoveHelper: directory can be moved only to a directory" << logend;
|
||||
//slog << logerror << T("mv_dir_can_be_moved_to_dir") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( src_dir.id == out_dir_tab.back()->id )
|
||||
{
|
||||
if( out_filename.empty() || src_dir.url == out_filename )
|
||||
return true; // the same directory -- there is nothing to do
|
||||
}
|
||||
|
||||
return MoveDir(src_dir, out_dir_tab, out_filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
bool MoveHelper::MoveFileOrSymlink(Item & src_file, std::vector<Item*> & dst_dir_tab, const std::wstring & new_url)
|
||||
{
|
||||
plugin->Call(WINIX_FILE_PREPARE_TO_MOVE, &src_file);
|
||||
|
||||
old_url = src_file.url;
|
||||
|
||||
if( !new_url.empty() )
|
||||
{
|
||||
src_file.url = new_url;
|
||||
functions->PrepareUrl(src_file);
|
||||
}
|
||||
|
||||
src_file.parent_id = dst_dir_tab.back()->id;
|
||||
|
||||
//Error status = db->EditParentUrlById(src_file, src_file.id);
|
||||
if( src_file.update(false) )
|
||||
{
|
||||
if( src_file.type == Item::file )
|
||||
log << log3 << "MoveHelper: file: ";
|
||||
else
|
||||
log << log3 << "MoveHelper: symlink: ";
|
||||
|
||||
log << old_url << " was moved to: ";
|
||||
system->dirs.LogDir(dst_dir_tab);
|
||||
log << src_file.url << logend;
|
||||
|
||||
if( src_file.item_content.file_type != WINIX_ITEM_FILETYPE_NONE )
|
||||
MoveStaticFile(src_file);
|
||||
|
||||
plugin->Call(WINIX_FILE_MOVED, &src_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// public
|
||||
bool MoveHelper::MoveFileOrSymlink(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
bool res = MoveFileOrSymlink2(src_file, dst_dir_id, new_url, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
bool MoveHelper::MoveFileOrSymlink2(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access)
|
||||
{
|
||||
if( src_file.type == Item::dir )
|
||||
{
|
||||
log << "MoveHelper: a file/symlink required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_file) )
|
||||
return false;
|
||||
|
||||
if( src_file.parent_id == dst_dir_id )
|
||||
{
|
||||
if( new_url.empty() || src_file.url == new_url )
|
||||
return true; // the same file -- there is nothing to do
|
||||
}
|
||||
|
||||
if( !system->dirs.CreateDirTab(dst_dir_id, out_dir_tab) )
|
||||
return false;
|
||||
|
||||
return MoveFileOrSymlink(src_file, out_dir_tab, new_url);
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// public
|
||||
bool MoveHelper::MoveFileOrSymlink(Item & src_file, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
bool res = MoveFileOrSymlink2(src_file, dst_path, check_access);
|
||||
Clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
bool MoveHelper::MoveFileOrSymlink2(Item & src_file, const std::wstring & dst_path, bool check_access)
|
||||
{
|
||||
if( src_file.type == Item::dir )
|
||||
{
|
||||
log << "MoveHelper: a file/symlink required" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( check_access && !CanRemoveRenameChild(src_file) )
|
||||
return false;
|
||||
|
||||
if( !ParseDir(dst_path, check_access) )
|
||||
return false;
|
||||
|
||||
if( out_has_file && src_file.parent_id == out_dir_tab.back()->id && src_file.url == out_item.url )
|
||||
{
|
||||
return true; // the same file -- there is nothing to do
|
||||
}
|
||||
|
||||
if( out_has_file )
|
||||
{
|
||||
log << log3 << "MoveHelper: such file already exists (skipping)" << logend;
|
||||
//slog << logerror << T("mv_file_exists") << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
return MoveFileOrSymlink(src_file, out_dir_tab, out_filename);
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
void MoveHelper::MoveAllFilesFromDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, bool check_access)
|
||||
{
|
||||
// content_dir_iq.WhereParentId(src_dir.id);
|
||||
// db->GetItems(item_tab, content_dir_iq);
|
||||
|
||||
morm::Finder<Item> finder(model_connector);
|
||||
|
||||
finder.
|
||||
select().
|
||||
where().
|
||||
eq(L"parent_id", src_dir.id).
|
||||
get_vector(item_tab);
|
||||
|
||||
out_filename.clear();
|
||||
|
||||
for(size_t i=0 ; i<item_tab.size() ; ++i)
|
||||
{
|
||||
if( check_access && !system->CanRemoveRenameChild(src_dir, item_tab[i].item_content.user_id) )
|
||||
{
|
||||
log << log1 << "MoveHelper: permission denied to: " << src_dir.url << logend;
|
||||
//slog << logerror << T("mv_permission_denied_to") << ": " << src_dir.url << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item_tab[i].type == Item::dir )
|
||||
MoveDir(item_tab[i], dst_dir_tab, out_filename);
|
||||
else
|
||||
MoveFileOrSymlink(item_tab[i], dst_dir_tab, out_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// public
|
||||
void MoveHelper::MoveDirContent(Item & src_dir, long dst_dir_id, bool check_access)
|
||||
{
|
||||
MoveDirContent2(src_dir, dst_dir_id, check_access);
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
void MoveHelper::MoveDirContent2(Item & src_dir, long dst_dir_id, bool check_access)
|
||||
{
|
||||
if( src_dir.type != Item::dir )
|
||||
{
|
||||
log << "MoveHelper: a directory required" << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( src_dir.parent_id == -1 )
|
||||
{
|
||||
log << log1 << "MoveHelper: the root directory cannot be moved anywhere" << logend;
|
||||
//slog << logerror << T("mv_cant_move_root_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !system->dirs.CreateDirTab(dst_dir_id, out_dir_tab) )
|
||||
{
|
||||
log << log1 << "MoveHelper: incorrect directory" << logend;
|
||||
//slog << logerror << T("mv_incorrect_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
MoveAllFilesFromDir(src_dir, out_dir_tab, check_access);
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// public
|
||||
void MoveHelper::MoveDirContent(Item & src_dir, const std::wstring & dst_dir, bool check_access)
|
||||
{
|
||||
MoveDirContent2(src_dir, dst_dir, check_access);
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////////// called /////////////////////////////
|
||||
// private
|
||||
void MoveHelper::MoveDirContent2(Item & src_dir, const std::wstring & dst_dir, bool check_access)
|
||||
{
|
||||
if( !ParseDir(dst_dir, check_access) )
|
||||
return;
|
||||
|
||||
if( out_has_file || !out_filename.empty() )
|
||||
{
|
||||
log << log1 << "MoveHelper: directory content can be moved only to a directory" << logend;
|
||||
//slog << logerror << T("mv_dir_content_can_be_moved_to_dir") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
MoveDirContent2(src_dir, out_dir_tab.back()->id, check_access);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Winix
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* This file is a part of Winix
|
||||
* and is distributed under the 2-Clause BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2022, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef headerfile_winix_winixd_utils_movehelper
|
||||
#define headerfile_winix_winixd_utils_movehelper
|
||||
|
||||
#include "core/winixmodeldeprecated.h"
|
||||
#include "core/system.h"
|
||||
#include "functions/functions.h"
|
||||
|
||||
|
||||
|
||||
namespace Winix
|
||||
{
|
||||
|
||||
|
||||
class MoveHelper : public WinixModelDeprecated
|
||||
{
|
||||
public:
|
||||
|
||||
MoveHelper(System * system, Functions * functions);
|
||||
|
||||
// moving a directory
|
||||
// new_url can be empty (in such a case the old one is preserved)
|
||||
// src_dir will be accordingly updated
|
||||
bool MoveDir(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access = true);
|
||||
bool MoveDir(Item & src_dir, const std::wstring & dst_path, bool check_access = true);
|
||||
|
||||
// moving only the content of src_dir
|
||||
// dst_path should point to an existing directory
|
||||
// src_dir will be accordingly updated
|
||||
void MoveDirContent(Item & src_dir, long dst_dir_id, bool check_access = true);
|
||||
void MoveDirContent(Item & src_dir, const std::wstring & dst_dir, bool check_access = true);
|
||||
|
||||
// moving a file
|
||||
// new_url can be empty (the old one is used then)
|
||||
// src_file will be accordingly updated
|
||||
bool MoveFileOrSymlink(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access = true);
|
||||
bool MoveFileOrSymlink(Item & src_file, const std::wstring & dst_path, bool check_access = true);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
System * system;
|
||||
Functions * functions;
|
||||
|
||||
// directories parsed by ParseDir()
|
||||
std::vector<Item*> out_dir_tab; // destination directories
|
||||
Item out_item; // destination file/symlink (if out_has_file is true)
|
||||
bool out_has_file; // if true then out_item is set
|
||||
std::wstring out_filename; // the last part in an input path (not an existing directory, file or symlink)
|
||||
// can be empty
|
||||
|
||||
// temporaries
|
||||
std::wstring out_path;
|
||||
std::wstring old_url;
|
||||
|
||||
std::wstring old_static_path;
|
||||
std::wstring old_static_thumb_path;
|
||||
std::wstring new_static_path;
|
||||
std::wstring new_static_thumb_path;
|
||||
|
||||
// for files/symlinks in a directory
|
||||
std::vector<Item> files_item_tab;
|
||||
//DbItemQuery files_iq;
|
||||
|
||||
// for moving content of a directory (all dirs/files/symlinks)
|
||||
//DbItemQuery content_dir_iq;
|
||||
std::vector<Item> item_tab;
|
||||
|
||||
|
||||
bool CanRemoveRenameChild(const Item & child);
|
||||
bool ParseDirCheckLastName();
|
||||
bool ParseDir(const std::wstring & dst_path, bool check_access);
|
||||
bool MoveStaticFile(const std::wstring & from, const std::wstring & to);
|
||||
void MoveStaticFile(Item & item);
|
||||
void MoveFilesPrepareTreeGo(const Item & src_dir);
|
||||
void MoveFilesPrepareTree(const Item & src_dir);
|
||||
void MoveFilesTree(const Item & dir);
|
||||
bool MoveDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, const std::wstring & dst_name);
|
||||
bool MoveFileOrSymlink(Item & src_file, std::vector<Item*> & dst_dir_tab, const std::wstring & new_url);
|
||||
void Clear();
|
||||
bool MoveDir2(Item & src_dir, long dst_dir_id, const std::wstring & new_url, bool check_access);
|
||||
bool MoveDir2(Item & src_dir, const std::wstring & dst_path, bool check_access);
|
||||
bool MoveFileOrSymlink2(Item & src_file, long dst_dir_id, const std::wstring & new_url, bool check_access);
|
||||
bool MoveFileOrSymlink2(Item & src_file, const std::wstring & dst_path, bool check_access);
|
||||
void MoveDirContent2(Item & src_dir, long dst_dir_id, bool check_access);
|
||||
void MoveAllFilesFromDir(Item & src_dir, std::vector<Item*> & dst_dir_tab, bool check_access);
|
||||
void MoveDirContent2(Item & src_dir, const std::wstring & dst_dir, bool check_access);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace Winix
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue