Skip to content

Commit

Permalink
add name mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
wsekta committed Jan 11, 2024
1 parent a8bc911 commit 41a8e8c
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 6 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ struct ObjectModel
// other way to define id column - will be over writen by using id_columns
// int id;

// defining table_name is optional
// defining table_name is optional, adding it will overwrite default table name
inline static const std::string table_name = "object_model";

// defining columns_names is optional, adding it will overwrite default columns names
// not all columns have to be defined, others will get default names
inline static const std::map<std::string, std::string> columns_names = {{"field1", "some_field1_name"},
{"field2", "some_field2_name"}};
};

int main()
Expand Down
7 changes: 6 additions & 1 deletion examples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ struct ObjectModel
// other way to define id column - will be over writen by using id_columns
// int id;

// defining table_name is optional
// defining table_name is optional, adding it will overwrite default table name
inline static const std::string table_name = "object_model";

// defining columns_names is optional, adding it will overwrite default columns names
// not all columns have to be defined, others will get default names
inline static const std::map<std::string, std::string> columns_names = {{"field1", "some_field1_name"},
{"field2", "some_field2_name"}};
};

int main()
Expand Down
5 changes: 3 additions & 2 deletions include/orm-cxx/model/ColumnInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <vector>

#include "ColumnType.hpp"
#include "NameMapping.hpp"

namespace orm::model
{
Expand All @@ -31,13 +32,13 @@ auto getColumnsInfo(const std::unordered_set<std::string>& ids = {}) -> std::vec
{
ColumnInfo columnInfo{};

columnInfo.name = field.name();
columnInfo.name = getColumnName<T>(field.name());

auto [type, isNotNull] = toColumnType(field.type());
columnInfo.type = type;
columnInfo.isNotNull = isNotNull;

if (ids.contains(field.name()))
if (ids.contains(columnInfo.name))
{
columnInfo.isPrimaryKey = true;
}
Expand Down
13 changes: 11 additions & 2 deletions include/orm-cxx/model/IdInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,27 @@
#include <string>
#include <unordered_set>

#include "NameMapping.hpp"

namespace orm::model
{
template <typename T>
auto getIdColumnsNames() -> std::unordered_set<std::string>
{
if constexpr (requires { T::id_columns; })
{
return {T::id_columns.begin(), T::id_columns.end()};
std::unordered_set<std::string> ids{};

for (const auto& id : T::id_columns)
{
ids.insert(getColumnName<T>(id));
}

return ids;
}
else if constexpr (requires(T t) { t.id; })
{
return {"id"};
return {getColumnName<T>("id")};
}
else
{
Expand Down
37 changes: 37 additions & 0 deletions include/orm-cxx/model/NameMapping.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <string>
#include <unordered_map>

namespace orm::model
{
template <typename T>
auto getColumnsNamesMapping() -> std::unordered_map<std::string, std::string>
{
if constexpr (requires {
T::columns_names;
T::columns_names.contains(std::string{});
T::columns_names.at(std::string{});
})
{
return {T::columns_names.begin(), T::columns_names.end()};
}
else
{
return {};
}
}

template <typename T>
auto getColumnName(const std::string& name) -> const std::string&
{
static auto mapping = getColumnsNamesMapping<T>();

if (mapping.contains(name))
{
return mapping.at(name);
}

return name;
}
}
27 changes: 27 additions & 0 deletions tests/DatabaseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ struct ModelWithOverwrittenId
inline static const std::vector<std::string> id_columns = {"field1", "field2"};
};

struct ModelWithIdAndNamesMapping
{
int id;
int field1;
std::string field2;

inline static const std::map<std::string, std::string> columns_names = {
{"field1", "some_field1_name"}, {"field2", "some_field2_name"}, {"id", "some_id_name"}};
};

template <typename T>
auto generateSomeDataModels(int count) -> std::vector<T>
Expand Down Expand Up @@ -204,3 +213,21 @@ TEST_F(DatabaseTest, shouldCreateTableWithOverwrittenIdColumn)

database.deleteTable<ModelWithOverwrittenId>();
}

TEST_F(DatabaseTest, shouldExecuteInsertQueryAndSelectQueryWithNamesMapping_valuesShouldBeSame)
{
database.connect(connectionString);
database.createTable<ModelWithIdAndNamesMapping>();
auto models = std::vector<ModelWithIdAndNamesMapping>{{1, 1, "test"}, {2, 2, "test2"}};
database.insertObjects(models);
orm::Query<ModelWithIdAndNamesMapping> queryForNamesMapping;
auto returnedModels = database.executeQuery(queryForNamesMapping);

for (std::size_t i = 0; i < models.size(); i++)
{
EXPECT_EQ(models[i].field1, returnedModels[i].field1);
EXPECT_EQ(models[i].field2, returnedModels[i].field2);
}

database.deleteTable<ModelWithIdAndNamesMapping>();
}
43 changes: 43 additions & 0 deletions tests/ModelTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,25 @@ struct StructWithIdColumns
int field2;
};

struct StructWithNamesMapping
{
int field1;
int field2;

inline static const std::map<std::string, std::string> columns_names = {{"field1", "some_field1_name"},
{"field2", "some_field2_name"}};
};

struct StructWithIdAndNamesMapping
{
int id;
int field1;
int field2;

inline static const std::map<std::string, std::string> columns_names = {
{"field1", "some_field1_name"}, {"field2", "some_field2_name"}, {"id", "some_id_name"}};
};

TEST(ModelTest, OneFieldStruct_shouldHaveOneColumn)
{
orm::Model<OneFieldStruct> model;
Expand Down Expand Up @@ -102,4 +121,28 @@ TEST(ModelTest, StructWithIdColumns_shouldHaveTwoIdColumns)
EXPECT_EQ(model.getModelInfo().columnsInfo[3].isPrimaryKey, false);
EXPECT_TRUE(model.getModelInfo().idColumnsNames.contains("id1"));
EXPECT_TRUE(model.getModelInfo().idColumnsNames.contains("id2"));
}

TEST(ModelTest, StructWithNamesMapping_shouldHaveTwoColumnsWithNamesFromMapping)
{
orm::Model<StructWithNamesMapping> model;

EXPECT_EQ(model.getModelInfo().columnsInfo.size(), 2);
EXPECT_EQ(model.getModelInfo().columnsInfo[0].name, "some_field1_name");
EXPECT_EQ(model.getModelInfo().columnsInfo[1].name, "some_field2_name");
EXPECT_TRUE(model.getModelInfo().idColumnsNames.empty());
}

TEST(ModelTest, StructWithIdAndNamesMapping_shouldHaveTwoColumnsWithNamesFromMappingAndOneIdColumn)
{
orm::Model<StructWithIdAndNamesMapping> model;

EXPECT_EQ(model.getModelInfo().columnsInfo.size(), 3);
EXPECT_EQ(model.getModelInfo().columnsInfo[0].name, "some_id_name");
EXPECT_EQ(model.getModelInfo().columnsInfo[0].isPrimaryKey, true);
EXPECT_EQ(model.getModelInfo().columnsInfo[1].name, "some_field1_name");
EXPECT_EQ(model.getModelInfo().columnsInfo[1].isPrimaryKey, false);
EXPECT_EQ(model.getModelInfo().columnsInfo[2].name, "some_field2_name");
EXPECT_EQ(model.getModelInfo().columnsInfo[2].isPrimaryKey, false);
EXPECT_TRUE(model.getModelInfo().idColumnsNames.contains("some_id_name"));
}

0 comments on commit 41a8e8c

Please sign in to comment.