diff --git a/src/tool1cd/CMakeLists.txt b/src/tool1cd/CMakeLists.txt index 77bd1916..f578297e 100644 --- a/src/tool1cd/CMakeLists.txt +++ b/src/tool1cd/CMakeLists.txt @@ -6,13 +6,13 @@ set (TOOL1CD_SOURCES MessageRegistration.cpp Class_1CD.cpp V8Object.cpp Field.cpp Index.cpp Table.cpp TableFiles.cpp TableFileStream.cpp MemBlock.cpp CRC32.cpp Packdata.cpp PackDirectory.cpp FieldType.cpp DetailedException.cpp BinaryDecimalNumber.cpp save_depot_config.cpp save_part_depot_config.cpp - SupplierConfig.cpp TableRecord.cpp BinaryGuid.cpp TableIterator.cpp) + SupplierConfig.cpp TableRecord.cpp BinaryGuid.cpp TableIterator.cpp SupplierConfigBuilder.cpp) set (TOOL1CD_HEADERS MessageRegistration.h Class_1CD.h Common.h ConfigStorage.h Parse_tree.h TempStream.h Base64.h UZLib.h Messenger.h db_ver.h NodeTypes.h V8Object.h Constants.h Field.h Index.h Table.h TableFiles.h TableFileStream.h MemBlock.h CRC32.h Packdata.h PackDirectory.h FieldType.h DetailedException.h - BinaryDecimalNumber.h SupplierConfig.h TableRecord.h BinaryGuid.h TableIterator.h) + BinaryDecimalNumber.h SupplierConfig.h TableRecord.h BinaryGuid.h TableIterator.h SupplierConfigBuilder.h) # .CF API set (TOOL1CD_SOURCES ${TOOL1CD_SOURCES} cfapi/V8File.cpp cfapi/V8Catalog.cpp cfapi/TV8FileStream.cpp diff --git a/src/tool1cd/Class_1CD.cpp b/src/tool1cd/Class_1CD.cpp index 93fc1b41..b5834589 100755 --- a/src/tool1cd/Class_1CD.cpp +++ b/src/tool1cd/Class_1CD.cpp @@ -525,211 +525,10 @@ void T_1CD::find_supplier_configs() } //--------------------------------------------------------------------------- -void T_1CD::add_supplier_config(TableFile* tf) +void T_1CD::add_supplier_config(TableFile* table_file) { - ContainerFile* f; - TStream* s; - int32_t i; - V8Catalog* cat = nullptr; - V8Catalog* cat2; - V8File* file; - tree* tr = nullptr; - String filenamemeta; - String nodetype; - String _name; // имя конфигурация поставщика - String _supplier; // синоним конфигурация поставщика - String _version; // версия конфигурация поставщика - - f = new ContainerFile(tf, tf->name); - if(!f->open()) - { - delete f; - return; - } - - s = new TTempStream; - - try - { - try - { - ZInflateStream(f->stream, s); - } - catch(...) - { - msreg_m.AddError("Ошибка распаковки конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя", tf->name); - delete s; - return; - } - f->close(); - delete f; - f = nullptr; - - cat = new V8Catalog(s, true); - s = nullptr; - file = cat->GetFile("version"); - if(!file) - { - msreg_m.AddError("Не найден файл version в конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name); - delete cat; - return; - } - - tr = file->get_tree(); - i = (*tr)[0][0][0].get_value().ToInt(); - delete tr; - tr = nullptr; - - #ifdef _DEBUG - msreg_m.AddDebugMessage("Найдена версия контейнера конфигурации поставщика", MessageState::Info, - "Таблица", tf->t->getname(), - "Имя файла", tf->name, - "Версия", i); - #endif - - if(i < 100) // 8.0 - { - file = cat->GetFile("metadata"); - if(!file) - { - msreg_m.AddError("Не найден каталог metadata в конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name); - delete cat; - return; - } - cat2 = file->GetCatalog(); - if(!cat2) - { - msreg_m.AddError("Файл metadata не является каталогом в конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name); - delete cat; - return; - } - - } - else cat2 = cat; // else 8.1 или 8.2 - - file = cat2->GetFile("root"); - if(!file) - { - msreg_m.AddError("Не найден файл root в конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name); - delete cat; - return; - } - - tr = file->get_tree(); - filenamemeta = (*tr)[0][1].get_value(); - delete tr; - tr = nullptr; - - file = cat2->GetFile(filenamemeta); - if(!file) - { - msreg_m.AddError("Не найден файл метаданных в конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name, - "Имя мета", filenamemeta); - delete cat; - return; - } - - #ifdef _DEBUG - msreg_m.AddDebugMessage("Найден файл метаданных в конфигурации поставщика", MessageState::Info, - "Таблица", tf->t->getname(), - "Имя файла", tf->name, - "Имя мета", filenamemeta); - #endif - - tr = file->get_tree(); - int32_t numnode = (*tr)[0][2].get_value().ToInt(); - for(i = 0; i < numnode; i++) - { - tree& node = (*tr)[0][3 + i]; - nodetype = node[0].get_value(); - if(nodetype.CompareIC(NODE_GENERAL) == 0) // узел "Общие" - { - tree& confinfo = node[1][1]; - int32_t verconfinfo = confinfo[0].get_value().ToInt(); - switch(verconfinfo) - { - case 15: - _name = confinfo[1][1][2].get_value(); - _supplier = confinfo[11].get_value(); - _version = confinfo[12].get_value(); - break; - case 22: - case 32: - case 34: - case 36: - case 37: - _name = confinfo[1][1][2].get_value(); - _supplier = confinfo[14].get_value(); - _version = confinfo[15].get_value(); - break; - default: - _name = confinfo[1][1][2].get_value(); - _supplier = confinfo[14].get_value(); - _version = confinfo[15].get_value(); - #ifdef _DEBUG - msreg_m.AddDebugMessage("Неизвестная версия свойств конфигурации поставщика", MessageState::Info, - "Таблица", tf->t->getname(), - "Имя файла", tf->name, - "Имя мета", filenamemeta, - "Версия свойств", verconfinfo); - #endif - break; - } - break; - } - } - delete tr; - tr = nullptr; - - if(i >= numnode) - { - msreg_m.AddError("Не найден узел Общие в метаданных конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name, - "Имя мета", filenamemeta); - _supplier = ""; - _version = ""; - } - #ifdef _DEBUG - else - { - msreg_m.AddDebugMessage("Найдена конфигурация поставщика", MessageState::Info, - "Таблица", tf->t->getname(), - "Имя файла", tf->name, - "Имя", _name, - "Версия", _version, - "Поставщик", _supplier); - } - #endif - - std::shared_ptr sup_conf = std::make_shared(tf, _name, _supplier, _version); - _supplier_configs.push_back(sup_conf); - - delete cat; - cat = nullptr; - } - catch(...) - { - msreg_m.AddError("Произошла ошибка при разборе конфигурации поставщика", - "Таблица", tf->t->getname(), - "Имя файла", tf->name); - delete cat; - delete s; - delete tr; - delete f; - } + auto sup_conf = SupplierConfig::create_supplier_config(table_file); + _supplier_configs.push_back(sup_conf); } //--------------------------------------------------------------------------- diff --git a/src/tool1cd/Class_1CD.h b/src/tool1cd/Class_1CD.h index c06ebad3..c8eda1a8 100755 --- a/src/tool1cd/Class_1CD.h +++ b/src/tool1cd/Class_1CD.h @@ -268,7 +268,7 @@ friend Field; void set_block_as_free(uint32_t block_number); // пометить блок как свободный uint32_t get_free_block(); // получить номер свободного блока (и пометить как занятый) - void add_supplier_config(TableFile* file); + void add_supplier_config(TableFile* table_file); bool recursive_test_stream_format(Table* t, uint32_t nrec); bool recursive_test_stream_format2(Table* t, uint32_t nrec); // для DBSCHEMA diff --git a/src/tool1cd/Constants.h b/src/tool1cd/Constants.h index 99de83d8..3f94914b 100644 --- a/src/tool1cd/Constants.h +++ b/src/tool1cd/Constants.h @@ -167,6 +167,4 @@ const String EMPTY_GUID = "00000000-0000-0000-0000-000000000000"; const BinaryGuid SNAPSHOT_VER1(std::string("3721ca9e-a272-496b-a093-206ea7629574")); const BinaryGuid SNAPSHOT_VER2(std::string("6fdfdf78-062a-46bb-8402-62145ae55764")); -const String NODE_GENERAL = "9cd510cd-abfc-11d4-9434-004095e12fc7"; - #endif diff --git a/src/tool1cd/DetailedException.cpp b/src/tool1cd/DetailedException.cpp index 0ebc0944..fe61ceeb 100644 --- a/src/tool1cd/DetailedException.cpp +++ b/src/tool1cd/DetailedException.cpp @@ -48,3 +48,8 @@ PackDirectoryDoesNotExistException::PackDirectoryDoesNotExistException(const Sys : DetailedException(message) { } + +SupplierConfigReadException::SupplierConfigReadException(const System::String &message) throw() + : DetailedException(message) +{ +} diff --git a/src/tool1cd/DetailedException.h b/src/tool1cd/DetailedException.h index 4acdbe5c..2ae19364 100644 --- a/src/tool1cd/DetailedException.h +++ b/src/tool1cd/DetailedException.h @@ -39,7 +39,13 @@ class SerializationException : public DetailedException class PackDirectoryDoesNotExistException : public DetailedException { public: - PackDirectoryDoesNotExistException(const String &message) throw(); + PackDirectoryDoesNotExistException(const String &message) throw(); +}; + +class SupplierConfigReadException : public DetailedException +{ +public: + SupplierConfigReadException(const String &message) throw(); }; #endif //TOOL1CD_PROJECT_DETAILEDEXCEPTION_H diff --git a/src/tool1cd/SupplierConfig.cpp b/src/tool1cd/SupplierConfig.cpp index e53b528f..eecf47a1 100644 --- a/src/tool1cd/SupplierConfig.cpp +++ b/src/tool1cd/SupplierConfig.cpp @@ -3,6 +3,7 @@ #include "MessageRegistration.h" #include "SupplierConfig.h" #include "ConfigStorage.h" +#include "SupplierConfigBuilder.h" #include "UZLib.h" extern Registrator msreg_g; @@ -61,3 +62,10 @@ String SupplierConfig::supplier() const { String SupplierConfig::version() const { return _version; } + + +std::shared_ptr SupplierConfig::create_supplier_config(TableFile *table_file) { + SupplierConfigBuilder builder(table_file); + + return builder.build(); +} diff --git a/src/tool1cd/SupplierConfig.h b/src/tool1cd/SupplierConfig.h index 4e1ea9a8..517e879a 100644 --- a/src/tool1cd/SupplierConfig.h +++ b/src/tool1cd/SupplierConfig.h @@ -22,6 +22,8 @@ class SupplierConfig String supplier() const; String version() const; + static std::shared_ptr create_supplier_config(TableFile* table_file); + private: TableFile* _file {nullptr}; String _name; // имя конфигурация поставщика diff --git a/src/tool1cd/SupplierConfigBuilder.cpp b/src/tool1cd/SupplierConfigBuilder.cpp new file mode 100644 index 00000000..3aa8e916 --- /dev/null +++ b/src/tool1cd/SupplierConfigBuilder.cpp @@ -0,0 +1,186 @@ +#include "SupplierConfigBuilder.h" +#include "ConfigStorage.h" +#include "System.Classes.hpp" +#include "TempStream.h" +#include "DetailedException.h" +#include "UZLib.h" + +extern Registrator msreg_g; + +String NODE_GENERAL() { + return String("9cd510cd-abfc-11d4-9434-004095e12fc7"); +} + +SupplierConfigBuilder::SupplierConfigBuilder(TableFile *table_file) + : _table_file(table_file) +{ + create_main_catalog(); +} + +std::shared_ptr SupplierConfigBuilder::build() { + String _name; // имя конфигурация поставщика + String _supplier; // синоним конфигурация поставщика + String _version; // версия конфигурация поставщика + + V8File* root_file = get_file("root"); + if(!root_file) { + throw SupplierConfigReadException("Не найден файл root в конфигурации поставщика") + .add_detail("Таблица", _table_file->t->getname()) + .add_detail("Имя файла", _table_file->name); + } + + String file_name_meta; + { + std::unique_ptr root_tree ( root_file->get_tree() ); + file_name_meta = (*root_tree)[0][1].get_value(); + } + + V8File* meta_file = get_file(file_name_meta); + if(!meta_file) { + throw SupplierConfigReadException("Не найден файл метаданных в конфигурации поставщика") + .add_detail("Таблица", _table_file->t->getname()) + .add_detail("Имя файла", _table_file->name) + .add_detail("Имя мета", file_name_meta); + } + + #ifdef _DEBUG + msreg_g.AddDebugMessage("Найден файл метаданных в конфигурации поставщика", MessageState::Info, + "Таблица", _table_file->t->getname(), + "Имя файла", _table_file->name, + "Имя мета", file_name_meta); + #endif + + std::unique_ptr meta_tree ( meta_file->get_tree() ); + int32_t numnode = (*meta_tree)[0][2].get_value().ToInt(); + int32_t current_node_number = 0; + for(current_node_number = 0; current_node_number < numnode; current_node_number++) { + tree& node = (*meta_tree)[0][3 + current_node_number]; + String nodetype = node[0].get_value(); + if(nodetype.CompareIC(NODE_GENERAL()) == 0) { // узел "Общие" + tree& confinfo = node[1][1]; + int32_t verconfinfo = confinfo[0].get_value().ToInt(); + switch(verconfinfo) { + case 15: + _name = confinfo[1][1][2].get_value(); + _supplier = confinfo[11].get_value(); + _version = confinfo[12].get_value(); + break; + case 22: + case 32: + case 34: + case 36: + case 37: + _name = confinfo[1][1][2].get_value(); + _supplier = confinfo[14].get_value(); + _version = confinfo[15].get_value(); + break; + default: + _name = confinfo[1][1][2].get_value(); + _supplier = confinfo[14].get_value(); + _version = confinfo[15].get_value(); + #ifdef _DEBUG + msreg_g.AddDebugMessage("Неизвестная версия свойств конфигурации поставщика", MessageState::Info, + "Таблица", _table_file->t->getname(), + "Имя файла", _table_file->name, + "Имя мета", file_name_meta, + "Версия свойств", verconfinfo); + #endif + break; + } + break; + } + } + + if(current_node_number >= numnode) { + msreg_g.AddError("Не найден узел Общие в метаданных конфигурации поставщика", // TODO: критичная ошибка? Обработка на месте? + "Таблица", _table_file->t->getname(), + "Имя файла", _table_file->name, + "Имя мета", file_name_meta); + _supplier = ""; + _version = ""; + } + #ifdef _DEBUG + else { + msreg_g.AddDebugMessage("Найдена конфигурация поставщика", MessageState::Info, + "Таблица", _table_file->t->getname(), + "Имя файла", _table_file->name, + "Имя", _name, + "Версия", _version, + "Поставщик", _supplier); + } + #endif + + std::shared_ptr sup_conf( new SupplierConfig(_table_file, _name, _supplier, _version) ); + + return sup_conf; +} + +void SupplierConfigBuilder::create_main_catalog() { + std::unique_ptr container_file( new ContainerFile(_table_file, _table_file->name) ); + if(!container_file->open()) { + throw SupplierConfigReadException("Ошибка открытия конейнера файлов") + .add_detail("Имя", container_file->name); + } + + std::unique_ptr out_stream( new TTempStream ); + + try { + ZInflateStream(container_file->stream, out_stream.get()); + } + catch(ZError) { + throw SupplierConfigReadException("Ошибка распаковки конфигурации поставщика") + .add_detail("Таблица", _table_file->t->getname()) + .add_detail("Имя", _table_file->name); + } + + container_file->close(); + + main_catalog.reset( new V8Catalog(out_stream.get(), true) ); +} + +int32_t SupplierConfigBuilder::get_version() const { + V8File* version_file = main_catalog->GetFile("version"); + if(!version_file) { + throw SupplierConfigReadException("Не найден файл version в конфигурации поставщика") + .add_detail("Таблица", _table_file->t->getname()) + .add_detail("Имя файла", _table_file->name); + } + + std::unique_ptr version_tree ( version_file->get_tree() ); + int32_t result = (*version_tree)[0][0][0].get_value().ToInt();; + +#ifdef _DEBUG +msreg_g.AddDebugMessage("Найдена версия контейнера конфигурации поставщика", MessageState::Info, + "Таблица", _table_file->t->getname(), + "Имя файла", _table_file->name, + "Версия", result); +#endif + + return result; +} + +V8File* SupplierConfigBuilder::get_file(const String &file_name) const { + V8File* result = nullptr; + + if(get_version() < 100) { // 8.0 + V8File* metadata_file = main_catalog->GetFile("metadata"); + if(metadata_file == nullptr) { + throw SupplierConfigReadException("Не найден каталог metadata в конфигурации поставщика") + .add_detail("Таблица", _table_file->t->getname()) + .add_detail("Имя файла", _table_file->name); + } + + V8Catalog* cat2 = metadata_file->GetCatalog(); + if(cat2 == nullptr) { + throw SupplierConfigReadException("Файл metadata не является каталогом в конфигурации поставщика") + .add_detail("Таблица", _table_file->t->getname()) + .add_detail("Имя файла", _table_file->name); + } + + result = cat2->GetFile(file_name); + } else { + result = main_catalog->GetFile(file_name); // else 8.1 или 8.2 + } + + return result; +} diff --git a/src/tool1cd/SupplierConfigBuilder.h b/src/tool1cd/SupplierConfigBuilder.h new file mode 100644 index 00000000..00d4300d --- /dev/null +++ b/src/tool1cd/SupplierConfigBuilder.h @@ -0,0 +1,32 @@ +#ifndef SUPPLIERCONFIGBUILDER_H +#define SUPPLIERCONFIGBUILDER_H + +#include + +#include "SupplierConfig.h" +#include "TableFiles.h" +#include "cfapi/V8Catalog.h" + + +class SupplierConfigBuilder +{ +public: + SupplierConfigBuilder() = delete; + explicit SupplierConfigBuilder(TableFile *table_file); + + ~SupplierConfigBuilder() = default; + + std::shared_ptr build(); + +private: + TableFile *_table_file {nullptr}; + std::unique_ptr main_catalog; + + void create_main_catalog(); + int32_t get_version() const; + V8File* get_file(const String& file_name) const; + + +}; + +#endif // SUPPLIERCONFIGBUILDER_H