Skip to content

Added columnCount(stmt) and columnMetadata(stmt, nCol) functions. #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/tiny_sqlite.nim
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ type
values: seq[DbValue]
columns: seq[string]

ColumnMetadata* = object
databaseName*: string
tableName*: string
originName*: string


const SqliteRcOk = [ sqlite.SQLITE_OK, sqlite.SQLITE_DONE, sqlite.SQLITE_ROW ]


Expand Down Expand Up @@ -574,6 +580,25 @@ proc value*(statement: SqlStatement,
for row in statement.iterate(params):
return some(row.values[0])

func columnCount*(statement: SqlStatement): int =
## Get column count for the prepared statement.
assertCanUseStatement statement
sqlite.column_count(statement.handle)

func columnMetadata*(statement: SqlStatement, idx: Natural): Option[ColumnMetadata] =
## Get column metadata for the given column of the prepared statement.
## See https://www.sqlite.org/c3ref/column_database_name.html
assertCanUseStatement statement
let
db = sqlite.column_database_name(statement.handle, idx.int32)
table = sqlite.column_table_name(statement.handle, idx.int32)
origin = sqlite.column_origin_name(statement.handle, idx.int32)
if db == nil or table == nil or origin == nil:
return none(ColumnMetadata)
some(ColumnMetadata(databaseName: $db,
tableName: $table,
originName: $origin))

proc finalize*(statement: SqlStatement): void =
## Finalize the statement. This needs to be called once the statement is no longer used to
## prevent memory leaks. Finalizing an already finalized statement is a harmless no-op.
Expand Down
6 changes: 6 additions & 0 deletions src/tiny_sqlite/sqlite_wrapper.nim
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ proc column_count*(stmt: Stmt): cint
proc column_name*(stmt: Stmt, col: cint): cstring
{.cdecl, dynlib: Lib, importc: "sqlite3_column_name".}

proc column_database_name*(stmt: Stmt, col: cint): cstring
{.cdecl, dynlib: Lib, importc: "sqlite3_column_database_name".}

proc column_origin_name*(stmt: Stmt, col: cint): cstring
{.cdecl, dynlib: Lib, importc: "sqlite3_column_origin_name".}

proc column_table_name*(stmt: Stmt, col: cint): cstring
{.cdecl, dynlib: Lib, importc: "sqlite3_column_table_name".}

Expand Down
12 changes: 12 additions & 0 deletions tests/tests.nim
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,18 @@ test "row.unpack":
expect AssertionDefect:
discard row.unpack(tuple[name: string])

test "stmt.columnMetadata":
withDb:
let stmt = db.stmt(SelectPersons)
check stmt.columnCount == 2
let col1 = stmt.columnMetadata(1)
check col1.isSome
check col1.get.databaseName == "main"
check col1.get.tableName == "Person"
check col1.get.originName == "age"
let col2 = stmt.columnMetadata(2)
check col2.isNone

test "stmt.all":
withDb:
let stmt = db.stmt(SelectPersons)
Expand Down