diff --git a/Doxyfile b/Doxyfile index 4a5a701..7fd615b 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1935,7 +1935,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = __cplusplus=201402L # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/examples/example1/main.cpp b/examples/example1/main.cpp index 45ba078..b11640d 100644 --- a/examples/example1/main.cpp +++ b/examples/example1/main.cpp @@ -16,6 +16,8 @@ #include #include +#include + #ifdef SQLITECPP_ENABLE_ASSERT_HANDLER namespace SQLite @@ -80,6 +82,34 @@ private: SQLite::Statement mQuery; ///< Database prepared SQL query }; +void demonstrateVariadicBind() { +#if ( __cplusplus>= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) + // Open a database file in create/write mode + SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + + db.exec("DROP TABLE IF EXISTS test"); + db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"); + + { + SQLite::Statement query(db, "INSERT INTO test VALUES (?, ?)"); + + SQLite::bind(query, 42, "fortytwo"); + // Execute the one-step query to insert the blob + int nb = query.exec(); + std::cout << "INSERT INTO test VALUES (NULL, ?)\", returned " << nb + << std::endl; + } + + SQLite::Statement query(db, "SELECT * FROM test"); + std::cout << "SELECT * FROM test :\n"; + if (query.executeStep()) { + std::cout << query.getColumn(0).getInt() << "\t\"" + << query.getColumn(1).getText() << "\"\n"; + } +#else + throw std::runtime_error("demonstrateVariadicBind(): sorry, no c++14 support in this build."); +#endif +} int main () { @@ -422,6 +452,15 @@ int main () } remove("out.png"); + //example with variadic bind (requires c++14) + try { + std::cout<<"cplusplus version is "<<__cplusplus<<'\n'; + demonstrateVariadicBind(); + } catch (std::exception& e) { + std::cout << "SQLite exception: " << e.what() << std::endl; + return EXIT_FAILURE; // unexpected error : exit the example program + } + std::cout << "everything ok, quitting\n"; return EXIT_SUCCESS; diff --git a/include/SQLiteCpp/VariadicBind.h b/include/SQLiteCpp/VariadicBind.h new file mode 100644 index 0000000..2448230 --- /dev/null +++ b/include/SQLiteCpp/VariadicBind.h @@ -0,0 +1,74 @@ +/** + * @file VariadicBind.h + * @ingroup SQLiteCpp + * @brief Convenience function for Statement::bind(...) + * + * Copyright (c) 2016 Paul Dreik (github@pauldreik.se) + * + * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt + * or copy at http://opensource.org/licenses/MIT) + */ +#pragma once + +#include + +namespace SQLite +{ + + +//this requires c++14. seems like visual studio 2015 should work (yet untested). +#if ( __cplusplus>= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) +/// @cond +#include +#include + +/// implementation detail for variadic bind. +namespace detail { +template +inline void invoke_with_index(F&& f, std::integer_sequence, + const Args& ...args) { + std::initializer_list { (f(I+1,args),0)... }; +} + +/// implementation detail for variadic bind. +template +inline void invoke_with_index(F&&f, const Args& ... args) { + invoke_with_index(std::forward(f),std::index_sequence_for(), args...); +} + +} //namespace detail +/// @endcond + +/** + * \brief Convenience function for calling Statement::bind(...) once for each argument given. + * + * This takes care of incrementing the index between each calls to bind. + * + * This feature requires a c++14 capable compiler. + * + * \code{.cpp} + * SQLite::Statement stm("SELECT * FROM MyTable WHERE colA>? && colB=? && colC +void bind(SQLite::Statement& s,const Args& ... args) { + + static_assert(sizeof...(args)>0,"please invoke bind with one or more args"); + + auto f=[&s](std::size_t index, const auto& value) { + s.bind(index,value); + }; + detail::invoke_with_index(f, args...); +} +#else +//not supported in older c++. provide a fallback? +#endif // c++14 + +} // namespace SQLite