Skip to content

Commit

Permalink
dbcopy: find column description on each export
Browse files Browse the repository at this point in the history
  • Loading branch information
franku committed Jan 31, 2020
1 parent 3ec99c5 commit 980275e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 29 deletions.
2 changes: 1 addition & 1 deletion core/src/dird/dbcopy/database_export.h
Expand Up @@ -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;
Expand Down
57 changes: 38 additions & 19 deletions core/src/dird/dbcopy/database_export_postgresql.cc
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion core/src/dird/dbcopy/database_export_postgresql.h
Expand Up @@ -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;
Expand Down
46 changes: 38 additions & 8 deletions core/src/dird/dbcopy/database_table_descriptions.cc
Expand Up @@ -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<ColumnDescription>& 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> DatabaseTableDescriptions::Create(
Expand Down
4 changes: 4 additions & 0 deletions core/src/dird/dbcopy/database_table_descriptions.h
Expand Up @@ -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:
Expand Down

0 comments on commit 980275e

Please sign in to comment.