From be0064f730cd0eab0bf28e356776cafc60265aa6 Mon Sep 17 00:00:00 2001 From: eelke Date: Sat, 17 Nov 2018 09:47:50 +0100 Subject: [PATCH] The codegen now can properly lookup array types. Array type lookup failed previously because the typemapping class was not yet receiving the list of types from the database. Fix was to pass this data --- pglab/CodeGenerator.cpp | 6 ++++-- pglab/CodeGenerator.h | 5 ++++- pglab/MainWindow.cpp | 2 +- pglablib/codebuilder/DefaultConfigs.cpp | 19 +++++++++++-------- pglablib/codebuilder/DefaultConfigs.h | 3 ++- pglablib/codebuilder/TypeMappings.cpp | 13 +++++++++---- pglablib/codebuilder/TypeMappings.h | 4 ++-- tests/pglabtests/tst_TypeMappings.cpp | 2 +- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/pglab/CodeGenerator.cpp b/pglab/CodeGenerator.cpp index 0cf97aa..227487e 100644 --- a/pglab/CodeGenerator.cpp +++ b/pglab/CodeGenerator.cpp @@ -20,8 +20,10 @@ CodeGenerator::~CodeGenerator() delete ui; } -void CodeGenerator::Init(QString query, std::shared_ptr dbres) +void CodeGenerator::Init(std::shared_ptr catalog, QString query, + std::shared_ptr dbres) { + m_catalog = catalog; m_query = query; m_dbres = dbres; generateCode(); @@ -42,7 +44,7 @@ void CodeGenerator::generateCode() QString buffer; QTextStream stream(&buffer); CodeBuilder builder; - builder.setLanguageConfig(getPglabCppLanguageConfig()); + builder.setLanguageConfig(getPglabCppLanguageConfig(m_catalog)); builder.GenCodeForExecutingQuery(stream, m_query, *m_dbres, struct_name); stream.flush(); ui->generatedCodeEditor->setPlainText(buffer); diff --git a/pglab/CodeGenerator.h b/pglab/CodeGenerator.h index c2dfac9..fb09c88 100644 --- a/pglab/CodeGenerator.h +++ b/pglab/CodeGenerator.h @@ -9,6 +9,8 @@ namespace Ui { class CodeGenerator; } +class PgDatabaseCatalog; + class CodeGenerator : public PlgPage { Q_OBJECT @@ -17,13 +19,14 @@ public: explicit CodeGenerator(QWidget *parent = nullptr); ~CodeGenerator(); - void Init(QString query, std::shared_ptr dbres); + void Init(std::shared_ptr catalog, QString query, std::shared_ptr dbres); private slots: void on_updateCodeButton_clicked(); private: Ui::CodeGenerator *ui; + std::shared_ptr m_catalog; QString m_query; std::shared_ptr m_dbres; diff --git a/pglab/MainWindow.cpp b/pglab/MainWindow.cpp index 064649f..e23745e 100644 --- a/pglab/MainWindow.cpp +++ b/pglab/MainWindow.cpp @@ -62,7 +62,7 @@ void MainWindow::newCrudPage(const PgClass &table) void MainWindow::newCodeGenPage(QString query, std::shared_ptr dbres) { auto cgtab = new CodeGenerator(this); - cgtab->Init(query, dbres); + cgtab->Init(m_database->catalogue(), query, dbres); addPage(cgtab, "Codegen"); } diff --git a/pglablib/codebuilder/DefaultConfigs.cpp b/pglablib/codebuilder/DefaultConfigs.cpp index 227ca22..4806aec 100644 --- a/pglablib/codebuilder/DefaultConfigs.cpp +++ b/pglablib/codebuilder/DefaultConfigs.cpp @@ -6,13 +6,16 @@ #include "StructureTemplate.h" #include "TypeMappings.h" #include "Pgsql_oids.h" +#include "PgDatabaseCatalog.h" using namespace Pgsql; -std::shared_ptr GetPglabCppTypeMappings() +class PgTypeContainer; + +std::shared_ptr GetPglabCppTypeMappings(std::shared_ptr types) { - auto tm = std::make_shared(); - *tm = { + auto tm = std::make_shared(types, std::initializer_list + { { bool_oid, "bool" }, { char_oid, "char" }, { name_oid, "std::string" }, @@ -23,7 +26,7 @@ std::shared_ptr GetPglabCppTypeMappings() { oid_oid, "Oid" }, { float4_oid, "float" }, { float8_oid, "double" } - }; + }); tm->setDefaultStringType("std::string"); tm->setDefaultContainerType("std::vector<%1>"); return tm; @@ -66,10 +69,10 @@ for (auto row: result) { } -std::shared_ptr buildPglabCppLanguageConfig() +std::shared_ptr buildPglabCppLanguageConfig(std::shared_ptr catalog) { auto config = std::make_shared(); - config->setTypeMappings(GetPglabCppTypeMappings()); + config->setTypeMappings(GetPglabCppTypeMappings(catalog->types())); config->setNameManglingRules(std::make_shared()); config->setStructureTemplate(buildPglabStructureTemplate()); config->setIndentationConfig(std::make_shared()); @@ -78,9 +81,9 @@ std::shared_ptr buildPglabCppLanguageConfig() } -std::shared_ptr getPglabCppLanguageConfig() +std::shared_ptr getPglabCppLanguageConfig(std::shared_ptr catalog) { - static auto config = buildPglabCppLanguageConfig(); + static auto config = buildPglabCppLanguageConfig(catalog); return config; } diff --git a/pglablib/codebuilder/DefaultConfigs.h b/pglablib/codebuilder/DefaultConfigs.h index bb04da9..c8fb0a5 100644 --- a/pglablib/codebuilder/DefaultConfigs.h +++ b/pglablib/codebuilder/DefaultConfigs.h @@ -4,8 +4,9 @@ #include class LanguageConfig; +class PgDatabaseCatalog; //std::shared_ptr getDefaultCppLanguageConfig(); -std::shared_ptr getPglabCppLanguageConfig(); +std::shared_ptr getPglabCppLanguageConfig(std::shared_ptr catalog); #endif // DEFAULTCONFIGS_H diff --git a/pglablib/codebuilder/TypeMappings.cpp b/pglablib/codebuilder/TypeMappings.cpp index b90a9e4..44fc40a 100644 --- a/pglablib/codebuilder/TypeMappings.cpp +++ b/pglablib/codebuilder/TypeMappings.cpp @@ -10,17 +10,18 @@ // }; //} -TypeMappings::TypeMappings() = default; +TypeMappings::TypeMappings(std::shared_ptr types) + : m_types(types) +{} -TypeMappings::TypeMappings(std::initializer_list mappings) +TypeMappings::TypeMappings(std::shared_ptr types, std::initializer_list mappings) + : TypeMappings(types) { m_typeMap.insert(mappings.begin(), mappings.end()); } QString TypeMappings::getTypeForOid(Oid oid) const { - // TODO use the catalog to determine if someting is an array or vector type. - // If it is lookup its element type and use the std container auto res = m_typeMap.find(oid); if (res != m_typeMap.end()) { return res->second; @@ -28,7 +29,11 @@ QString TypeMappings::getTypeForOid(Oid oid) const if (m_types) { PgType type = m_types->getByKey(oid); + // Found a valid type? elem is set? then it is array type if (type.oid != InvalidOid && type.elem != InvalidOid) { + // Lookup what the element type is and wrap the mapping for that in the standard container type + // for the language config. If that isn't right the end user should create a specific mapping for + // that array type. res = m_typeMap.find(type.elem); QString type_string; if (res == m_typeMap.end()) { diff --git a/pglablib/codebuilder/TypeMappings.h b/pglablib/codebuilder/TypeMappings.h index 38e0c74..e5de106 100644 --- a/pglablib/codebuilder/TypeMappings.h +++ b/pglablib/codebuilder/TypeMappings.h @@ -13,9 +13,9 @@ public: using TypeMap = std::unordered_map; using Mapping = std::pair; - TypeMappings(); + TypeMappings(std::shared_ptr types = nullptr); - TypeMappings(std::initializer_list mappings); + TypeMappings(std::shared_ptr types, std::initializer_list mappings); QString getTypeForOid(Oid oid) const; diff --git a/tests/pglabtests/tst_TypeMappings.cpp b/tests/pglabtests/tst_TypeMappings.cpp index 505778f..4f7a372 100644 --- a/tests/pglabtests/tst_TypeMappings.cpp +++ b/tests/pglabtests/tst_TypeMappings.cpp @@ -18,7 +18,7 @@ protected: def_str_type = "std::string"; int4str = "int"; int8str = "long long"; - tm = TypeMappings( { + tm = TypeMappings(nullptr, { { Pgsql::int4_oid, int4str }, { Pgsql::int8_oid, int8str } });