diff --git a/README.md b/README.md index f321e52..3a50438 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,22 @@ sqlite3pp::query qry( "FROM foods"); ``` +## loadable extension + +```cpp +#define SQLITE3PP_LOADABLE_EXTENSION +#include + +int sqlite3_extension_init( + sqlite3 *pdb, + char **pzErrMsg, + const sqlite3_api_routines *pApi) { + SQLITE_EXTENSION_INIT2(pApi); + sqlite3pp:database db(sqlite3pp::ext::borrow(pdb)); + // pdb is not closed since db just borrows it. +} + +``` # See also diff --git a/headeronly_src/sqlite3pp.h b/headeronly_src/sqlite3pp.h index b5f1a41..f15a60c 100644 --- a/headeronly_src/sqlite3pp.h +++ b/headeronly_src/sqlite3pp.h @@ -25,24 +25,33 @@ #ifndef SQLITE3PP_H #define SQLITE3PP_H -#define SQLITE3PP_VERSION "1.0.6" +#define SQLITE3PP_VERSION "1.0.7" #define SQLITE3PP_VERSION_MAJOR 1 #define SQLITE3PP_VERSION_MINOR 0 -#define SQLITE3PP_VERSION_PATCH 6 +#define SQLITE3PP_VERSION_PATCH 7 #include #include -#include #include #include #include +#ifdef SQLITE3PP_LOADABLE_EXTENSION +#include +SQLITE_EXTENSION_INIT1 +#else +# include +#endif + namespace sqlite3pp { + class database; + namespace ext { class function; class aggregate; + database borrow(sqlite3* pdb); } template @@ -71,6 +80,7 @@ namespace sqlite3pp friend class database_error; friend class ext::function; friend class ext::aggregate; + friend database ext::borrow(sqlite3* pdb); public: using busy_handler = std::function; @@ -119,8 +129,12 @@ namespace sqlite3pp void set_update_handler(update_handler h); void set_authorize_handler(authorize_handler h); + private: + database(sqlite3* pdb) : db_(pdb), borrowing_(true) {} + private: sqlite3* db_; + bool borrowing_; busy_handler bh_; commit_handler ch_; diff --git a/headeronly_src/sqlite3pp.ipp b/headeronly_src/sqlite3pp.ipp index cd5f29d..f85631a 100644 --- a/headeronly_src/sqlite3pp.ipp +++ b/headeronly_src/sqlite3pp.ipp @@ -64,7 +64,7 @@ namespace sqlite3pp } // namespace - inline database::database(char const* dbname, int flags, char const* vfs) : db_(nullptr) + inline database::database(char const* dbname, int flags, char const* vfs) : db_(nullptr), borrowing_(false) { if (dbname) { auto rc = connect(dbname, flags, vfs); @@ -74,6 +74,7 @@ namespace sqlite3pp } inline database::database(database&& db) : db_(std::move(db.db_)), + borrowing_(std::move(db.borrowing_)), bh_(std::move(db.bh_)), ch_(std::move(db.ch_)), rh_(std::move(db.rh_)), @@ -87,6 +88,7 @@ namespace sqlite3pp { db_ = std::move(db.db_); db.db_ = nullptr; + borrowing_ = std::move(db.borrowing_); bh_ = std::move(db.bh_); ch_ = std::move(db.ch_); @@ -99,12 +101,16 @@ namespace sqlite3pp inline database::~database() { - disconnect(); + if (!borrowing_) { + disconnect(); + } } inline int database::connect(char const* dbname, int flags, char const* vfs) { - disconnect(); + if (!borrowing_) { + disconnect(); + } return sqlite3_open_v2(dbname, &db_, flags, vfs); } diff --git a/headeronly_src/sqlite3ppext.h b/headeronly_src/sqlite3ppext.h index f0aefcf..d0469f4 100644 --- a/headeronly_src/sqlite3ppext.h +++ b/headeronly_src/sqlite3ppext.h @@ -76,6 +76,9 @@ namespace sqlite3pp namespace ext { + database borrow(sqlite3* pdb) { + return database(pdb); + } class context : noncopyable { diff --git a/src/sqlite3pp.cpp b/src/sqlite3pp.cpp index 58fdfce..5c789cc 100644 --- a/src/sqlite3pp.cpp +++ b/src/sqlite3pp.cpp @@ -66,7 +66,7 @@ namespace sqlite3pp } // namespace - database::database(char const* dbname, int flags, char const* vfs) : db_(nullptr) + database::database(char const* dbname, int flags, char const* vfs) : db_(nullptr), borrowing_(false) { if (dbname) { auto rc = connect(dbname, flags, vfs); @@ -75,7 +75,12 @@ namespace sqlite3pp } } + database::database(sqlite3* pdb) : db_(pdb), borrowing_(true) + { + } + database::database(database&& db) : db_(std::move(db.db_)), + borrowing_(std::move(db.borrowing_)), bh_(std::move(db.bh_)), ch_(std::move(db.ch_)), rh_(std::move(db.rh_)), @@ -89,7 +94,7 @@ namespace sqlite3pp { db_ = std::move(db.db_); db.db_ = nullptr; - + borrowing_ = std::move(db.borrowing_); bh_ = std::move(db.bh_); ch_ = std::move(db.ch_); rh_ = std::move(db.rh_); @@ -101,12 +106,16 @@ namespace sqlite3pp database::~database() { - disconnect(); + if (!borrowing_) { + disconnect(); + } } int database::connect(char const* dbname, int flags, char const* vfs) { - disconnect(); + if (!borrowing_) { + disconnect(); + } return sqlite3_open_v2(dbname, &db_, flags, vfs); } diff --git a/src/sqlite3pp.h b/src/sqlite3pp.h index 8621ea2..5ea62df 100644 --- a/src/sqlite3pp.h +++ b/src/sqlite3pp.h @@ -25,24 +25,33 @@ #ifndef SQLITE3PP_H #define SQLITE3PP_H -#define SQLITE3PP_VERSION "1.0.0" +#define SQLITE3PP_VERSION "1.0.7" #define SQLITE3PP_VERSION_MAJOR 1 #define SQLITE3PP_VERSION_MINOR 0 -#define SQLITE3PP_VERSION_PATCH 6 +#define SQLITE3PP_VERSION_PATCH 7 #include #include -#include #include #include #include +#ifdef SQLITE3PP_LOADABLE_EXTENSION +#include +SQLITE_EXTENSION_INIT1 +#else +# include +#endif + namespace sqlite3pp { + class database; + namespace ext { class function; class aggregate; + database borrow(sqlite3* pdb); } template @@ -72,6 +81,7 @@ namespace sqlite3pp friend class database_error; friend class ext::function; friend class ext::aggregate; + friend database ext::borrow(sqlite3* pdb); public: using busy_handler = std::function; @@ -120,8 +130,12 @@ namespace sqlite3pp void set_update_handler(update_handler h); void set_authorize_handler(authorize_handler h); + private: + database(sqlite3* pdb); + private: sqlite3* db_; + bool borrowing_; busy_handler bh_; commit_handler ch_; diff --git a/src/sqlite3ppext.cpp b/src/sqlite3ppext.cpp index 6f0c28e..841295c 100644 --- a/src/sqlite3ppext.cpp +++ b/src/sqlite3ppext.cpp @@ -59,6 +59,9 @@ namespace sqlite3pp } // namespace + database borrow(sqlite3* pdb) { + return database(pdb); + } context::context(sqlite3_context* ctx, int nargs, sqlite3_value** values) : ctx_(ctx), nargs_(nargs), values_(values) diff --git a/src/sqlite3ppext.h b/src/sqlite3ppext.h index 2ce0e71..ed79398 100644 --- a/src/sqlite3ppext.h +++ b/src/sqlite3ppext.h @@ -76,6 +76,7 @@ namespace sqlite3pp namespace ext { + database borrow(sqlite3* pdb); class context : noncopyable {