Skip to content

Commit

Permalink
Merge pull request #75 from zauguin/std_optional
Browse files Browse the repository at this point in the history
std::optional support
  • Loading branch information
aminroosta authored Jan 31, 2017
2 parents 0974493 + 7e9dd24 commit cf01458
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 2 deletions.
39 changes: 37 additions & 2 deletions hdr/sqlite_modern_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <memory>
#include <vector>

#if __has_include(<optional>)
#include <optional>
#endif

#ifdef _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
#include <boost/optional.hpp>
#endif
Expand Down Expand Up @@ -237,6 +241,11 @@ namespace sqlite {
friend database_binder& operator <<(database_binder& db, const std::u16string& txt);


#if __has_include(<optional>)
template <typename OptionalT> friend database_binder& operator <<(database_binder& db, const std::optional<OptionalT>& val);
template <typename OptionalT> friend void get_col_from_db(database_binder& db, int inx, std::optional<OptionalT>& o);
#endif

#ifdef _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
template <typename BoostOptionalT> friend database_binder& operator <<(database_binder& db, const boost::optional<BoostOptionalT>& val);
template <typename BoostOptionalT> friend void get_col_from_db(database_binder& db, int inx, boost::optional<BoostOptionalT>& o);
Expand Down Expand Up @@ -545,7 +554,33 @@ namespace sqlite {
++db._inx;
return db;
}
// boost::optinal support for NULL values
// std::optional support for NULL values
#if __has_include(<optional>)
template <typename OptionalT> inline database_binder& operator <<(database_binder& db, const std::optional<OptionalT>& val) {
if(val) {
return operator << (std::move(db), std::move(*val));
}
int hresult;
if((hresult = sqlite3_bind_null(db._stmt.get(), db._inx)) != SQLITE_OK) {
exceptions::throw_sqlite_error(hresult);
}

++db._inx;
return db;
}

template <typename OptionalT> inline void get_col_from_db(database_binder& db, int inx, std::optional<OptionalT>& o) {
if(sqlite3_column_type(db._stmt.get(), inx) == SQLITE_NULL) {
o.reset();
} else {
OptionalT v;
get_col_from_db(db, inx, v);
o = std::move(v);
}
}
#endif

// boost::optional support for NULL values
#ifdef _MODERN_SQLITE_BOOST_OPTIONAL_SUPPORT
template <typename BoostOptionalT> inline database_binder& operator <<(database_binder& db, const boost::optional<BoostOptionalT>& val) {
if(val) {
Expand Down Expand Up @@ -574,7 +609,7 @@ namespace sqlite {
// Some ppl are lazy so we have a operator for proper prep. statemant handling.
void inline operator++(database_binder& db, int) { db.execute(); db.reset(); }

// Convert the rValue binder to a reference and call first op<<, its needed for the call that creates the binder (be carfull of recursion here!)
// Convert the rValue binder to a reference and call first op<<, its needed for the call that creates the binder (be carefull of recursion here!)
template<typename T> database_binder& operator << (database_binder&& db, const T& val) { return db << val; }

}
75 changes: 75 additions & 0 deletions tests/std_optional.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <unistd.h>
#include <iostream>

#include <sqlite_modern_cpp.h>

using namespace sqlite;
using namespace std;

#if __has_include(<optional>)
void insert(database& db, bool is_null) {
int id = 1;
std::optional<int> val;
if(!is_null) val = 5;

db << "delete from test where id = 1";
db << "insert into test(id,val) values(?,?)" << id << val;
}

void select(database& db, bool should_be_null) {
db << "select id,val from test" >> [&](long long, std::optional<int> val) {
if(should_be_null) {
if(val) exit(EXIT_FAILURE);
} else {
if(!val) exit(EXIT_FAILURE);
}
};
}

struct TmpFile {
string fname;

TmpFile() {
char f[] = "/tmp/sqlite_modern_cpp_test_XXXXXX";
int fid = mkstemp(f);
close(fid);

fname = f;
}

~TmpFile() {
unlink(fname.c_str());
}
};

int main() {
try {
// creates a database file 'dbfile.db' if it does not exists.
TmpFile file;
database db(file.fname);

db << "drop table if exists test";
db <<
"create table if not exists test ("
" id integer primary key,"
" val int"
");";

insert(db, true);
select(db, true);

insert(db, false);
select(db, false);

} catch(exception& e) {
cout << e.what() << endl;
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
#else
#pragma message "<optional> not found, test disabled."
int main() {
exit(EXIT_SUCCESS);
}
#endif

0 comments on commit cf01458

Please sign in to comment.