3535#include " serializing_util.h"
3636#include " table_info.h"
3737
38- namespace sqlite_orm {
38+ SQLITE_ORM_EXPORT namespace sqlite_orm {
39+ struct on_open {
40+ using storage_prop_tag = int ;
41+
42+ #ifndef SQLITE_ORM_AGGREGATE_PAREN_INIT_SUPPORTED
43+ on_open () = default;
44+ on_open (std::function<void (sqlite3*)> onOpen) : onOpen{std::move (onOpen)} {}
45+ #endif
3946
47+ std::function<void (sqlite3*)> onOpen;
48+ };
49+
50+ struct connection_control {
51+ using storage_prop_tag = int ;
52+
53+ bool openForever = false ;
54+ };
55+ }
56+
57+ namespace sqlite_orm {
4058 namespace internal {
4159
4260 struct storage_base {
@@ -289,17 +307,19 @@ namespace sqlite_orm {
289307 * needed and closes when it is not needed. This function breaks this rule. In memory storage always
290308 * keeps connection opened so calling this for in-memory storage changes nothing.
291309 * Note about multithreading: in multithreading context avoiding using this function for not in-memory
292- * storage may lead to data races. If you have data races in such a configuration try to call `open_forever`
310+ * storage may lead to data races. If you have data races in such a configuration try to call `open_forever() `
293311 * before accessing your storage - it may fix data races.
294312 */
295313 void open_forever () {
296- this ->isOpenedForever = true ;
297- this ->connection ->retain ();
314+ if (!this ->isOpenedForever ) {
315+ this ->isOpenedForever = true ;
316+ this ->connection ->retain ();
317+ }
298318 }
299319
300320 /* *
301321 * Create an application-defined scalar SQL function.
302- * Can be called at any time no matter whether the database connection is opened or not.
322+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is opened or not.
303323 *
304324 * Note: `create_scalar_function()` merely creates a closure to generate an instance of the scalar function object,
305325 * together with a copy of the passed initialization arguments.
@@ -342,7 +362,7 @@ namespace sqlite_orm {
342362#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
343363 /* *
344364 * Create an application-defined scalar function.
345- * Can be called at any time no matter whether the database connection is opened or not.
365+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is opened or not.
346366 *
347367 * Note: `create_scalar_function()` merely creates a closure to generate an instance of the scalar function object,
348368 * together with a copy of the passed initialization arguments.
@@ -357,7 +377,7 @@ namespace sqlite_orm {
357377
358378 /* *
359379 * Create an application-defined scalar function.
360- * Can be called at any time no matter whether the database connection is opened or not.
380+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is opened or not.
361381 *
362382 * If `quotedF` contains a freestanding function, stateless lambda or stateless function object,
363383 * `quoted_scalar_function::callable()` uses the original function object, assuming it is free of side effects;
@@ -398,7 +418,7 @@ namespace sqlite_orm {
398418
399419 /* *
400420 * Create an application-defined aggregate SQL function.
401- * Can be called at any time no matter whether the database connection is opened or not.
421+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is opened or not.
402422 *
403423 * Note: `create_aggregate_function()` merely creates a closure to generate an instance of the aggregate function object,
404424 * together with a copy of the passed initialization arguments.
@@ -447,7 +467,7 @@ namespace sqlite_orm {
447467#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
448468 /* *
449469 * Create an application-defined aggregate function.
450- * Can be called at any time no matter whether the database connection is opened or not.
470+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is opened or not.
451471 *
452472 * Note: `create_aggregate_function()` merely creates a closure to generate an instance of the aggregate function object,
453473 * together with a copy of the passed initialization arguments.
@@ -462,7 +482,7 @@ namespace sqlite_orm {
462482
463483 /* *
464484 * Delete a scalar function you created before.
465- * Can be called at any time no matter whether the database connection is open or not.
485+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is open or not.
466486 */
467487 template <class F >
468488 void delete_scalar_function () {
@@ -474,7 +494,7 @@ namespace sqlite_orm {
474494#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
475495 /* *
476496 * Delete a scalar function you created before.
477- * Can be called at any time no matter whether the database connection is open or not.
497+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is open or not.
478498 */
479499 template <orm_scalar_function auto f>
480500 void delete_scalar_function () {
@@ -483,7 +503,7 @@ namespace sqlite_orm {
483503
484504 /* *
485505 * Delete a quoted scalar function you created before.
486- * Can be called at any time no matter whether the database connection is open or not.
506+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is open or not.
487507 */
488508 template <orm_quoted_scalar_function auto quotedF>
489509 void delete_scalar_function () {
@@ -493,7 +513,7 @@ namespace sqlite_orm {
493513
494514 /* *
495515 * Delete aggregate function you created before.
496- * Can be called at any time no matter whether the database connection is open or not.
516+ * Can be called at any time (in a single-threaded context) no matter whether the database connection is open or not.
497517 */
498518 template <class F >
499519 void delete_aggregate_function () {
@@ -661,30 +681,41 @@ namespace sqlite_orm {
661681 }
662682
663683 protected:
664- storage_base (std::string filename, int foreignKeysCount) :
684+ storage_base (std::string filename,
685+ sqlite_orm::on_open onOpenSpec,
686+ connection_control connectionCtrl,
687+ int foreignKeysCount) :
688+ on_open{std::move (onOpenSpec.onOpen )}, isOpenedForever{connectionCtrl.openForever },
665689 pragma (std::bind (&storage_base::get_connection, this )),
666690 limit (std::bind (&storage_base::get_connection, this )),
667691 inMemory (filename.empty () || filename == " :memory:" ),
668692 connection (std::make_unique<connection_holder>(
669693 std::move (filename),
670- inMemory,
694+ inMemory || isOpenedForever ,
671695 std::bind (&storage_base::on_open_internal, this , std::placeholders::_1))),
672696 cachedForeignKeysCount (foreignKeysCount) {
673697 if (this ->inMemory ) {
674698 this ->connection ->retain ();
675699 }
700+ if (this ->isOpenedForever ) {
701+ this ->connection ->retain ();
702+ }
676703 }
677704
678705 storage_base (const storage_base& other) :
679706 on_open (other.on_open ), pragma (std::bind (&storage_base::get_connection, this )),
680707 limit (std::bind (&storage_base::get_connection, this )), inMemory (other.inMemory ),
708+ isOpenedForever{other.isOpenedForever },
681709 connection (std::make_unique<connection_holder>(
682710 *other.connection ,
683711 std::bind (&storage_base::on_open_internal, this , std::placeholders::_1))),
684712 cachedForeignKeysCount (other.cachedForeignKeysCount ) {
685713 if (this ->inMemory ) {
686714 this ->connection ->retain ();
687715 }
716+ if (this ->isOpenedForever ) {
717+ this ->connection ->retain ();
718+ }
688719 }
689720
690721 ~storage_base () {
@@ -719,15 +750,15 @@ namespace sqlite_orm {
719750 perform_exec (db, " PRAGMA foreign_keys" , extract_single_value<bool >, &result);
720751 return result;
721752 }
722-
723753#endif
724- void on_open_internal (sqlite3* db) {
725754
755+ void on_open_internal (sqlite3* db) {
726756#if SQLITE_VERSION_NUMBER >= 3006019
727757 if (this ->cachedForeignKeysCount ) {
728758 this ->foreign_keys (db, true );
729759 }
730760#endif
761+
731762 if (this ->pragma .synchronous_ != -1 ) {
732763 this ->pragma .set_pragma (" synchronous" , this ->pragma .synchronous_ , db);
733764 }
0 commit comments