@@ -145,6 +145,7 @@ exqlite_close(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
145145 assert (env );
146146
147147 connection_t * conn = NULL ;
148+ int rc = SQLITE_OK ;
148149
149150 if (argc != 1 ) {
150151 return enif_make_badarg (env );
@@ -154,7 +155,21 @@ exqlite_close(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
154155 return make_error_tuple (env , "invalid_connection" );
155156 }
156157
158+ int autocommit = sqlite3_get_autocommit (conn -> db );
159+ if (autocommit == 0 ) {
160+ rc = sqlite3_exec (conn -> db , "ROLLBACK;" , NULL , NULL , NULL );
161+ if (rc != SQLITE_OK ) {
162+ return make_sqlite3_error_tuple (env , rc , conn -> db );
163+ }
164+ }
165+
166+ // note: _v2 may not fully close the connection, hence why we check if
167+ // any transaction is open above, to make sure other connections aren't blocked.
168+ // v1 is guaranteed to close or error, but will return error if any
169+ // unfinalized statements, which we likely have, as we rely on the destructors
170+ // to later run to clean those up
157171 sqlite3_close_v2 (conn -> db );
172+
158173 conn -> db = NULL ;
159174
160175 return make_atom (env , "ok" );
@@ -539,6 +554,27 @@ exqlite_last_insert_rowid(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
539554 return make_ok_tuple (env , enif_make_int64 (env , last_rowid ));
540555}
541556
557+ static ERL_NIF_TERM
558+ exqlite_transaction_status (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
559+ {
560+ assert (env );
561+
562+ connection_t * conn = NULL ;
563+
564+ if (argc != 1 ) {
565+ return enif_make_badarg (env );
566+ }
567+
568+ if (!enif_get_resource (env , argv [0 ], connection_type , (void * * )& conn )) {
569+ return make_error_tuple (env , "invalid_connection" );
570+ }
571+
572+ int autocommit = sqlite3_get_autocommit (conn -> db );
573+ return make_ok_tuple (
574+ env ,
575+ autocommit == 0 ? make_atom (env , "transaction" ) : make_atom (env , "idle" ));
576+ }
577+
542578static void
543579connection_type_destructor (ErlNifEnv * env , void * arg )
544580{
@@ -611,6 +647,7 @@ static ErlNifFunc nif_funcs[] = {
611647 {"step" , 2 , exqlite_step , ERL_NIF_DIRTY_JOB_IO_BOUND },
612648 {"columns" , 2 , exqlite_columns , ERL_NIF_DIRTY_JOB_IO_BOUND },
613649 {"last_insert_rowid" , 1 , exqlite_last_insert_rowid , ERL_NIF_DIRTY_JOB_IO_BOUND },
650+ {"transaction_status" , 1 , exqlite_transaction_status , ERL_NIF_DIRTY_JOB_IO_BOUND },
614651};
615652
616653ERL_NIF_INIT (Elixir .Exqlite .Sqlite3NIF , nif_funcs , on_load , NULL , NULL , NULL )
0 commit comments