Skip to content

Commit f2e6568

Browse files
authored
Merge pull request #133 from Jacyking/master
support for enum
2 parents 530ce35 + 9e4ec7c commit f2e6568

File tree

6 files changed

+234
-42
lines changed

6 files changed

+234
-42
lines changed

README.md

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -91,47 +91,94 @@ REFLECTION(student, code, name, sex, age, dm, classroom)
9191
using namespace ormpp;
9292

9393
struct person {
94-
int id;
95-
std::string name;
9694
std::optional<int> age; // 可以插入null值
95+
std::string name;
96+
int id;
9797
};
98+
REGISTER_AUTO_KEY(person, id)
99+
REGISTER_CONFLICT_KEY(person, name)
100+
// REGISTER_CONFLICT_KEY(person, name, age)
98101
REFLECTION(person, id, name, age)
99102
// REFLECTION_WITH_NAME(person, "CUSTOM_TABLE_NAME", id, name, age)
103+
// REFLECTION_ALIAS(person, "CUSTOM_TABLE_NAME",
104+
// FLDALIAS(&person::id, "person_id"),
105+
// FLDALIAS(&person::name, "person_name"),
106+
// FLDALIAS(&person::age, "person_age"));
107+
108+
int main() {
109+
person p = {"test1", 2};
110+
person p1 = {"test2", 3};
111+
person p2 = {"test3", 4};
112+
std::vector<person> v{p1, p2};
113+
114+
dbng<mysql> mysql;
115+
mysql.connect("127.0.0.1", "dbuser", "yourpwd", "testdb");
116+
mysql.create_datatable<person>(ormpp_auto_key{"id"});
117+
118+
mysql.insert(p);
119+
mysql.insert(v);
120+
auto id1 = mysql.get_insert_id_after_insert<person>(p);
121+
auto id2 = mysql.get_insert_id_after_insert<person>(v);
122+
123+
mysql.update(p);
124+
mysql.update(v);
125+
mysql.update(p, "id=1");
126+
127+
mysql.replace(p);
128+
mysql.replace(v);
129+
130+
auto result = mysql.query<person>(); // vector<person>
131+
for (auto &person : result) {
132+
std::cout << person.id << " " << person.name << " " << person.age
133+
<< std::endl;
134+
}
135+
136+
mysql.delete_records<person>();
137+
138+
// transaction
139+
mysql.begin();
140+
for (int i = 0; i < 10; ++i) {
141+
person s = {"tom", 19};
142+
if (!mysql.insert(s)) {
143+
mysql.rollback();
144+
return -1;
145+
}
146+
}
147+
mysql.commit();
148+
return 0;
149+
}
150+
```
100151
101-
int main()
102-
{
103-
person p = {1, "test1", 2};
104-
person p1 = {2, "test2", 3};
105-
person p2 = {3, "test3", 4};
106-
std::vector<person> v{p1, p2};
152+
```C++
153+
enum class Color { BLUE = 10, RED = 15 };
154+
enum Fruit { APPLE, BANANA };
107155
108-
dbng<mysql> mysql;
109-
mysql.connect("127.0.0.1", "dbuser", "yourpwd", "testdb");
110-
mysql.create_datatable<person>();
111-
112-
mysql.insert(p);
113-
mysql.insert(v);
114-
115-
mysql.update(p);
116-
mysql.update(v);
117-
118-
auto result = mysql.query<person>(); //vector<person>
119-
for(auto& person : result){
120-
std::cout<<person.id<<" "<<person.name<<" "<<person.age<<std::endl;
121-
}
122-
123-
mysql.delete_records<person>();
124-
125-
//transaction
126-
mysql.begin();
127-
for (int i = 0; i < 10; ++i) {
128-
person s = {i, "tom", 19};
129-
if(!mysql.insert(s)){
130-
mysql.rollback();
131-
return -1;
132-
}
133-
}
134-
mysql.commit();
156+
struct test_enum_t {
157+
Color color;
158+
Fruit fruit;
159+
int id;
160+
};
161+
REGISTER_AUTO_KEY(test_enum_t, id)
162+
REFLECTION(test_enum_t, id, color, fruit)
163+
164+
int main() {
165+
dbng<sqlite> sqlite;
166+
sqlite.connect(db);
167+
sqlite.execute("drop table if exists test_enum_t");
168+
sqlite.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
169+
sqlite.insert<test_enum_t>({Color::BLUE});
170+
auto vec1 = sqlite.query<test_enum_t>();
171+
vec1.front().color = Color::RED;
172+
sqlite.update(vec1.front());
173+
auto vec2 = sqlite.query<test_enum_t>();
174+
sqlite.update<test_enum_t>({Color::BLUE, BANANA, 1}, "id=1");
175+
auto vec3 = sqlite.query<test_enum_t>();
176+
vec3.front().color = Color::RED;
177+
sqlite.replace(vec3.front());
178+
auto vec4 = sqlite.query<test_enum_t>();
179+
sqlite.delete_records<test_enum_t>();
180+
auto vec5 = sqlite.query<test_enum_t>();
181+
return 0;
135182
}
136183
```
137184

include/mysql.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ class mysql {
172172
param.buffer_type = MYSQL_TYPE_NULL;
173173
}
174174
}
175+
else if constexpr (std::is_enum_v<U>) {
176+
param.buffer_type = MYSQL_TYPE_LONG;
177+
param.buffer = const_cast<void *>(static_cast<const void *>(&value));
178+
}
175179
else if constexpr (std::is_arithmetic_v<U>) {
176180
param.buffer_type =
177181
(enum_field_types)ormpp_mysql::type_to_id(identity<U>{});
@@ -205,6 +209,10 @@ class mysql {
205209
if constexpr (is_optional_v<U>::value) {
206210
return set_param_bind(param_bind, *value, i, mp, is_null);
207211
}
212+
else if constexpr (std::is_enum_v<U>) {
213+
param_bind.buffer_type = MYSQL_TYPE_LONG;
214+
param_bind.buffer = const_cast<void *>(static_cast<const void *>(&value));
215+
}
208216
else if constexpr (std::is_arithmetic_v<U>) {
209217
param_bind.buffer_type =
210218
(enum_field_types)ormpp_mysql::type_to_id(identity<U>{});

include/postgresql.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,11 @@ class postgresql {
519519
param_values.push_back({});
520520
}
521521
}
522+
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
523+
std::vector<char> temp(20, 0);
524+
itoa_fwd(static_cast<int>(value), temp.data());
525+
param_values.push_back(std::move(temp));
526+
}
522527
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
523528
std::vector<char> temp(20, 0);
524529
itoa_fwd(value, temp.data());
@@ -563,6 +568,9 @@ class postgresql {
563568
assign(item, row, i);
564569
value = std::move(item);
565570
}
571+
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
572+
value = static_cast<U>(std::atoi(PQgetvalue(res_, row, i)));
573+
}
566574
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
567575
value = std::atoi(PQgetvalue(res_, row, i));
568576
}

include/sqlite.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,10 @@ class sqlite {
432432
}
433433
return SQLITE_OK == sqlite3_bind_null(stmt_, i);
434434
}
435-
else if constexpr (std::is_integral_v<U> &&
436-
!iguana::is_int64_v<U>) { // double, int64
435+
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
436+
return SQLITE_OK == sqlite3_bind_int(stmt_, i, static_cast<int>(value));
437+
}
438+
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
437439
return SQLITE_OK == sqlite3_bind_int(stmt_, i, value);
438440
}
439441
else if constexpr (iguana::is_int64_v<U>) {
@@ -468,8 +470,10 @@ class sqlite {
468470
assign(item, i);
469471
value = std::move(item);
470472
}
471-
else if constexpr (std::is_integral_v<U> &&
472-
!iguana::is_int64_v<U>) { // double, int64
473+
else if constexpr (std::is_enum_v<U> && !iguana::is_int64_v<U>) {
474+
value = static_cast<U>(sqlite3_column_int(stmt_, i));
475+
}
476+
else if constexpr (std::is_integral_v<U> && !iguana::is_int64_v<U>) {
473477
if constexpr (std::is_same_v<U, char>) {
474478
value = (char)sqlite3_column_int(stmt_, i);
475479
}

include/utility.hpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ inline constexpr auto get_type_names(DBType type) {
140140
}
141141
#ifdef ORMPP_ENABLE_MYSQL
142142
else if (type == DBType::mysql) {
143-
if constexpr (is_optional_v<U>::value) {
143+
if constexpr (std::is_enum_v<U>) {
144+
s = "INTEGER"sv;
145+
}
146+
else if constexpr (is_optional_v<U>::value) {
144147
s = ormpp_mysql::type_to_name(identity<typename U::value_type>{});
145148
}
146149
else {
@@ -150,7 +153,10 @@ inline constexpr auto get_type_names(DBType type) {
150153
#endif
151154
#ifdef ORMPP_ENABLE_SQLITE3
152155
else if (type == DBType::sqlite) {
153-
if constexpr (is_optional_v<U>::value) {
156+
if constexpr (std::is_enum_v<U>) {
157+
s = "INTEGER"sv;
158+
}
159+
else if constexpr (is_optional_v<U>::value) {
154160
s = ormpp_sqlite::type_to_name(identity<typename U::value_type>{});
155161
}
156162
else {
@@ -160,7 +166,10 @@ inline constexpr auto get_type_names(DBType type) {
160166
#endif
161167
#ifdef ORMPP_ENABLE_PG
162168
else if (type == DBType::postgresql) {
163-
if constexpr (is_optional_v<U>::value) {
169+
if constexpr (std::is_enum_v<U>) {
170+
s = "integer"sv;
171+
}
172+
else if constexpr (is_optional_v<U>::value) {
164173
s = ormpp_postgresql::type_to_name(identity<typename U::value_type>{});
165174
}
166175
else {

tests/test_ormpp.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,122 @@ TEST_CASE("query tuple_optional_t") {
13391339
#endif
13401340
}
13411341

1342+
enum class Color { BLUE = 10, RED = 15 };
1343+
enum Fruit { APPLE, BANANA };
1344+
1345+
struct test_enum_t {
1346+
Color color;
1347+
Fruit fruit;
1348+
int id;
1349+
};
1350+
REGISTER_AUTO_KEY(test_enum_t, id)
1351+
REFLECTION(test_enum_t, id, color, fruit)
1352+
1353+
TEST_CASE("test enum") {
1354+
#ifdef ORMPP_ENABLE_MYSQL
1355+
dbng<mysql> mysql;
1356+
if (mysql.connect(ip, username, password, db)) {
1357+
mysql.execute("drop table if exists test_enum_t");
1358+
mysql.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
1359+
mysql.insert<test_enum_t>({Color::BLUE});
1360+
auto vec = mysql.query<test_enum_t>();
1361+
CHECK(vec.size() == 1);
1362+
CHECK(vec.front().color == Color::BLUE);
1363+
CHECK(vec.front().fruit == APPLE);
1364+
vec.front().color = Color::RED;
1365+
vec.front().fruit = BANANA;
1366+
mysql.update(vec.front());
1367+
vec = mysql.query<test_enum_t>();
1368+
CHECK(vec.size() == 1);
1369+
CHECK(vec.front().color == Color::RED);
1370+
CHECK(vec.front().fruit == BANANA);
1371+
mysql.update<test_enum_t>({Color::BLUE, APPLE, 1}, "id=1");
1372+
vec = mysql.query<test_enum_t>();
1373+
CHECK(vec.size() == 1);
1374+
CHECK(vec.front().color == Color::BLUE);
1375+
CHECK(vec.front().fruit == APPLE);
1376+
vec.front().color = Color::RED;
1377+
vec.front().fruit = BANANA;
1378+
mysql.replace(vec.front());
1379+
vec = mysql.query<test_enum_t>();
1380+
CHECK(vec.size() == 1);
1381+
CHECK(vec.front().color == Color::RED);
1382+
CHECK(vec.front().fruit == BANANA);
1383+
mysql.delete_records<test_enum_t>();
1384+
vec = mysql.query<test_enum_t>();
1385+
CHECK(vec.size() == 0);
1386+
}
1387+
#endif
1388+
#ifdef ORMPP_ENABLE_PG
1389+
dbng<postgresql> postgres;
1390+
if (postgres.connect(ip, username, password, db)) {
1391+
postgres.execute("drop table if exists test_enum_t");
1392+
postgres.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
1393+
postgres.insert<test_enum_t>({Color::BLUE});
1394+
auto vec = postgres.query<test_enum_t>();
1395+
CHECK(vec.size() == 1);
1396+
CHECK(vec.front().color == Color::BLUE);
1397+
CHECK(vec.front().fruit == APPLE);
1398+
vec.front().color = Color::RED;
1399+
vec.front().fruit = BANANA;
1400+
postgres.update(vec.front());
1401+
vec = postgres.query<test_enum_t>();
1402+
CHECK(vec.size() == 1);
1403+
CHECK(vec.front().color == Color::RED);
1404+
CHECK(vec.front().fruit == BANANA);
1405+
postgres.update<test_enum_t>({Color::BLUE, APPLE, 1}, "id=1");
1406+
vec = postgres.query<test_enum_t>();
1407+
CHECK(vec.size() == 1);
1408+
CHECK(vec.front().color == Color::BLUE);
1409+
CHECK(vec.front().fruit == APPLE);
1410+
vec.front().color = Color::RED;
1411+
vec.front().fruit = BANANA;
1412+
postgres.replace(vec.front());
1413+
vec = postgres.query<test_enum_t>();
1414+
CHECK(vec.size() == 1);
1415+
CHECK(vec.front().color == Color::RED);
1416+
CHECK(vec.front().fruit == BANANA);
1417+
postgres.delete_records<test_enum_t>();
1418+
vec = postgres.query<test_enum_t>();
1419+
CHECK(vec.size() == 0);
1420+
}
1421+
#endif
1422+
#ifdef ORMPP_ENABLE_SQLITE3
1423+
dbng<sqlite> sqlite;
1424+
if (sqlite.connect(db)) {
1425+
sqlite.execute("drop table if exists test_enum_t");
1426+
sqlite.create_datatable<test_enum_t>(ormpp_auto_key{"id"});
1427+
sqlite.insert<test_enum_t>({Color::BLUE});
1428+
auto vec = sqlite.query<test_enum_t>();
1429+
CHECK(vec.size() == 1);
1430+
CHECK(vec.front().color == Color::BLUE);
1431+
CHECK(vec.front().fruit == APPLE);
1432+
vec.front().color = Color::RED;
1433+
vec.front().fruit = BANANA;
1434+
sqlite.update(vec.front());
1435+
vec = sqlite.query<test_enum_t>();
1436+
CHECK(vec.size() == 1);
1437+
CHECK(vec.front().color == Color::RED);
1438+
CHECK(vec.front().fruit == BANANA);
1439+
sqlite.update<test_enum_t>({Color::BLUE, APPLE, 1}, "id=1");
1440+
vec = sqlite.query<test_enum_t>();
1441+
CHECK(vec.size() == 1);
1442+
CHECK(vec.front().color == Color::BLUE);
1443+
CHECK(vec.front().fruit == APPLE);
1444+
vec.front().color = Color::RED;
1445+
vec.front().fruit = BANANA;
1446+
sqlite.replace(vec.front());
1447+
vec = sqlite.query<test_enum_t>();
1448+
CHECK(vec.size() == 1);
1449+
CHECK(vec.front().color == Color::RED);
1450+
CHECK(vec.front().fruit == BANANA);
1451+
sqlite.delete_records<test_enum_t>();
1452+
vec = sqlite.query<test_enum_t>();
1453+
CHECK(vec.size() == 0);
1454+
}
1455+
#endif
1456+
}
1457+
13421458
struct alias {
13431459
std::string name;
13441460
int id;

0 commit comments

Comments
 (0)