1212
1313namespace gromox {
1414
15+ static std::unordered_map<std::string, std::string> active_xa;
16+ static std::mutex active_xa_lock;
1517unsigned int gx_sqlite_debug, gx_force_write_txn, gx_sql_deep_backtrace;
1618
1719static bool write_statement (const char *q)
@@ -28,11 +30,18 @@ xstmt gx_sql_prep(sqlite3 *db, const char *query)
2830 if (gx_sqlite_debug >= 1 )
2931 mlog (LV_DEBUG, " > sqlite3_prep(%s, %s)" , znul (sqlite3_db_filename (db, nullptr )), query);
3032 auto state = sqlite3_txn_state (db, " main" );
31- if (state == SQLITE_TXN_READ && write_statement (query))
32- mlog (LV_ERR, " > sqlite3_prep(%s) inside a readonly TXN" , query);
33+ if (state == SQLITE_TXN_READ && write_statement (query)) {
34+ auto fn = sqlite3_db_filename (db, nullptr );
35+ if (fn == nullptr || *fn == ' \0 ' )
36+ fn = " :memory:" ;
37+ auto it = active_xa.find (fn);
38+ mlog (LV_ERR, " sqlite_prep(%s): ro held by [%s], rw at [%s]" , query,
39+ it != active_xa.end () ? it->second .c_str () : " unknown" ,
40+ simple_backtrace ().c_str ());
41+ }
3342 int ret = sqlite3_prepare_v2 (db, query, -1 , &out.m_ptr , nullptr );
3443 if (ret != SQLITE_OK)
35- mlog (LV_ERR, " sqlite3_prepare_v2 (%s) \" %s\" : %s (%d)" ,
44+ mlog (LV_ERR, " sqlite_prep (%s) \" %s\" : %s (%d)" ,
3645 znul (sqlite3_db_filename (db, nullptr )),
3746 query, sqlite3_errstr (ret), ret);
3847 return out;
@@ -46,9 +55,6 @@ xtransaction &xtransaction::operator=(xtransaction &&o) noexcept
4655 return *this ;
4756}
4857
49- static std::unordered_map<std::string, std::string> active_xa;
50- static std::mutex active_xa_lock;
51-
5258xtransaction::~xtransaction ()
5359{
5460 teardown ();
@@ -176,8 +182,15 @@ int gx_sql_exec(sqlite3 *db, const char *query, unsigned int flags)
176182 if (gx_sqlite_debug >= 1 )
177183 mlog (LV_DEBUG, " > sqlite3_exec(%s, %s)" , znul (sqlite3_db_filename (db, nullptr )), query);
178184 auto state = sqlite3_txn_state (db, " main" );
179- if (state == SQLITE_TXN_READ && write_statement (query))
180- mlog (LV_ERR, " > sqlite3_exec(%s) inside a readonly TXN" , query);
185+ if (state == SQLITE_TXN_READ && write_statement (query)) {
186+ auto fn = sqlite3_db_filename (db, nullptr );
187+ if (fn == nullptr || *fn == ' \0 ' )
188+ fn = " :memory:" ;
189+ auto it = active_xa.find (fn);
190+ mlog (LV_ERR, " sqlite_exec(%s): ro held by [%s], rw at [%s]" , query,
191+ it != active_xa.end () ? it->second .c_str () : " unknown" ,
192+ simple_backtrace ().c_str ());
193+ }
181194 auto ret = sqlite3_exec (db, query, nullptr , nullptr , &estr);
182195 if (ret == SQLITE_OK)
183196 return ret;
0 commit comments