summary refs log tree commit diff stats
path: root/lib/impure/db_sqlite.nim
diff options
context:
space:
mode:
authorAdam Strzelecki <ono@java.pl>2015-06-04 00:38:49 +0200
committerAdam Strzelecki <ono@java.pl>2015-06-09 20:53:03 +0200
commit87429071330cc8516dab2612b45689a510528f6a (patch)
treeef0182542edb1ea69315ea24e94b724a700d3d13 /lib/impure/db_sqlite.nim
parent25a19875172db5024c1edf7011a5b46996e4f543 (diff)
downloadNim-87429071330cc8516dab2612b45689a510528f6a.tar.gz
db: InstantRow and instantRows
It is drop-in replacement for Row and fastRows, however instantRows returns a
handle, not seq[string], so no Nim string is created until [] operator is
called on the given handle. Also there is a len() proc returning number of
columns in the handle.

In some situations, when we iterate through many rows, but later we just read
few columns this solution will be quicker than converting all column to Nim
seq[string] on each iteration.
Diffstat (limited to 'lib/impure/db_sqlite.nim')
-rw-r--r--lib/impure/db_sqlite.nim24
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim
index 47e7c1900..1a037becc 100644
--- a/lib/impure/db_sqlite.nim
+++ b/lib/impure/db_sqlite.nim
@@ -16,6 +16,8 @@ type
   DbConn* = PSqlite3  ## encapsulates a database connection
   Row* = seq[string]  ## a row of a dataset. NULL database values will be
                        ## transformed always to the empty string.
+  InstantRow* = Pstmt  ## a handle that can be used to get a row's column
+                       ## text on demand
   EDb* = object of IOError ## exception that is raised if a database error occurs
   
   SqlQuery* = distinct string ## an SQL query string
@@ -109,6 +111,24 @@ iterator fastRows*(db: DbConn, query: SqlQuery,
     yield result
   if finalize(stmt) != SQLITE_OK: dbError(db)
 
+iterator instantRows*(db: DbConn, query: SqlQuery,
+                      args: varargs[string, `$`]): InstantRow
+                      {.tags: [FReadDb].} =
+  ## same as fastRows but returns a handle that can be used to get column text
+  ## on demand using []. Returned handle is valid only within interator body.
+  var stmt = setupQuery(db, query, args)
+  while step(stmt) == SQLITE_ROW:
+    yield stmt
+  if finalize(stmt) != SQLITE_OK: dbError(db)
+
+proc `[]`*(row: InstantRow, col: int32): string {.inline.} =
+  ## returns text for given column of the row
+  $column_text(row, col)
+
+proc len*(row: InstantRow): int32 {.inline.} =
+  ## returns number of columns in the row
+  column_count(row)
+
 proc getRow*(db: DbConn, query: SqlQuery,
              args: varargs[string, `$`]): Row {.tags: [FReadDb].} =
   ## retrieves a single row. If the query doesn't return any rows, this proc
@@ -216,5 +236,7 @@ when not defined(testing) and isMainModule:
   #db.query("insert into tbl1 values('goodbye', 20)")
   for r in db.rows(sql"select * from tbl1", []):
     echo(r[0], r[1])
-  
+  for r in db.instantRows(sql"select * from tbl1", []):
+    echo(r[0], r[1])
+
   db_sqlite.close(db)