2011-10-30 11:30:52 +00:00
|
|
|
|
#include <Poco/DirectoryIterator.h>
|
|
|
|
|
#include <Poco/FileStream.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/ParserCreateQuery.h>
|
|
|
|
|
#include <DB/Parsers/ASTCreateQuery.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Interpreters/InterpreterCreateQuery.h>
|
|
|
|
|
#include <DB/Interpreters/loadMetadata.h>
|
|
|
|
|
|
2013-01-17 19:36:34 +00:00
|
|
|
|
#include <DB/IO/ReadBufferFromFile.h>
|
|
|
|
|
#include <DB/IO/WriteBufferFromString.h>
|
|
|
|
|
#include <DB/IO/copyData.h>
|
|
|
|
|
|
2011-10-30 11:30:52 +00:00
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void executeCreateQuery(const String & query, Context & context, const String & database, const String & file_name)
|
|
|
|
|
{
|
|
|
|
|
const char * begin = query.data();
|
|
|
|
|
const char * end = begin + query.size();
|
|
|
|
|
const char * pos = begin;
|
|
|
|
|
|
|
|
|
|
ParserCreateQuery parser;
|
|
|
|
|
ASTPtr ast;
|
|
|
|
|
String expected;
|
|
|
|
|
bool parse_res = parser.parse(pos, end, ast, expected);
|
|
|
|
|
|
|
|
|
|
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
|
|
|
|
|
if (!parse_res || (pos != end && *pos != ';'))
|
|
|
|
|
throw DB::Exception("Syntax error while executing query from file " + file_name + ": failed at position "
|
|
|
|
|
+ Poco::NumberFormatter::format(pos - begin) + ": "
|
|
|
|
|
+ std::string(pos, std::min(SHOW_CHARS_ON_SYNTAX_ERROR, end - pos))
|
|
|
|
|
+ ", expected " + (parse_res ? "end of query" : expected) + ".",
|
|
|
|
|
DB::ErrorCodes::SYNTAX_ERROR);
|
|
|
|
|
|
|
|
|
|
ASTCreateQuery & ast_create_query = dynamic_cast<ASTCreateQuery &>(*ast);
|
|
|
|
|
ast_create_query.attach = true;
|
|
|
|
|
ast_create_query.database = database;
|
2012-03-09 03:06:09 +00:00
|
|
|
|
|
2011-11-01 15:16:04 +00:00
|
|
|
|
InterpreterCreateQuery interpreter(ast, context);
|
2013-01-17 20:31:44 +00:00
|
|
|
|
interpreter.execute(true);
|
2011-10-30 11:30:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void loadMetadata(Context & context)
|
|
|
|
|
{
|
|
|
|
|
/// Здесь хранятся определения таблиц
|
2012-08-02 17:33:31 +00:00
|
|
|
|
String path = context.getPath() + "metadata";
|
2011-10-30 11:30:52 +00:00
|
|
|
|
|
|
|
|
|
/// Цикл по базам данных
|
|
|
|
|
Poco::DirectoryIterator dir_end;
|
|
|
|
|
for (Poco::DirectoryIterator it(path); it != dir_end; ++it)
|
|
|
|
|
{
|
|
|
|
|
if (!it->isDirectory())
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-03-09 03:56:12 +00:00
|
|
|
|
/// Для директории .svn
|
|
|
|
|
if (it.name().at(0) == '.')
|
|
|
|
|
continue;
|
|
|
|
|
|
2011-11-05 23:31:19 +00:00
|
|
|
|
executeCreateQuery("ATTACH DATABASE " + it.name(), context, it.name(), it->path());
|
|
|
|
|
|
2011-10-30 11:30:52 +00:00
|
|
|
|
/// Цикл по таблицам
|
|
|
|
|
for (Poco::DirectoryIterator jt(it->path()); jt != dir_end; ++jt)
|
|
|
|
|
{
|
2013-01-20 23:47:23 +00:00
|
|
|
|
if (jt.name() == ".svn")
|
|
|
|
|
continue;
|
|
|
|
|
|
2011-10-30 11:30:52 +00:00
|
|
|
|
/// Файлы имеют имена вида table_name.sql
|
|
|
|
|
if (jt.name().compare(jt.name().size() - 4, 4, ".sql"))
|
|
|
|
|
throw Exception("Incorrect file extension: " + jt.name() + " in metadata directory " + it->path(), ErrorCodes::INCORRECT_FILE_NAME);
|
|
|
|
|
|
2013-01-17 19:36:34 +00:00
|
|
|
|
String s;
|
|
|
|
|
{
|
|
|
|
|
ReadBufferFromFile in(jt->path(), 32768);
|
|
|
|
|
WriteBufferFromString out(s);
|
|
|
|
|
copyData(in, out);
|
|
|
|
|
}
|
2011-10-30 11:30:52 +00:00
|
|
|
|
|
2012-09-27 18:27:05 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
2013-01-17 19:36:34 +00:00
|
|
|
|
executeCreateQuery(s, context, it.name(), jt->path());
|
2012-09-27 18:27:05 +00:00
|
|
|
|
}
|
|
|
|
|
catch (const DB::Exception & e)
|
|
|
|
|
{
|
2012-11-08 18:30:49 +00:00
|
|
|
|
throw Exception("Cannot create table from metadata file " + jt->path() + ", error: " + e.displayText(),
|
2012-09-27 18:27:05 +00:00
|
|
|
|
ErrorCodes::CANNOT_CREATE_TABLE_FROM_METADATA);
|
|
|
|
|
}
|
2011-10-30 11:30:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|