annotate semiconginev2/thirdparty/db_connector/db_sqlite.nim @ 1264:cb4d626ca671

Added tag main for changeset e0f0a0be7880
author sam <sam@basx.dev>
date Sun, 28 Jul 2024 21:58:53 +0700
parents 56781cc0fc7c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1191
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
1 #
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
2 #
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
3 # Nim's Runtime Library
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
4 # (c) Copyright 2015 Andreas Rumpf
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
5 #
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
6 # See the file "copying.txt", included in this
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
7 # distribution, for details about the copyright.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
8 #
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
9
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
10 ## .. note:: In order to use this module, run `nimble install db_connector`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
11 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
12 ## A higher level `SQLite`:idx: database wrapper. This interface
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
13 ## is implemented for other databases too.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
14 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
15 ## Basic usage
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
16 ## ===========
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
17 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
18 ## The basic flow of using this module is:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
19 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
20 ## 1. Open database connection
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
21 ## 2. Execute SQL query
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
22 ## 3. Close database connection
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
23 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
24 ## Parameter substitution
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
25 ## ----------------------
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
26 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
27 ## All `db_*` modules support the same form of parameter substitution.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
28 ## That is, using the `?` (question mark) to signify the place where a
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
29 ## value should be placed. For example:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
30 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
31 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
32 ## sql"INSERT INTO my_table (colA, colB, colC) VALUES (?, ?, ?)"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
33 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
34 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
35 ## Opening a connection to a database
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
36 ## ----------------------------------
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
37 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
38 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
39 ## import db_connector/db_sqlite
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
40 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
41 ## # user, password, database name can be empty.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
42 ## # These params are not used on db_sqlite module.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
43 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
44 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
45 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
46 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
47 ## Creating a table
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
48 ## ----------------
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
49 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
50 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
51 ## db.exec(sql"DROP TABLE IF EXISTS my_table")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
52 ## db.exec(sql"""CREATE TABLE my_table (
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
53 ## id INTEGER,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
54 ## name VARCHAR(50) NOT NULL
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
55 ## )""")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
56 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
57 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
58 ## Inserting data
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
59 ## --------------
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
60 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
61 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
62 ## db.exec(sql"INSERT INTO my_table (id, name) VALUES (0, ?)",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
63 ## "Jack")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
64 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
65 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
66 ## Larger example
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
67 ## --------------
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
68 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
69 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
70 ## import db_connector/db_sqlite
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
71 ## import std/math
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
72 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
73 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
74 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
75 ## db.exec(sql"DROP TABLE IF EXISTS my_table")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
76 ## db.exec(sql"""CREATE TABLE my_table (
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
77 ## id INTEGER PRIMARY KEY,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
78 ## name VARCHAR(50) NOT NULL,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
79 ## i INT(11),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
80 ## f DECIMAL(18, 10)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
81 ## )""")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
82 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
83 ## db.exec(sql"BEGIN")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
84 ## for i in 1..1000:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
85 ## db.exec(sql"INSERT INTO my_table (name, i, f) VALUES (?, ?, ?)",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
86 ## "Item#" & $i, i, sqrt(i.float))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
87 ## db.exec(sql"COMMIT")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
88 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
89 ## for x in db.fastRows(sql"SELECT * FROM my_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
90 ## echo x
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
91 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
92 ## let id = db.tryInsertId(sql"""INSERT INTO my_table (name, i, f)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
93 ## VALUES (?, ?, ?)""",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
94 ## "Item#1001", 1001, sqrt(1001.0))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
95 ## echo "Inserted item: ", db.getValue(sql"SELECT name FROM my_table WHERE id=?", id)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
96 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
97 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
98 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
99 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
100 ## Storing binary data example
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
101 ##----------------------------
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
102 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
103 ## ```nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
104 ## import std/random
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
105 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
106 ## ## Generate random float datas
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
107 ## var orig = newSeq[float64](150)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
108 ## randomize()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
109 ## for x in orig.mitems:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
110 ## x = rand(1.0)/10.0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
111 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
112 ## let db = open("mysqlite.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
113 ## block: ## Create database
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
114 ## ## Binary datas needs to be of type BLOB in SQLite
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
115 ## let createTableStr = sql"""CREATE TABLE test(
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
116 ## id INTEGER NOT NULL PRIMARY KEY,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
117 ## data BLOB
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
118 ## )
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
119 ## """
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
120 ## db.exec(createTableStr)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
121 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
122 ## block: ## Insert data
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
123 ## var id = 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
124 ## ## Data needs to be converted to seq[byte] to be interpreted as binary by bindParams
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
125 ## var dbuf = newSeq[byte](orig.len*sizeof(float64))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
126 ## copyMem(unsafeAddr(dbuf[0]), unsafeAddr(orig[0]), dbuf.len)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
127 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
128 ## ## Use prepared statement to insert binary data into database
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
129 ## var insertStmt = db.prepare("INSERT INTO test (id, data) VALUES (?, ?)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
130 ## insertStmt.bindParams(id, dbuf)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
131 ## let bres = db.tryExec(insertStmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
132 ## ## Check insert
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
133 ## doAssert(bres)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
134 ## # Destroy statement
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
135 ## finalize(insertStmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
136 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
137 ## block: ## Use getValue to select data
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
138 ## var dataTest = db.getValue(sql"SELECT data FROM test WHERE id = ?", 1)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
139 ## ## Calculate sequence size from buffer size
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
140 ## let seqSize = int(dataTest.len*sizeof(byte)/sizeof(float64))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
141 ## ## Copy binary string data in dataTest into a seq
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
142 ## var res: seq[float64] = newSeq[float64](seqSize)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
143 ## copyMem(unsafeAddr(res[0]), addr(dataTest[0]), dataTest.len)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
144 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
145 ## ## Check datas obtained is identical
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
146 ## doAssert res == orig
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
147 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
148 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
149 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
150 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
151 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
152 ## Note
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
153 ## ====
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
154 ## This module does not implement any ORM features such as mapping the types from the schema.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
155 ## Instead, a `seq[string]` is returned for each row.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
156 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
157 ## The reasoning is as follows:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
158 ## 1. it's close to what many DBs offer natively (`char**`:c:)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
159 ## 2. it hides the number of types that the DB supports
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
160 ## (int? int64? decimal up to 10 places? geo coords?)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
161 ## 3. it's convenient when all you do is to forward the data to somewhere else (echo, log, put the data into a new query)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
162 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
163 ## See also
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
164 ## ========
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
165 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
166 ## * `db_odbc module <db_odbc.html>`_ for ODBC database wrapper
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
167 ## * `db_mysql module <db_mysql.html>`_ for MySQL database wrapper
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
168 ## * `db_postgres module <db_postgres.html>`_ for PostgreSQL database wrapper
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
169
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
170
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
171 import ./sqlite3, macros
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
172
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
173 import ./db_common
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
174 export db_common
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
175
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
176 import private/dbutils
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
177
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
178 import std/private/[since]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
179 when defined(nimPreviewSlimSystem):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
180 import std/assertions
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
181
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
182 type
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
183 DbConn* = PSqlite3 ## Encapsulates a database connection.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
184 Row* = seq[string] ## A row of a dataset. `NULL` database values will be
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
185 ## converted to an empty string.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
186 InstantRow* = PStmt ## A handle that can be used to get a row's column
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
187 ## text on demand.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
188 SqlPrepared* = distinct PStmt ## a identifier for the prepared queries
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
189
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
190 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: int32) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
191 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: int64) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
192 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: int) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
193 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: float64) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
194 proc bindNull*(ps: SqlPrepared, paramIdx: int) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
195 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: string, copy = true) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
196 proc bindParam*(ps: SqlPrepared, paramIdx: int,val: openArray[byte], copy = true) {.since: (1, 3).}
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
197
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
198 proc dbError*(db: DbConn) {.noreturn.} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
199 ## Raises a `DbError` exception.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
200 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
201 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
202 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
203 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
204 ## if not db.tryExec(sql"SELECT * FROM not_exist_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
205 ## dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
206 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
207 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
208 var e: ref DbError
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
209 new(e)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
210 e.msg = $sqlite3.errmsg(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
211 raise e
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
212
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
213 proc dbQuote*(s: string): string =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
214 ## Escapes the `'` (single quote) char to `''`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
215 ## Because single quote is used for defining `VARCHAR` in SQL.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
216 runnableExamples:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
217 doAssert dbQuote("'") == "''''"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
218 doAssert dbQuote("A Foobar's pen.") == "'A Foobar''s pen.'"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
219
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
220 result = "'"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
221 for c in items(s):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
222 if c == '\'': add(result, "''")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
223 else: add(result, c)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
224 add(result, '\'')
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
225
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
226 proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
227 dbFormatImpl(formatstr, dbQuote, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
228
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
229 proc prepare*(db: DbConn; q: string): SqlPrepared {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
230 ## Creates a new `SqlPrepared` statement.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
231 if prepare_v2(db, q, q.len.cint,result.PStmt, nil) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
232 discard finalize(result.PStmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
233 dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
234
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
235 proc tryExec*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
236 args: varargs[string, `$`]): bool {.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
237 tags: [ReadDbEffect, WriteDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
238 ## Tries to execute the query and returns `true` if successful, `false` otherwise.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
239 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
240 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
241 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
242 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
243 ## if not db.tryExec(sql"SELECT * FROM my_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
244 ## dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
245 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
246 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
247 assert(not db.isNil, "Database not connected.")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
248 var q = dbFormat(query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
249 var stmt: sqlite3.PStmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
250 if prepare_v2(db, q.cstring, q.len.cint, stmt, nil) == SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
251 let x = step(stmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
252 if x in [SQLITE_DONE, SQLITE_ROW]:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
253 result = finalize(stmt) == SQLITE_OK
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
254 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
255 discard finalize(stmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
256 result = false
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
257
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
258 proc tryExec*(db: DbConn, stmtName: SqlPrepared): bool {.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
259 tags: [ReadDbEffect, WriteDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
260 let x = step(stmtName.PStmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
261 if x in [SQLITE_DONE, SQLITE_ROW]:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
262 result = true
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
263 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
264 discard finalize(stmtName.PStmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
265 result = false
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
266
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
267 proc exec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) {.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
268 tags: [ReadDbEffect, WriteDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
269 ## Executes the query and raises a `DbError` exception if not successful.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
270 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
271 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
272 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
273 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
274 ## try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
275 ## db.exec(sql"INSERT INTO my_table (id, name) VALUES (?, ?)",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
276 ## 1, "item#1")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
277 ## except:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
278 ## stderr.writeLine(getCurrentExceptionMsg())
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
279 ## finally:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
280 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
281 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
282 if not tryExec(db, query, args): dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
283
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
284 macro untypedLen(args: varargs[untyped]): int =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
285 newLit(args.len)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
286
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
287 macro bindParams*(ps: SqlPrepared, params: varargs[untyped]): untyped {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
288 let bindParam = bindSym("bindParam", brOpen)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
289 let bindNull = bindSym("bindNull")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
290 let preparedStatement = genSym()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
291 result = newStmtList()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
292 # Store `ps` in a temporary variable. This prevents `ps` from being evaluated every call.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
293 result.add newNimNode(nnkLetSection).add(newIdentDefs(preparedStatement, newEmptyNode(), ps))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
294 for idx, param in params:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
295 if param.kind != nnkNilLit:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
296 result.add newCall(bindParam, preparedStatement, newIntLitNode idx + 1, param)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
297 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
298 result.add newCall(bindNull, preparedStatement, newIntLitNode idx + 1)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
299
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
300
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
301 template exec*(db: DbConn, stmtName: SqlPrepared,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
302 args: varargs[typed]): untyped =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
303 when untypedLen(args) > 0:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
304 if reset(stmtName.PStmt) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
305 dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
306 if clear_bindings(stmtName.PStmt) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
307 dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
308 stmtName.bindParams(args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
309 if not tryExec(db, stmtName): dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
310
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
311 proc newRow(L: int): Row =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
312 newSeq(result, L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
313 for i in 0..L-1: result[i] = ""
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
314
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
315 proc setupQuery(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
316 args: varargs[string]): PStmt =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
317 assert(not db.isNil, "Database not connected.")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
318 var q = dbFormat(query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
319 if prepare_v2(db, q.cstring, q.len.cint, result, nil) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
320
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
321 proc setupQuery(db: DbConn, stmtName: SqlPrepared): SqlPrepared {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
322 assert(not db.isNil, "Database not connected.")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
323 result = stmtName
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
324
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
325 proc setRow(stmt: PStmt, r: var Row, cols: cint) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
326 for col in 0'i32..cols-1:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
327 let cb = column_bytes(stmt, col)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
328 setLen(r[col], cb) # set capacity
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
329 if column_type(stmt, col) == SQLITE_BLOB:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
330 copyMem(addr(r[col][0]), column_blob(stmt, col), cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
331 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
332 setLen(r[col], 0)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
333 let x = column_text(stmt, col)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
334 if not isNil(x): add(r[col], x)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
335
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
336 iterator fastRows*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
337 args: varargs[string, `$`]): Row {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
338 ## Executes the query and iterates over the result dataset.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
339 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
340 ## This is very fast, but potentially dangerous. Use this iterator only
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
341 ## if you require **ALL** the rows.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
342 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
343 ## **Note:** Breaking the `fastRows()` iterator during a loop will cause the
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
344 ## next database query to raise a `DbError` exception `unable to close due
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
345 ## to ...`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
346 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
347 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
348 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
349 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
350 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
351 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
352 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
353 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
354 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
355 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
356 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
357 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
358 ## for row in db.fastRows(sql"SELECT id, name FROM my_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
359 ## echo row
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
360 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
361 ## # Output:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
362 ## # @["1", "item#1"]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
363 ## # @["2", "item#2"]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
364 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
365 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
366 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
367 var stmt = setupQuery(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
368 var L = (column_count(stmt))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
369 var result = newRow(L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
370 try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
371 while step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
372 setRow(stmt, result, L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
373 yield result
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
374 finally:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
375 if finalize(stmt) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
376
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
377 iterator fastRows*(db: DbConn, stmtName: SqlPrepared): Row
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
378 {.tags: [ReadDbEffect,WriteDbEffect], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
379 discard setupQuery(db, stmtName)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
380 var L = (column_count(stmtName.PStmt))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
381 var result = newRow(L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
382 try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
383 while step(stmtName.PStmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
384 setRow(stmtName.PStmt, result, L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
385 yield result
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
386 except:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
387 dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
388
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
389 iterator instantRows*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
390 args: varargs[string, `$`]): InstantRow
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
391 {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
392 ## Similar to `fastRows iterator <#fastRows.i,DbConn,SqlQuery,varargs[string,]>`_
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
393 ## but returns a handle that can be used to get column text
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
394 ## on demand using `[]`. Returned handle is valid only within the iterator body.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
395 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
396 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
397 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
398 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
399 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
400 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
401 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
402 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
403 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
404 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
405 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
406 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
407 ## for row in db.instantRows(sql"SELECT * FROM my_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
408 ## echo "id:" & row[0]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
409 ## echo "name:" & row[1]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
410 ## echo "length:" & $len(row)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
411 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
412 ## # Output:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
413 ## # id:1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
414 ## # name:item#1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
415 ## # length:2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
416 ## # id:2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
417 ## # name:item#2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
418 ## # length:2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
419 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
420 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
421 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
422 var stmt = setupQuery(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
423 try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
424 while step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
425 yield stmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
426 finally:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
427 if finalize(stmt) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
428
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
429 iterator instantRows*(db: DbConn, stmtName: SqlPrepared): InstantRow
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
430 {.tags: [ReadDbEffect,WriteDbEffect], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
431 var stmt = setupQuery(db, stmtName).PStmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
432 try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
433 while step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
434 yield stmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
435 except:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
436 dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
437
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
438 proc toTypeKind(t: var DbType; x: int32) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
439 case x
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
440 of SQLITE_INTEGER:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
441 t.kind = dbInt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
442 t.size = 8
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
443 of SQLITE_FLOAT:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
444 t.kind = dbFloat
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
445 t.size = 8
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
446 of SQLITE_BLOB: t.kind = dbBlob
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
447 of SQLITE_NULL: t.kind = dbNull
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
448 of SQLITE_TEXT: t.kind = dbVarchar
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
449 else: t.kind = dbUnknown
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
450
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
451 proc setColumns(columns: var DbColumns; x: PStmt) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
452 let L = column_count(x)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
453 setLen(columns, L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
454 for i in 0'i32 ..< L:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
455 columns[i].name = $column_name(x, i)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
456 columns[i].typ.name = $column_decltype(x, i)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
457 toTypeKind(columns[i].typ, column_type(x, i))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
458 columns[i].tableName = $column_table_name(x, i)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
459
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
460 iterator instantRows*(db: DbConn; columns: var DbColumns; query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
461 args: varargs[string, `$`]): InstantRow
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
462 {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
463 ## Similar to `instantRows iterator <#instantRows.i,DbConn,SqlQuery,varargs[string,]>`_,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
464 ## but sets information about columns to `columns`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
465 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
466 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
467 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
468 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
469 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
470 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
471 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
472 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
473 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
474 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
475 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
476 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
477 ## var columns: DbColumns
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
478 ## for row in db.instantRows(columns, sql"SELECT * FROM my_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
479 ## discard
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
480 ## echo columns[0]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
481 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
482 ## # Output:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
483 ## # (name: "id", tableName: "my_table", typ: (kind: dbNull,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
484 ## # notNull: false, name: "INTEGER", size: 0, maxReprLen: 0, precision: 0,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
485 ## # scale: 0, min: 0, max: 0, validValues: @[]), primaryKey: false,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
486 ## # foreignKey: false)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
487 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
488 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
489 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
490 var stmt = setupQuery(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
491 setColumns(columns, stmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
492 try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
493 while step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
494 yield stmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
495 finally:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
496 if finalize(stmt) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
497
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
498 proc `[]`*(row: InstantRow, col: int32): string {.inline.} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
499 ## Returns text for given column of the row.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
500 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
501 ## See also:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
502 ## * `instantRows iterator <#instantRows.i,DbConn,SqlQuery,varargs[string,]>`_
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
503 ## example code
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
504 $column_text(row, col)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
505
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
506 proc unsafeColumnAt*(row: InstantRow, index: int32): cstring {.inline.} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
507 ## Returns cstring for given column of the row.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
508 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
509 ## See also:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
510 ## * `instantRows iterator <#instantRows.i,DbConn,SqlQuery,varargs[string,]>`_
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
511 ## example code
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
512 column_text(row, index)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
513
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
514 proc len*(row: InstantRow): int32 {.inline.} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
515 ## Returns number of columns in a row.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
516 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
517 ## See also:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
518 ## * `instantRows iterator <#instantRows.i,DbConn,SqlQuery,varargs[string,]>`_
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
519 ## example code
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
520 column_count(row)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
521
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
522 proc getRow*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
523 args: varargs[string, `$`]): Row {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
524 ## Retrieves a single row. If the query doesn't return any rows, this proc
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
525 ## will return a `Row` with empty strings for each column.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
526 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
527 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
528 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
529 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
530 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
531 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
532 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
533 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
534 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
535 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
536 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
537 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
538 ## doAssert db.getRow(sql"SELECT id, name FROM my_table"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
539 ## ) == Row(@["1", "item#1"])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
540 ## doAssert db.getRow(sql"SELECT id, name FROM my_table WHERE id = ?",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
541 ## 2) == Row(@["2", "item#2"])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
542 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
543 ## # Returns empty.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
544 ## doAssert db.getRow(sql"INSERT INTO my_table (id, name) VALUES (?, ?)",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
545 ## 3, "item#3") == @[]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
546 ## doAssert db.getRow(sql"DELETE FROM my_table WHERE id = ?", 3) == @[]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
547 ## doAssert db.getRow(sql"UPDATE my_table SET name = 'ITEM#1' WHERE id = ?",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
548 ## 1) == @[]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
549 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
550 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
551 var stmt = setupQuery(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
552 var L = (column_count(stmt))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
553 result = newRow(L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
554 if step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
555 setRow(stmt, result, L)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
556 if finalize(stmt) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
557
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
558 proc getAllRows*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
559 args: varargs[string, `$`]): seq[Row] {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
560 ## Executes the query and returns the whole result dataset.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
561 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
562 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
563 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
564 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
565 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
566 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
567 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
568 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
569 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
570 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
571 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
572 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
573 ## doAssert db.getAllRows(sql"SELECT id, name FROM my_table") == @[Row(@["1", "item#1"]), Row(@["2", "item#2"])]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
574 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
575 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
576 result = @[]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
577 for r in fastRows(db, query, args):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
578 result.add(r)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
579
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
580 proc getAllRows*(db: DbConn, stmtName: SqlPrepared): seq[Row]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
581 {.tags: [ReadDbEffect,WriteDbEffect], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
582 result = @[]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
583 for r in fastRows(db, stmtName):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
584 result.add(r)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
585
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
586 iterator rows*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
587 args: varargs[string, `$`]): Row {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
588 ## Similar to `fastRows iterator <#fastRows.i,DbConn,SqlQuery,varargs[string,]>`_,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
589 ## but slower and safe.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
590 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
591 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
592 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
593 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
594 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
595 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
596 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
597 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
598 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
599 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
600 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
601 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
602 ## for row in db.rows(sql"SELECT id, name FROM my_table"):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
603 ## echo row
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
604 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
605 ## ## Output:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
606 ## ## @["1", "item#1"]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
607 ## ## @["2", "item#2"]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
608 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
609 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
610 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
611 for r in fastRows(db, query, args): yield r
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
612
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
613 iterator rows*(db: DbConn, stmtName: SqlPrepared): Row
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
614 {.tags: [ReadDbEffect,WriteDbEffect], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
615 for r in fastRows(db, stmtName): yield r
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
616
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
617 proc getValue*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
618 args: varargs[string, `$`]): string {.tags: [ReadDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
619 ## Executes the query and returns the first column of the first row of the
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
620 ## result dataset. Returns `""` if the dataset contains no rows or the database
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
621 ## value is `NULL`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
622 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
623 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
624 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
625 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
626 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
627 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
628 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
629 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
630 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
631 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
632 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
633 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
634 ## doAssert db.getValue(sql"SELECT name FROM my_table WHERE id = ?",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
635 ## 2) == "item#2"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
636 ## doAssert db.getValue(sql"SELECT id, name FROM my_table") == "1"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
637 ## doAssert db.getValue(sql"SELECT name, id FROM my_table") == "item#1"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
638 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
639 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
640 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
641 var stmt = setupQuery(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
642 if step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
643 let cb = column_bytes(stmt, 0)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
644 if cb == 0:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
645 result = ""
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
646 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
647 if column_type(stmt, 0) == SQLITE_BLOB:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
648 result.setLen(cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
649 copyMem(addr(result[0]), column_blob(stmt, 0), cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
650 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
651 result = newStringOfCap(cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
652 add(result, column_text(stmt, 0))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
653 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
654 result = ""
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
655 if finalize(stmt) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
656
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
657 proc getValue*(db: DbConn, stmtName: SqlPrepared): string
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
658 {.tags: [ReadDbEffect,WriteDbEffect], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
659 var stmt = setupQuery(db, stmtName).PStmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
660 if step(stmt) == SQLITE_ROW:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
661 let cb = column_bytes(stmt, 0)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
662 if cb == 0:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
663 result = ""
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
664 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
665 if column_type(stmt, 0) == SQLITE_BLOB:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
666 result.setLen(cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
667 copyMem(addr(result[0]), column_blob(stmt, 0), cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
668 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
669 result = newStringOfCap(cb)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
670 add(result, column_text(stmt, 0))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
671 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
672 result = ""
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
673
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
674 proc tryInsertID*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
675 args: varargs[string, `$`]): int64
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
676 {.tags: [WriteDbEffect], raises: [DbError].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
677 ## Executes the query (typically "INSERT") and returns the
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
678 ## generated ID for the row or -1 in case of an error.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
679 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
680 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
681 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
682 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
683 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
684 ## db.exec(sql"CREATE TABLE my_table (id INTEGER, name VARCHAR(50) NOT NULL)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
685 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
686 ## doAssert db.tryInsertID(sql"INSERT INTO not_exist_table (id, name) VALUES (?, ?)",
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
687 ## 1, "item#1") == -1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
688 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
689 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
690 assert(not db.isNil, "Database not connected.")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
691 var q = dbFormat(query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
692 var stmt: sqlite3.PStmt
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
693 result = -1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
694 if prepare_v2(db, q.cstring, q.len.cint, stmt, nil) == SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
695 if step(stmt) == SQLITE_DONE:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
696 result = last_insert_rowid(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
697 if finalize(stmt) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
698 result = -1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
699 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
700 discard finalize(stmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
701
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
702 proc insertID*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
703 args: varargs[string, `$`]): int64 {.tags: [WriteDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
704 ## Executes the query (typically "INSERT") and returns the
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
705 ## generated ID for the row.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
706 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
707 ## Raises a `DbError` exception when failed to insert row.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
708 ## For Postgre this adds `RETURNING id` to the query, so it only works
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
709 ## if your primary key is named `id`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
710 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
711 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
712 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
713 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
714 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
715 ## db.exec(sql"CREATE TABLE my_table (id INTEGER, name VARCHAR(50) NOT NULL)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
716 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
717 ## for i in 0..2:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
718 ## let id = db.insertID(sql"INSERT INTO my_table (id, name) VALUES (?, ?)", i, "item#" & $i)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
719 ## echo "LoopIndex = ", i, ", InsertID = ", id
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
720 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
721 ## # Output:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
722 ## # LoopIndex = 0, InsertID = 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
723 ## # LoopIndex = 1, InsertID = 2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
724 ## # LoopIndex = 2, InsertID = 3
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
725 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
726 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
727 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
728 result = tryInsertID(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
729 if result < 0: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
730
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
731 proc tryInsert*(db: DbConn, query: SqlQuery, pkName: string,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
732 args: varargs[string, `$`]): int64
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
733 {.tags: [WriteDbEffect], raises: [DbError], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
734 ## same as tryInsertID
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
735 tryInsertID(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
736
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
737 proc insert*(db: DbConn, query: SqlQuery, pkName: string,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
738 args: varargs[string, `$`]): int64
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
739 {.tags: [WriteDbEffect], since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
740 ## same as insertId
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
741 result = tryInsert(db, query, pkName, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
742 if result < 0: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
743
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
744 proc execAffectedRows*(db: DbConn, query: SqlQuery,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
745 args: varargs[string, `$`]): int64 {.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
746 tags: [ReadDbEffect, WriteDbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
747 ## Executes the query (typically "UPDATE") and returns the
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
748 ## number of affected rows.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
749 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
750 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
751 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
752 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
753 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
754 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
755 ## # Records of my_table:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
756 ## # | id | name |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
757 ## # |----|----------|
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
758 ## # | 1 | item#1 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
759 ## # | 2 | item#2 |
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
760 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
761 ## doAssert db.execAffectedRows(sql"UPDATE my_table SET name = 'TEST'") == 2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
762 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
763 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
764 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
765 exec(db, query, args)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
766 result = changes(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
767
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
768 proc execAffectedRows*(db: DbConn, stmtName: SqlPrepared): int64
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
769 {.tags: [ReadDbEffect, WriteDbEffect],since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
770 exec(db, stmtName)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
771 result = changes(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
772
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
773 proc close*(db: DbConn) {.tags: [DbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
774 ## Closes the database connection.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
775 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
776 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
777 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
778 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
779 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
780 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
781 if sqlite3.close(db) != SQLITE_OK: dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
782
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
783 proc open*(connection, user, password, database: string): DbConn {.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
784 tags: [DbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
785 ## Opens a database connection. Raises a `DbError` exception if the connection
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
786 ## could not be established.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
787 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
788 ## **Note:** Only the `connection` parameter is used for `sqlite`.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
789 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
790 ## **Examples:**
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
791 ## ```Nim
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
792 ## try:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
793 ## let db = open("mytest.db", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
794 ## ## do something...
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
795 ## ## db.getAllRows(sql"SELECT * FROM my_table")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
796 ## db.close()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
797 ## except:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
798 ## stderr.writeLine(getCurrentExceptionMsg())
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
799 ## ```
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
800 var db: DbConn
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
801 if sqlite3.open(connection, db) == SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
802 result = db
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
803 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
804 dbError(db)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
805
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
806 proc setEncoding*(connection: DbConn, encoding: string): bool {.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
807 tags: [DbEffect].} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
808 ## Sets the encoding of a database connection, returns `true` for
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
809 ## success, `false` for failure.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
810 ##
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
811 ## **Note:** The encoding cannot be changed once it's been set.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
812 ## According to SQLite3 documentation, any attempt to change
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
813 ## the encoding after the database is created will be silently
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
814 ## ignored.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
815 exec(connection, sql"PRAGMA encoding = ?", [encoding])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
816 result = connection.getValue(sql"PRAGMA encoding") == encoding
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
817
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
818 proc finalize*(sqlPrepared:SqlPrepared) {.discardable, since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
819 discard finalize(sqlPrepared.PStmt)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
820
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
821 template dbBindParamError*(paramIdx: int, val: varargs[untyped]) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
822 ## Raises a `DbError` exception.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
823 var e: ref DbError
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
824 new(e)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
825 e.msg = "error binding param in position " & $paramIdx
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
826 raise e
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
827
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
828 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: int32) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
829 ## Binds a int32 to the specified paramIndex.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
830 if bind_int(ps.PStmt, paramIdx.int32, val) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
831 dbBindParamError(paramIdx, val)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
832
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
833 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: int64) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
834 ## Binds a int64 to the specified paramIndex.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
835 if bind_int64(ps.PStmt, paramIdx.int32, val) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
836 dbBindParamError(paramIdx, val)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
837
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
838 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: int) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
839 ## Binds a int to the specified paramIndex.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
840 when sizeof(int) == 8:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
841 bindParam(ps, paramIdx, val.int64)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
842 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
843 bindParam(ps, paramIdx, val.int32)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
844
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
845 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: float64) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
846 ## Binds a 64bit float to the specified paramIndex.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
847 if bind_double(ps.PStmt, paramIdx.int32, val) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
848 dbBindParamError(paramIdx, val)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
849
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
850 proc bindNull*(ps: SqlPrepared, paramIdx: int) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
851 ## Sets the bindparam at the specified paramIndex to null
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
852 ## (default behaviour by sqlite).
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
853 if bind_null(ps.PStmt, paramIdx.int32) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
854 dbBindParamError(paramIdx)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
855
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
856 proc bindParam*(ps: SqlPrepared, paramIdx: int, val: string, copy = true) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
857 ## Binds a string to the specified paramIndex.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
858 ## if copy is true then SQLite makes its own private copy of the data immediately
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
859 if bind_text(ps.PStmt, paramIdx.int32, val.cstring, val.len.int32, if copy: SQLITE_TRANSIENT else: SQLITE_STATIC) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
860 dbBindParamError(paramIdx, val)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
861
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
862 proc bindParam*(ps: SqlPrepared, paramIdx: int,val: openArray[byte], copy = true) {.since: (1, 3).} =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
863 ## binds a blob to the specified paramIndex.
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
864 ## if copy is true then SQLite makes its own private copy of the data immediately
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
865 let len = val.len
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
866 if bind_blob(ps.PStmt, paramIdx.int32, val[0].unsafeAddr, len.int32, if copy: SQLITE_TRANSIENT else: SQLITE_STATIC) != SQLITE_OK:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
867 dbBindParamError(paramIdx, val)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
868
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
869 when not defined(testing) and isMainModule:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
870 var db = open(":memory:", "", "", "")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
871 exec(db, sql"create table tbl1(one varchar(10), two smallint)", [])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
872 exec(db, sql"insert into tbl1 values('hello!',10)", [])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
873 exec(db, sql"insert into tbl1 values('goodbye', 20)", [])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
874 var p1 = db.prepare "create table tbl2(one varchar(10), two smallint)"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
875 exec(db, p1)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
876 finalize(p1)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
877 var p2 = db.prepare "insert into tbl2 values('hello!',10)"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
878 exec(db, p2)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
879 finalize(p2)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
880 var p3 = db.prepare "insert into tbl2 values('goodbye', 20)"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
881 exec(db, p3)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
882 finalize(p3)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
883 #db.query("create table tbl1(one varchar(10), two smallint)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
884 #db.query("insert into tbl1 values('hello!',10)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
885 #db.query("insert into tbl1 values('goodbye', 20)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
886 for r in db.rows(sql"select * from tbl1", []):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
887 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
888 for r in db.instantRows(sql"select * from tbl1", []):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
889 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
890 var p4 = db.prepare "select * from tbl2"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
891 for r in db.rows(p4):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
892 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
893 finalize(p4)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
894 var i5 = 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
895 var p5 = db.prepare "select * from tbl2"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
896 for r in db.instantRows(p5):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
897 inc i5
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
898 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
899 assert i5 == 2
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
900 finalize(p5)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
901
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
902 for r in db.rows(sql"select * from tbl2", []):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
903 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
904 for r in db.instantRows(sql"select * from tbl2", []):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
905 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
906 var p6 = db.prepare "select * from tbl2 where one = ? "
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
907 p6.bindParams("goodbye")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
908 var rowsP3 = 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
909 for r in db.rows(p6):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
910 rowsP3 = 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
911 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
912 assert rowsP3 == 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
913 finalize(p6)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
914
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
915 var p7 = db.prepare "select * from tbl2 where two=?"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
916 p7.bindParams(20'i32)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
917 when sizeof(int) == 4:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
918 p7.bindParams(20)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
919 var rowsP = 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
920 for r in db.rows(p7):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
921 rowsP = 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
922 echo(r[0], r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
923 assert rowsP == 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
924 finalize(p7)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
925
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
926 exec(db, sql"CREATE TABLE photos(ID INTEGER PRIMARY KEY AUTOINCREMENT, photo BLOB)")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
927 var p8 = db.prepare "INSERT INTO photos (ID,PHOTO) VALUES (?,?)"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
928 var d = "abcdefghijklmnopqrstuvwxyz"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
929 p8.bindParams(1'i32, "abcdefghijklmnopqrstuvwxyz")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
930 exec(db, p8)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
931 finalize(p8)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
932 var p10 = db.prepare "INSERT INTO photos (ID,PHOTO) VALUES (?,?)"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
933 p10.bindParams(2'i32,nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
934 exec(db, p10)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
935 exec( db, p10, 3, nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
936 finalize(p10)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
937 for r in db.rows(sql"select * from photos where ID = 1", []):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
938 assert r[1].len == d.len
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
939 assert r[1] == d
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
940 var i6 = 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
941 for r in db.rows(sql"select * from photos where ID = 3", []):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
942 i6 = 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
943 assert i6 == 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
944 var p9 = db.prepare("select * from photos where PHOTO is ?")
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
945 p9.bindParams(nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
946 var rowsP2 = 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
947 for r in db.rows(p9):
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
948 rowsP2 = 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
949 echo(r[0], repr r[1])
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
950 assert rowsP2 == 1
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
951 finalize(p9)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
952
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
953 db_sqlite.close(db)