Hello, I’m building a small SQLite-backed library in nimony and I’m stuck on the cleanup model for owned DB resources.
The core problem is that some cleanup operations can fail:
So I’m trying to choose between:
type
DbHandle = object
conn: sqlite3.DbConn
StmtHandle = object
stmt: sqlite3.Stmt
proc `=destroy`(x: DbHandle) =
discard sqlite3_close_v2(x.conn) # can fail, but destructor can't report it
proc `=destroy`(x: StmtHandle) =
discard sqlite3_finalize(x.stmt) # same problem
If I avoid destructors, cleanup becomes explicit:
proc close(x: DbHandle) {.raises.} =
checkSqlite(sqlite3_close_v2(x.conn))
iterator rows(x: sink StmtHandle): Row =
try:
while step(x.stmt) == SQLITE_ROW:
yield decode(x)
finally:
checkSqlite(sqlite3_finalize(x.stmt))
That preserves error reporting, but loses RAII-style cleanup.
So my question is: what’s the recommended pattern in Nim/nimony for database libraries when cleanup itself can fail? Should destructors be allowed to raise, or is explicit close/finally the preferred idiom? I am torn with this one.