2014-08-01 13:19:27 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Yandex/logger_useful.h>
|
2014-08-04 06:36:24 +00:00
|
|
|
#include <DB/Columns/IColumn.h>
|
2014-08-01 13:19:27 +00:00
|
|
|
#include <Poco/AutoPtr.h>
|
|
|
|
#include <Poco/Util/XMLConfiguration.h>
|
2014-08-18 15:29:45 +00:00
|
|
|
#include <Poco/Path.h>
|
2014-08-01 13:19:27 +00:00
|
|
|
#include <string>
|
2014-08-04 06:36:24 +00:00
|
|
|
#include <Poco/File.h>
|
|
|
|
#include <DB/Common/escapeForFileName.h>
|
2014-08-15 14:34:45 +00:00
|
|
|
|
|
|
|
#include <boost/property_tree/ptree.hpp>
|
2014-08-15 16:46:13 +00:00
|
|
|
#include <boost/property_tree/json_parser.hpp>
|
2014-08-04 08:37:46 +00:00
|
|
|
|
2014-08-04 06:36:24 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
2014-08-01 13:19:27 +00:00
|
|
|
|
|
|
|
/// хранит размеры всех столбцов, и может проверять не побились ли столбцы
|
|
|
|
template <class Storage>
|
|
|
|
class FileChecker
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FileChecker(const std::string &file_info_path_, Storage & storage_) :
|
2014-08-15 14:34:45 +00:00
|
|
|
files_info_path(file_info_path_), files_info(), storage(storage_), log(&Logger::get("FileChecker"))
|
2014-08-01 13:19:27 +00:00
|
|
|
{
|
2014-08-18 15:29:45 +00:00
|
|
|
Poco::Path path(files_info_path);
|
|
|
|
tmp_files_info_path = path.parent().toString() + "tmp_" + path.getFileName();
|
|
|
|
|
2014-08-15 14:34:45 +00:00
|
|
|
if (Poco::File(files_info_path).exists())
|
2014-08-15 16:46:13 +00:00
|
|
|
boost::property_tree::read_json(files_info_path, files_info);
|
2014-08-01 13:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setPath(const std::string & file_info_path_)
|
|
|
|
{
|
|
|
|
files_info_path = file_info_path_;
|
|
|
|
}
|
|
|
|
|
2014-08-04 06:36:24 +00:00
|
|
|
using Files = std::vector<Poco::File>;
|
|
|
|
|
2014-08-04 11:16:20 +00:00
|
|
|
void update(const Poco::File & file)
|
|
|
|
{
|
|
|
|
updateTree(file);
|
|
|
|
saveTree();
|
|
|
|
}
|
|
|
|
|
2014-08-04 06:36:24 +00:00
|
|
|
void update(const Files::iterator & begin, const Files::iterator & end)
|
2014-08-01 13:19:27 +00:00
|
|
|
{
|
|
|
|
for (auto it = begin; it != end; ++it)
|
2014-08-04 11:16:20 +00:00
|
|
|
updateTree(*it);
|
|
|
|
saveTree();
|
2014-08-01 13:19:27 +00:00
|
|
|
}
|
|
|
|
|
2014-08-06 13:22:52 +00:00
|
|
|
/// Проверяем файлы, параметры которых указаны в sizes.json
|
2014-08-05 12:50:20 +00:00
|
|
|
bool check() const
|
2014-08-01 13:19:27 +00:00
|
|
|
{
|
2014-08-04 11:16:20 +00:00
|
|
|
bool correct = true;
|
2014-08-15 14:34:45 +00:00
|
|
|
if (!files_info.empty())
|
2014-09-02 16:26:30 +00:00
|
|
|
for (auto & node : files_info.get_child("yandex"))
|
2014-08-06 13:22:52 +00:00
|
|
|
{
|
2014-08-15 14:34:45 +00:00
|
|
|
std::string filename = unescapeForFileName(node.first);
|
|
|
|
size_t expected_size = std::stoull(node.second.get<std::string>("size"));
|
2014-08-05 13:41:07 +00:00
|
|
|
|
2014-08-15 14:34:45 +00:00
|
|
|
Poco::File file(Poco::Path(files_info_path).parent().toString() + "/" + filename);
|
|
|
|
if (!file.exists())
|
|
|
|
{
|
|
|
|
LOG_ERROR(log, "File " << file.path() << " doesn't exists");
|
|
|
|
correct = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t real_size = file.getSize();
|
|
|
|
if (real_size != expected_size)
|
|
|
|
{
|
|
|
|
LOG_ERROR(log, "Size of " << file.path() << " is wrong. Size is " << real_size << " but should be " << expected_size);
|
|
|
|
correct = false;
|
|
|
|
}
|
2014-08-01 13:19:27 +00:00
|
|
|
}
|
2014-08-04 11:16:20 +00:00
|
|
|
return correct;
|
2014-08-01 13:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2014-08-04 11:16:20 +00:00
|
|
|
void updateTree(const Poco::File & file)
|
|
|
|
{
|
2014-09-02 16:26:30 +00:00
|
|
|
files_info.put(std::string("yandex.") + escapeForFileName(Poco::Path(file.path()).getFileName()) + ".size", std::to_string(file.getSize()));
|
2014-08-04 11:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void saveTree()
|
|
|
|
{
|
2014-09-02 13:39:31 +00:00
|
|
|
boost::property_tree::write_json(tmp_files_info_path, files_info, std::locale());
|
|
|
|
|
|
|
|
Poco::File current_file(files_info_path);
|
2014-08-18 15:29:45 +00:00
|
|
|
|
2014-09-02 13:39:31 +00:00
|
|
|
if (current_file.exists())
|
2014-08-18 15:29:45 +00:00
|
|
|
{
|
2014-09-02 13:39:31 +00:00
|
|
|
std::string old_file_name = files_info_path + ".old";
|
|
|
|
current_file.renameTo(old_file_name);
|
2014-08-18 15:29:45 +00:00
|
|
|
Poco::File(tmp_files_info_path).renameTo(files_info_path);
|
|
|
|
Poco::File(old_file_name).remove();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Poco::File(tmp_files_info_path).renameTo(files_info_path);
|
2014-08-04 11:16:20 +00:00
|
|
|
}
|
|
|
|
|
2014-08-01 13:19:27 +00:00
|
|
|
std::string files_info_path;
|
2014-08-18 15:29:45 +00:00
|
|
|
std::string tmp_files_info_path;
|
2014-08-01 13:19:27 +00:00
|
|
|
|
2014-08-15 14:34:45 +00:00
|
|
|
using PropertyTree = boost::property_tree::ptree;
|
|
|
|
PropertyTree files_info;
|
2014-08-01 13:19:27 +00:00
|
|
|
|
|
|
|
Storage & storage;
|
|
|
|
Logger * log;
|
|
|
|
};
|
2014-08-04 06:36:24 +00:00
|
|
|
}
|