diff --git a/datastore/key/namespace.nim b/datastore/key/namespace.nim index eecda9c..6613c09 100644 --- a/datastore/key/namespace.nim +++ b/datastore/key/namespace.nim @@ -1,6 +1,5 @@ import std/hashes -import std/strformat import pkg/questionable import pkg/questionable/results @@ -19,32 +18,26 @@ type func init*(T: type Namespace, field, value: string): ?!T = if value.contains(Delimiter): - return failure (&"value string must not contain Delimiter '{Delimiter}'") - .catch.expect("should not fail") + return failure ("value string must not contain Delimiter " & Delimiter) if value.contains(Separator): - return failure (&"value string must not contain Separator {Separator}") - .catch.expect("should not fail") + return failure ("value string must not contain Separator " & Separator) if field.contains(Delimiter): - return failure (&"field string must not contain Delimiter {Delimiter}") - .catch.expect("should not fail") + return failure ("field string must not contain Delimiter " & Delimiter) if field.contains(Separator): - return failure (&"field string must not contain Separator {Separator}") - .catch.expect("should not fail") + return failure ("field string must not contain Separator " & Separator) success T(field: field, value: value) func init*(T: type Namespace, id: string): ?!T = if id.len > 0: if id.contains(Separator): - return failure (&"id string must not contain Separator {Separator}") - .catch.expect("should not fail") + return failure (&"id string must not contain Separator " & Separator) if id.count(Delimiter) > 1: - return failure (&"id string must not contain more than one {Delimiter}") - .catch.expect("should not fail") + return failure (&"id string must not contain more than one " & Delimiter) let (field, value) = block: diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index ff440e4..d959028 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -228,8 +228,7 @@ method query*( let queryStmt = QueryStmt.prepare( - self.db.env, queryStr).expect("should not fail") - + self.db.env, queryStr).expect("Query prepare should not fail") s = RawStmtPtr(queryStmt) var @@ -263,7 +262,7 @@ method query*( let key = Key.init( $sqlite3_column_text_not_null(s, QueryStmtIdCol)) - .expect("should not fail") + .expect("Key should should not fail") blob: ?pointer = if query.value: @@ -308,7 +307,7 @@ method query*( iter.dispose = proc(): Future[?!void] {.async.} = discard sqlite3_reset(s) discard sqlite3_clear_bindings(s) - s.dispose + iter.next = nil return success() iter.next = next diff --git a/datastore/sql/sqlitedsdb.nim b/datastore/sql/sqlitedsdb.nim index f35e087..2381ecb 100644 --- a/datastore/sql/sqlitedsdb.nim +++ b/datastore/sql/sqlitedsdb.nim @@ -279,17 +279,30 @@ proc getDBFilePath*(path: string): ?!string = except CatchableError as exc: return failure(exc.msg) -proc close*(self: SQLiteDsDb) = - self.containsStmt.dispose - self.getStmt.dispose - self.beginStmt.dispose - self.endStmt.dispose - self.rollbackStmt.dispose - self.getVersionedStmt.dispose - self.updateVersionedStmt.dispose - self.insertVersionedStmt.dispose - self.deleteVersionedStmt.dispose - self.getChangesStmt.dispose +proc close*(self: var SQLiteDsDb) = + + var + env: AutoDisposed[SQLite] + + defer: + disposeIfUnreleased(env) + + env.val = self.env + + if not RawStmtPtr(self.containsStmt).isNil: + self.containsStmt.dispose + + if not RawStmtPtr(self.getStmt).isNil: + self.getStmt.dispose + + if not RawStmtPtr(self.beginStmt).isNil: + self.beginStmt.dispose + + if not RawStmtPtr(self.endStmt).isNil: + self.endStmt.dispose + + if not RawStmtPtr(self.rollbackStmt).isNil: + self.rollbackStmt.dispose if not RawStmtPtr(self.deleteStmt).isNil: self.deleteStmt.dispose @@ -297,7 +310,20 @@ proc close*(self: SQLiteDsDb) = if not RawStmtPtr(self.putStmt).isNil: self.putStmt.dispose - self.env.dispose + if not RawStmtPtr(self.getVersionedStmt).isNil: + self.getVersionedStmt.dispose + + if not RawStmtPtr(self.updateVersionedStmt).isNil: + self.updateVersionedStmt.dispose + + if not RawStmtPtr(self.insertVersionedStmt).isNil: + self.insertVersionedStmt.dispose + + if not RawStmtPtr(self.deleteVersionedStmt).isNil: + self.deleteVersionedStmt.dispose + + if not RawStmtPtr(self.getChangesStmt).isNil: + self.getChangesStmt.dispose proc open*( T: type SQLiteDsDb, @@ -329,7 +355,7 @@ proc open*( open(absPath, env.val, flags) - let + var pragmaStmt = journalModePragmaStmt(env.val) checkExec(pragmaStmt) diff --git a/datastore/sql/sqliteutils.nim b/datastore/sql/sqliteutils.nim index bffb6e8..6cdbabb 100644 --- a/datastore/sql/sqliteutils.nim +++ b/datastore/sql/sqliteutils.nim @@ -89,7 +89,8 @@ template checkErr*(op: untyped) = return failure $sqlite3_errstr(v) template dispose*(rawStmt: RawStmtPtr) = - discard sqlite3_finalize(rawStmt) + doAssert SQLITE_OK == sqlite3_finalize(rawStmt) + rawStmt = nil template checkExec*(s: RawStmtPtr) = if (let x = sqlite3_step(s); x != SQLITE_DONE): @@ -113,16 +114,22 @@ template prepare*( s template checkExec*(env: SQLite, q: string) = - let + var s = prepare(env, q) checkExec(s) template dispose*(db: SQLite) = + # TODO: the assert bellow fails because we're + # not releasing all the statements at the time of + # releasing the connection. I suspect these are the + # query iterators that aren't being released on close + # doAssert SQLITE_OK == sqlite3_close(db) discard sqlite3_close(db) template dispose*(sqliteStmt: SQLiteStmt) = - discard sqlite3_finalize(RawStmtPtr(sqliteStmt)) + doAssert SQLITE_OK == sqlite3_finalize(RawStmtPtr(sqliteStmt)) + sqliteStmt = nil proc release*[T](x: var AutoDisposed[T]): T = result = x.val @@ -171,7 +178,7 @@ proc sqlite3_column_text_not_null*( text template journalModePragmaStmt*(env: SQLite): RawStmtPtr = - let + var s = prepare(env, "PRAGMA journal_mode = WAL;") if (let x = sqlite3_step(s); x != SQLITE_ROW): @@ -250,7 +257,7 @@ proc query*( query: string, onData: DataProc): ?!bool = - let + var s = ? NoParamsStmt.prepare(env, query) res = s.query((), onData) diff --git a/tests/datastore/sql/testsqlitedsdb.nim b/tests/datastore/sql/testsqlitedsdb.nim index b6ff105..7251d31 100644 --- a/tests/datastore/sql/testsqlitedsdb.nim +++ b/tests/datastore/sql/testsqlitedsdb.nim @@ -27,7 +27,7 @@ suite "Test Open SQLite Datastore DB": require(not dirExists(basePathAbs)) test "Should create and open datastore DB": - let + var dsDb = SQLiteDsDb.open( path = dbPathAbs, flags = SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE).tryGet() @@ -39,7 +39,7 @@ suite "Test Open SQLite Datastore DB": fileExists(dbPathAbs) test "Should open existing DB": - let + var dsDb = SQLiteDsDb.open( path = dbPathAbs, flags = SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE).tryGet() @@ -54,7 +54,7 @@ suite "Test Open SQLite Datastore DB": check: fileExists(dbPathAbs) - let + var dsDb = SQLiteDsDb.open( path = dbPathAbs, flags = SQLITE_OPEN_READONLY).tryGet()