Skip to content

Commit 72af939

Browse files
committed
Merge pull request #26 from aminroosta/fix25
Fixed boost::optional support #25 and added Test
2 parents 71eb026 + 271a571 commit 72af939

File tree

7 files changed

+125
-45
lines changed

7 files changed

+125
-45
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ addons:
1010
- gcc-5
1111
- g++-5
1212
- libsqlite3-dev
13+
- libboost-all-dev
1314

1415
before_install:
1516
- export CXX="g++-5" CC="gcc-5"

hdr/sqlite_modern_cpp.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
#include <ctime>
77
#include <tuple>
88

9+
#ifdef _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
10+
#include <boost/optional.hpp>
11+
#endif
12+
913
#include <sqlite3.h>
1014

1115
#include <sqlite_modern_cpp/utility/function_traits.h>
@@ -184,6 +188,11 @@ class database_binder {
184188
template<typename T> friend database_binder&& operator <<(database_binder&& ddb,T const&& val);
185189
template<typename T> friend void get_col_from_db(database_binder& ddb, int inx, T& val);
186190

191+
#ifdef _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
192+
template <typename BoostOptionalT> friend database_binder&& operator <<(database_binder&& db, const boost::optional<BoostOptionalT>&& val);
193+
template <typename BoostOptionalT> friend void get_col_from_db(database_binder& db, int inx, boost::optional<BoostOptionalT>& o);
194+
#endif
195+
187196
protected:
188197
database_binder(sqlite3* db, std::u16string const & sql):
189198
_db(db),
@@ -473,6 +482,8 @@ template<> inline void get_col_from_db(database_binder& db, int inx, std::u16str
473482
w = std::u16string(reinterpret_cast<char16_t const *>(sqlite3_column_text16(db._stmt, inx)));
474483
}
475484
}
485+
486+
// boost::optinal support for NULL values
476487
template<> inline database_binder&& operator <<(database_binder&& db, std::u16string const&& txt) {
477488
int hresult;
478489
if((hresult = sqlite3_bind_text16(db._stmt, db._inx, txt.data(), -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
@@ -483,6 +494,31 @@ template<> inline database_binder&& operator <<(database_binder&& db, std::u16st
483494
return std::move(db);
484495
}
485496

497+
#ifdef _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
498+
template <typename BoostOptionalT> database_binder&& operator <<(database_binder&& db, const boost::optional<BoostOptionalT>&& val) {
499+
if(val) {
500+
return operator << (std::move(db), std::move(*val));
501+
}
502+
int hresult;
503+
if((hresult = sqlite3_bind_null(db._stmt, db._inx)) != SQLITE_OK) {
504+
db.throw_sqlite_error(hresult);
505+
}
506+
507+
++db._inx;
508+
return std::move(db);
509+
}
510+
511+
template <typename BoostOptionalT> void get_col_from_db(database_binder& db, int inx, boost::optional<BoostOptionalT>& o) {
512+
if(sqlite3_column_type(db._stmt, inx) == SQLITE_NULL) {
513+
o.reset();
514+
} else {
515+
BoostOptionalT v;
516+
get_col_from_db(db, inx, v);
517+
o = std::move(v);
518+
}
519+
}
520+
#endif
521+
486522
/* call the rvalue functions */
487523
template<typename T> database_binder&& operator <<(database_binder&& db, T const& val) { return std::move(db) << std::move(val); }
488524

hdr/sqlite_modern_cpp/extensions/boost_json_spirit.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ namespace sqlite {
1111
a = tmp.get_array();
1212
}
1313

14-
template<> database_binder& operator <<(database_binder& db, const json_spirit::mArray& val) {
14+
template<> database_binder&& operator <<(database_binder&& db, const json_spirit::mArray&& val) {
1515
auto tmp = json_spirit::write(val);
16-
if(sqlite3_bind_blob(db._stmt, db._inx, tmp.c_str() , tmp.size() , SQLITE_TRANSIENT) != SQLITE_OK) {
17-
db.throw_sqlite_error();
16+
auto ret = sqlite3_bind_blob(db._stmt, db._inx, tmp.c_str(), tmp.size(), SQLITE_TRANSIENT);
17+
if(ret != SQLITE_OK) {
18+
db.throw_sqlite_error(ret);
1819
}
1920

2021
++db._inx;
21-
return db;
22+
return std::move(db);
2223
}
2324

2425
// json_spirit::mObject
@@ -31,13 +32,14 @@ namespace sqlite {
3132
a = tmp.get_obj();
3233
}
3334

34-
template<> database_binder& operator <<(database_binder& db, const json_spirit::mObject& val) {
35+
template<> database_binder&& operator <<(database_binder&& db, const json_spirit::mObject&& val) {
3536
auto tmp = json_spirit::write(val);
36-
if(sqlite3_bind_blob(db._stmt, db._inx, tmp.c_str(), tmp.size(), SQLITE_TRANSIENT) != SQLITE_OK) {
37-
db.throw_sqlite_error();
37+
auto ret = sqlite3_bind_blob(db._stmt, db._inx, tmp.c_str(), tmp.size(), SQLITE_TRANSIENT);
38+
if( ret != SQLITE_OK) {
39+
db.throw_sqlite_error(ret);
3840
}
3941

4042
++db._inx;
41-
return db;
43+
return std::move(db);
4244
}
4345
}

hdr/sqlite_modern_cpp/extensions/boost_optional.h

Lines changed: 0 additions & 26 deletions
This file was deleted.

hdr/sqlite_modern_cpp/extensions/boost_uuid.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
namespace sqlite {
44
// boost::uuid
5-
template<> database_binder& operator <<(database_binder& db, const boost::uuids::uuid& uuid) {
5+
template<> database_binder&& operator <<(database_binder&& db, const boost::uuids::uuid&& uuid) {
66

7-
if(sqlite3_bind_blob(db._stmt, db._inx, uuid.begin(), uuid.size(), SQLITE_TRANSIENT) != SQLITE_OK) {
8-
db.throw_sqlite_error();
7+
auto ret = sqlite3_bind_blob(db._stmt, db._inx, uuid.begin(), uuid.size(), SQLITE_TRANSIENT);
8+
if(ret != SQLITE_OK) {
9+
db.throw_sqlite_error(ret);
910
}
1011

1112
++db._inx;
12-
return db;
13+
return std::move(db);
1314
}
1415
template <> void get_col_from_db(database_binder& db, int inx, boost::uuids::uuid& uuid) {
1516
if(sqlite3_column_type(db._stmt, inx) == SQLITE_NULL) {

hdr/sqlite_modern_cpp/extensions/std_time_t.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,18 @@
22

33
namespace sqlite {
44
// std::time_t
5-
template<> void get_col_from_db(database_binder& db, int inx, std::time_t& t) {
5+
template<std::time_t> inline void get_col_from_db(database_binder& db, int inx, std::time_t& t) {
66
if(sqlite3_column_type(db._stmt, inx) == SQLITE_NULL) {
77
t = 0;
88
} else {
99
t = sqlite3_column_int64(db._stmt, inx);
1010
}
1111
}
12-
template<> database_binder& operator <<(database_binder& db, const std::time_t& val) {
12+
template<std::time_t> inline database_binder&& operator <<(database_binder&& db, const std::time_t&& val) {
1313
//sqlite_int64 tmpval = static_cast<sqlite_int64>(val);
14-
if(sqlite3_bind_int64(db._stmt, db._inx, val) != SQLITE_OK) {
15-
db.throw_sqlite_error();
16-
}
17-
14+
auto ret = sqlite3_bind_int64(db._stmt, db._inx, val);
15+
if(ret != SQLITE_OK) db.throw_sqlite_error(ret);
1816
++db._inx;
19-
return db;
17+
return std::move(db);
2018
}
2119
}

tests/boost_optional.cc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <iostream>
2+
3+
#define _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
4+
#include <sqlite_modern_cpp.h>
5+
6+
using namespace sqlite;
7+
using namespace std;
8+
9+
void insert(database& db, bool is_null) {
10+
int id = 1;
11+
boost::optional<int> val;
12+
if(!is_null) val = 5;
13+
14+
db << "delete from test where id = 1";
15+
db << "insert into test(id,val) values(?,?)" << id << val;
16+
}
17+
18+
void select(database& db, bool should_be_null) {
19+
db << "select id,val from test" >> [&](long long id, boost::optional<int> val) {
20+
id = id;
21+
if(should_be_null) {
22+
if(val) exit(1);
23+
} else {
24+
if(!val) exit(1);
25+
}
26+
};
27+
}
28+
29+
struct TmpFile {
30+
string fname;
31+
32+
TmpFile() {
33+
char f[] = "/tmp/sqlite_modern_cpp_test_XXXXXX";
34+
int fid = mkstemp(f);
35+
close(fid);
36+
37+
fname = f;
38+
}
39+
40+
~TmpFile() {
41+
unlink(fname.c_str());
42+
}
43+
};
44+
45+
int main() {
46+
try {
47+
// creates a database file 'dbfile.db' if it does not exists.
48+
TmpFile file;
49+
database db(file.fname);
50+
51+
db << "drop table if exists test";
52+
db <<
53+
"create table if not exists test ("
54+
" id integer primary key autoincrement not null,"
55+
" val int"
56+
");";
57+
58+
insert(db, true);
59+
select(db, true);
60+
61+
insert(db, false);
62+
select(db, false);
63+
64+
} catch(exception& e) {
65+
cout << e.what() << endl;
66+
}
67+
return 0;
68+
}

0 commit comments

Comments
 (0)