Skip to content

Commit

Permalink
Merge pull request #133 from Jacyking/master
Browse files Browse the repository at this point in the history
support for enum
  • Loading branch information
Jacyking authored Dec 15, 2023
2 parents 530ce35 + 9e4ec7c commit f2e6568
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 42 deletions.
117 changes: 82 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,47 +91,94 @@ REFLECTION(student, code, name, sex, age, dm, classroom)
using namespace ormpp;

struct person {
int id;
std::string name;
std::optional<int> age; // 可以插入null值
std::string name;
int id;
};
REGISTER_AUTO_KEY(person, id)
REGISTER_CONFLICT_KEY(person, name)
// REGISTER_CONFLICT_KEY(person, name, age)
REFLECTION(person, id, name, age)
// REFLECTION_WITH_NAME(person, "CUSTOM_TABLE_NAME", id, name, age)
// REFLECTION_ALIAS(person, "CUSTOM_TABLE_NAME",
// FLDALIAS(&person::id, "person_id"),
// FLDALIAS(&person::name, "person_name"),
// FLDALIAS(&person::age, "person_age"));

int main() {
person p = {"test1", 2};
person p1 = {"test2", 3};
person p2 = {"test3", 4};
std::vector<person> v{p1, p2};

dbng<mysql> mysql;
mysql.connect("127.0.0.1", "dbuser", "yourpwd", "testdb");
mysql.create_datatable<person>(ormpp_auto_key{"id"});

mysql.insert(p);
mysql.insert(v);
auto id1 = mysql.get_insert_id_after_insert<person>(p);
auto id2 = mysql.get_insert_id_after_insert<person>(v);

mysql.update(p);
mysql.update(v);
mysql.update(p, "id=1");

mysql.replace(p);
mysql.replace(v);

auto result = mysql.query<person>(); // vector<person>
for (auto &person : result) {
std::cout << person.id << " " << person.name << " " << person.age
<< std::endl;
}

mysql.delete_records<person>();

// transaction
mysql.begin();
for (int i = 0; i < 10; ++i) {
person s = {"tom", 19};
if (!mysql.insert(s)) {
mysql.rollback();
return -1;
}
}
mysql.commit();
return 0;
}
```
int main()
{
person p = {1, "test1", 2};
person p1 = {2, "test2", 3};
person p2 = {3, "test3", 4};
std::vector<person> v{p1, p2};
```C++
enum class Color { BLUE = 10, RED = 15 };
enum Fruit { APPLE, BANANA };
dbng<mysql> mysql;
mysql.connect("127.0.0.1", "dbuser", "yourpwd", "testdb");
mysql.create_datatable<person>();

mysql.insert(p);
mysql.insert(v);

mysql.update(p);
mysql.update(v);

auto result = mysql.query<person>(); //vector<person>
for(auto& person : result){
std::cout<<person.id<<" "<<person.name<<" "<<person.age<<std::endl;
}

mysql.delete_records<person>();

//transaction
mysql.begin();
for (int i = 0; i < 10; ++i) {
person s = {i, "tom", 19};
if(!mysql.insert(s)){
mysql.rollback();
return -1;
}
}
mysql.commit();
struct test_enum_t {
Color color;
Fruit fruit;
int id;
};
REGISTER_AUTO_KEY(test_enum_t, id)
REFLECTION(test_enum_t, id, color, fruit)
int main() {
dbng<sqlite> sqlite;
sqlite.connect(db);
sqlite.execute("drop table if exists test_enum_t");
sqlite.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
sqlite.insert<test_enum_t>({Color::BLUE});
auto vec1 = sqlite.query<test_enum_t>();
vec1.front().color = Color::RED;
sqlite.update(vec1.front());
auto vec2 = sqlite.query<test_enum_t>();
sqlite.update<test_enum_t>({Color::BLUE, BANANA, 1}, "id=1");
auto vec3 = sqlite.query<test_enum_t>();
vec3.front().color = Color::RED;
sqlite.replace(vec3.front());
auto vec4 = sqlite.query<test_enum_t>();
sqlite.delete_records<test_enum_t>();
auto vec5 = sqlite.query<test_enum_t>();
return 0;
}
```

Expand Down
8 changes: 8 additions & 0 deletions include/mysql.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ class mysql {
param.buffer_type = MYSQL_TYPE_NULL;
}
}
else if constexpr (std::is_enum_v<U>) {
param.buffer_type = MYSQL_TYPE_LONG;
param.buffer = const_cast<void *>(static_cast<const void *>(&value));
}
else if constexpr (std::is_arithmetic_v<U>) {
param.buffer_type =
(enum_field_types)ormpp_mysql::type_to_id(identity<U>{});
Expand Down Expand Up @@ -205,6 +209,10 @@ class mysql {
if constexpr (is_optional_v<U>::value) {
return set_param_bind(param_bind, *value, i, mp, is_null);
}
else if constexpr (std::is_enum_v<U>) {
param_bind.buffer_type = MYSQL_TYPE_LONG;
param_bind.buffer = const_cast<void *>(static_cast<const void *>(&value));
}
else if constexpr (std::is_arithmetic_v<U>) {
param_bind.buffer_type =
(enum_field_types)ormpp_mysql::type_to_id(identity<U>{});
Expand Down
8 changes: 8 additions & 0 deletions include/postgresql.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,11 @@ class postgresql {
param_values.push_back({});
}
}
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
std::vector<char> temp(20, 0);
itoa_fwd(static_cast<int>(value), temp.data());
param_values.push_back(std::move(temp));
}
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
std::vector<char> temp(20, 0);
itoa_fwd(value, temp.data());
Expand Down Expand Up @@ -563,6 +568,9 @@ class postgresql {
assign(item, row, i);
value = std::move(item);
}
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
value = static_cast<U>(std::atoi(PQgetvalue(res_, row, i)));
}
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
value = std::atoi(PQgetvalue(res_, row, i));
}
Expand Down
12 changes: 8 additions & 4 deletions include/sqlite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,10 @@ class sqlite {
}
return SQLITE_OK == sqlite3_bind_null(stmt_, i);
}
else if constexpr (std::is_integral_v<U> &&
!iguana::is_int64_v<U>) { // double, int64
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
return SQLITE_OK == sqlite3_bind_int(stmt_, i, static_cast<int>(value));
}
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
return SQLITE_OK == sqlite3_bind_int(stmt_, i, value);
}
else if constexpr (iguana::is_int64_v<U>) {
Expand Down Expand Up @@ -468,8 +470,10 @@ class sqlite {
assign(item, i);
value = std::move(item);
}
else if constexpr (std::is_integral_v<U> &&
!iguana::is_int64_v<U>) { // double, int64
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
value = static_cast<U>(sqlite3_column_int(stmt_, i));
}
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
if constexpr (std::is_same_v<U, char>) {
value = (char)sqlite3_column_int(stmt_, i);
}
Expand Down
15 changes: 12 additions & 3 deletions include/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ inline constexpr auto get_type_names(DBType type) {
}
#ifdef ORMPP_ENABLE_MYSQL
else if (type == DBType::mysql) {
if constexpr (is_optional_v<U>::value) {
if constexpr (std::is_enum_v<U>) {
s = "INTEGER"sv;
}
else if constexpr (is_optional_v<U>::value) {
s = ormpp_mysql::type_to_name(identity<typename U::value_type>{});
}
else {
Expand All @@ -150,7 +153,10 @@ inline constexpr auto get_type_names(DBType type) {
#endif
#ifdef ORMPP_ENABLE_SQLITE3
else if (type == DBType::sqlite) {
if constexpr (is_optional_v<U>::value) {
if constexpr (std::is_enum_v<U>) {
s = "INTEGER"sv;
}
else if constexpr (is_optional_v<U>::value) {
s = ormpp_sqlite::type_to_name(identity<typename U::value_type>{});
}
else {
Expand All @@ -160,7 +166,10 @@ inline constexpr auto get_type_names(DBType type) {
#endif
#ifdef ORMPP_ENABLE_PG
else if (type == DBType::postgresql) {
if constexpr (is_optional_v<U>::value) {
if constexpr (std::is_enum_v<U>) {
s = "integer"sv;
}
else if constexpr (is_optional_v<U>::value) {
s = ormpp_postgresql::type_to_name(identity<typename U::value_type>{});
}
else {
Expand Down
116 changes: 116 additions & 0 deletions tests/test_ormpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,122 @@ TEST_CASE("query tuple_optional_t") {
#endif
}

enum class Color { BLUE = 10, RED = 15 };
enum Fruit { APPLE, BANANA };

struct test_enum_t {
Color color;
Fruit fruit;
int id;
};
REGISTER_AUTO_KEY(test_enum_t, id)
REFLECTION(test_enum_t, id, color, fruit)

TEST_CASE("test enum") {
#ifdef ORMPP_ENABLE_MYSQL
dbng<mysql> mysql;
if (mysql.connect(ip, username, password, db)) {
mysql.execute("drop table if exists test_enum_t");
mysql.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
mysql.insert<test_enum_t>({Color::BLUE});
auto vec = mysql.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::BLUE);
CHECK(vec.front().fruit == APPLE);
vec.front().color = Color::RED;
vec.front().fruit = BANANA;
mysql.update(vec.front());
vec = mysql.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::RED);
CHECK(vec.front().fruit == BANANA);
mysql.update<test_enum_t>({Color::BLUE, APPLE, 1}, "id=1");
vec = mysql.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::BLUE);
CHECK(vec.front().fruit == APPLE);
vec.front().color = Color::RED;
vec.front().fruit = BANANA;
mysql.replace(vec.front());
vec = mysql.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::RED);
CHECK(vec.front().fruit == BANANA);
mysql.delete_records<test_enum_t>();
vec = mysql.query<test_enum_t>();
CHECK(vec.size() == 0);
}
#endif
#ifdef ORMPP_ENABLE_PG
dbng<postgresql> postgres;
if (postgres.connect(ip, username, password, db)) {
postgres.execute("drop table if exists test_enum_t");
postgres.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
postgres.insert<test_enum_t>({Color::BLUE});
auto vec = postgres.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::BLUE);
CHECK(vec.front().fruit == APPLE);
vec.front().color = Color::RED;
vec.front().fruit = BANANA;
postgres.update(vec.front());
vec = postgres.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::RED);
CHECK(vec.front().fruit == BANANA);
postgres.update<test_enum_t>({Color::BLUE, APPLE, 1}, "id=1");
vec = postgres.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::BLUE);
CHECK(vec.front().fruit == APPLE);
vec.front().color = Color::RED;
vec.front().fruit = BANANA;
postgres.replace(vec.front());
vec = postgres.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::RED);
CHECK(vec.front().fruit == BANANA);
postgres.delete_records<test_enum_t>();
vec = postgres.query<test_enum_t>();
CHECK(vec.size() == 0);
}
#endif
#ifdef ORMPP_ENABLE_SQLITE3
dbng<sqlite> sqlite;
if (sqlite.connect(db)) {
sqlite.execute("drop table if exists test_enum_t");
sqlite.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
sqlite.insert<test_enum_t>({Color::BLUE});
auto vec = sqlite.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::BLUE);
CHECK(vec.front().fruit == APPLE);
vec.front().color = Color::RED;
vec.front().fruit = BANANA;
sqlite.update(vec.front());
vec = sqlite.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::RED);
CHECK(vec.front().fruit == BANANA);
sqlite.update<test_enum_t>({Color::BLUE, APPLE, 1}, "id=1");
vec = sqlite.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::BLUE);
CHECK(vec.front().fruit == APPLE);
vec.front().color = Color::RED;
vec.front().fruit = BANANA;
sqlite.replace(vec.front());
vec = sqlite.query<test_enum_t>();
CHECK(vec.size() == 1);
CHECK(vec.front().color == Color::RED);
CHECK(vec.front().fruit == BANANA);
sqlite.delete_records<test_enum_t>();
vec = sqlite.query<test_enum_t>();
CHECK(vec.size() == 0);
}
#endif
}

struct alias {
std::string name;
int id;
Expand Down

0 comments on commit f2e6568

Please sign in to comment.