From 980275e6724cb091263430fc9f1251f4e6376700 Mon Sep 17 00:00:00 2001 From: Frank Ueberschar Date: Wed, 29 Jan 2020 14:58:32 +0100 Subject: [PATCH] dbcopy: find column description on each export --- core/src/dird/dbcopy/database_export.h | 2 +- .../dird/dbcopy/database_export_postgresql.cc | 57 ++++++++++++------- .../dird/dbcopy/database_export_postgresql.h | 2 +- .../dbcopy/database_table_descriptions.cc | 46 ++++++++++++--- .../dird/dbcopy/database_table_descriptions.h | 4 ++ 5 files changed, 82 insertions(+), 29 deletions(-) diff --git a/core/src/dird/dbcopy/database_export.h b/core/src/dird/dbcopy/database_export.h index 16200d718f3..73b69d27e86 100644 --- a/core/src/dird/dbcopy/database_export.h +++ b/core/src/dird/dbcopy/database_export.h @@ -44,7 +44,7 @@ class DatabaseExport { virtual void EndTable() = 0; virtual void CopyStart() = 0; - virtual void CopyRow(const RowData& data) = 0; + virtual void CopyRow(RowData& origin_data) = 0; virtual void CopyEnd() = 0; virtual void CompareRow(const RowData& data) = 0; diff --git a/core/src/dird/dbcopy/database_export_postgresql.cc b/core/src/dird/dbcopy/database_export_postgresql.cc index 66dea35775b..ff3f79866a8 100644 --- a/core/src/dird/dbcopy/database_export_postgresql.cc +++ b/core/src/dird/dbcopy/database_export_postgresql.cc @@ -59,32 +59,51 @@ DatabaseExportPostgresql::~DatabaseExportPostgresql() if (transaction_) { db_->SqlQuery("ROLLBACK"); } } -void DatabaseExportPostgresql::CopyRow(const RowData& data) +void DatabaseExportPostgresql::CopyRow(RowData& origin_data) { - std::string query{"INSERT INTO "}; - query += data.table_name; - query += " ("; - for (const auto& c : data.column_descriptions) { - query += c->column_name; - query += ", "; - } - query.resize(query.size() - 2); - query += ")"; + std::string query_into{"INSERT INTO "}; + query_into += origin_data.table_name; + query_into += " ("; - query += " VALUES ("; + std::string query_values = " VALUES ("; - for (const auto& r : data.row) { - query += "'"; - query += r.data_pointer; - query += "',"; + for (std::size_t i = 0; i < origin_data.column_descriptions.size(); i++) { + query_into += origin_data.column_descriptions[i]->column_name; + query_into += ", "; + + const ColumnDescription* column_description = + table_descriptions_->GetColumnDescription( + origin_data.table_name, + origin_data.column_descriptions[i]->column_name); + + if (!column_description) { + std::string err{"Could not get column description for: "}; + err += origin_data.column_descriptions[i]->column_name; + throw std::runtime_error(err); + } + + if (i < origin_data.row.size()) { + query_values += "'"; + column_description->db_export_converter(origin_data.row[i]); + query_values += origin_data.row[i].data_pointer; + query_values += "',"; + } else { + throw std::runtime_error("Row number does not match column description"); + } } - query.resize(query.size() - 1); - query += ")"; + query_values.resize(query_values.size() - 1); + query_values += ")"; + + query_into.resize(query_into.size() - 2); + query_into += ")"; + + query_into += query_values; + #if 0 - std::cout << query << std::endl; + std::cout << query_into << std::endl; #else - if (!db_->SqlQuery(query.c_str())) { + if (!db_->SqlQuery(query_into.c_str())) { std::string err{"DatabaseExportPostgresql: Could not execute query: "}; err += db_->get_errmsg(); throw std::runtime_error(err); diff --git a/core/src/dird/dbcopy/database_export_postgresql.h b/core/src/dird/dbcopy/database_export_postgresql.h index 65a6c10f9ea..a82f54b6352 100644 --- a/core/src/dird/dbcopy/database_export_postgresql.h +++ b/core/src/dird/dbcopy/database_export_postgresql.h @@ -35,7 +35,7 @@ class DatabaseExportPostgresql : public DatabaseExport { void EndTable() override; void CopyStart() override; - void CopyRow(const RowData& data) override; + void CopyRow(RowData& origin_data) override; void CopyEnd() override; virtual void CompareRow(const RowData& data) override; diff --git a/core/src/dird/dbcopy/database_table_descriptions.cc b/core/src/dird/dbcopy/database_table_descriptions.cc index f0071321f07..cc439b3384f 100644 --- a/core/src/dird/dbcopy/database_table_descriptions.cc +++ b/core/src/dird/dbcopy/database_table_descriptions.cc @@ -87,20 +87,50 @@ DatabaseTablesMysql::DatabaseTablesMysql(BareosDb* db) } } +static void ToLowerCase(const std::string& i1, + const std::string& i2, + std::string& o1, + std::string& o2) +{ + o1.clear(); + o2.clear(); + std::transform(i1.cbegin(), i1.cend(), std::back_inserter(o1), ::tolower); + std::transform(i2.cbegin(), i2.cend(), std::back_inserter(o2), ::tolower); +} + const DatabaseTableDescriptions::TableDescription* DatabaseTableDescriptions::GetTableDescription( const std::string& table_name) const { - auto tr = std::find_if( - tables.begin(), tables.end(), [&table_name](const TableDescription& t) { + auto tr = std::find_if(tables.begin(), tables.end(), + [&table_name](const TableDescription& t) { + std::string l1, l2; + ToLowerCase(table_name, t.table_name, l1, l2); + return l1 == l2; + }); + return tr == tables.end() ? nullptr : std::addressof(*tr); +} + +const ColumnDescription* DatabaseTableDescriptions::GetColumnDescription( + const std::string& table_name, + const std::string& column_name) const +{ + const DatabaseTableDescriptions::TableDescription* table = + GetTableDescription(table_name); + if (table == nullptr) { + std::cout << "Could not get table description for table: " << table_name + << std::endl; + return nullptr; + } + auto c = std::find_if( + table->column_descriptions.cbegin(), table->column_descriptions.cend(), + [&column_name](const std::unique_ptr& c) { std::string l1, l2; - std::transform(table_name.cbegin(), table_name.cend(), - std::back_inserter(l1), ::tolower); - std::transform(t.table_name.cbegin(), t.table_name.cend(), - std::back_inserter(l2), ::tolower); - return l1 == l2; + ToLowerCase(column_name, c->column_name, l1, l2); + if (l1 == l2) { return true; } + return false; }); - return tr == tables.end() ? nullptr : std::addressof(*tr); + return (c == table->column_descriptions.cend()) ? nullptr : c->get(); } std::unique_ptr DatabaseTableDescriptions::Create( diff --git a/core/src/dird/dbcopy/database_table_descriptions.h b/core/src/dird/dbcopy/database_table_descriptions.h index 03a5bcd70d8..a6c56734754 100644 --- a/core/src/dird/dbcopy/database_table_descriptions.h +++ b/core/src/dird/dbcopy/database_table_descriptions.h @@ -54,6 +54,10 @@ class DatabaseTableDescriptions { const TableDescription* GetTableDescription( const std::string& table_name) const; + const ColumnDescription* GetColumnDescription( + const std::string& table_name, + const std::string& column_name) const; + virtual ~DatabaseTableDescriptions() = default; protected: