@@ -131,7 +131,7 @@ pub fn connect(path string) !DB {
131131 code := C.sqlite3_open (& char (path.str), & db)
132132 if code != 0 {
133133 return & SQLError{
134- msg: unsafe { cstring_to_vstring (& char (C.sqlite3_errstr (code ))) }
134+ msg: unsafe { cstring_to_vstring (& char (C.sqlite3_errmsg (db ))) }
135135 code: code
136136 }
137137 }
@@ -150,7 +150,7 @@ pub fn (mut db DB) close() !bool {
150150 db.is_open = false
151151 } else {
152152 return & SQLError{
153- msg: unsafe { cstring_to_vstring (& char (C.sqlite3_errstr (code ))) }
153+ msg: unsafe { cstring_to_vstring (& char (C.sqlite3_errmsg (db.conn ))) }
154154 code: code
155155 }
156156 }
@@ -180,41 +180,50 @@ pub fn (db &DB) get_affected_rows_count() int {
180180 return C.sqlite3_changes (db.conn)
181181}
182182
183- // q_int returns a single integer value, from the first column of the result of executing `query`
184- pub fn (db &DB) q_int (query string ) int {
183+ // q_int returns a single integer value, from the first column of the result of executing `query`, or an error on failure
184+ pub fn (db &DB) q_int (query string ) ! int {
185185 stmt := & C.sqlite3_stmt (unsafe { nil })
186186 defer {
187187 C.sqlite3_finalize (stmt)
188188 }
189189 C.sqlite3_prepare_v2 (db.conn, & char (query.str), query.len, & stmt, 0 )
190- C.sqlite3_step (stmt)
190+ code := C.sqlite3_step (stmt)
191+ if code != sqlite.sqlite_row {
192+ return db.error_message (code, query)
193+ }
191194
192195 res := C.sqlite3_column_int (stmt, 0 )
193196 return res
194197}
195198
196- // q_string returns a single string value, from the first column of the result of executing `query`
197- pub fn (db &DB) q_string (query string ) string {
199+ // q_string returns a single string value, from the first column of the result of executing `query`, or an error on failure
200+ pub fn (db &DB) q_string (query string ) ! string {
198201 stmt := & C.sqlite3_stmt (unsafe { nil })
199202 defer {
200203 C.sqlite3_finalize (stmt)
201204 }
202205 C.sqlite3_prepare_v2 (db.conn, & char (query.str), query.len, & stmt, 0 )
203- C.sqlite3_step (stmt)
206+ code := C.sqlite3_step (stmt)
207+ if code != sqlite.sqlite_row {
208+ return db.error_message (code, query)
209+ }
204210
205211 val := unsafe { & u8 (C.sqlite3_column_text (stmt, 0 )) }
206212 return if val != & u8 (0 ) { unsafe { tos_clone (val) } } else { '' }
207213}
208214
209- // exec executes the query on the given `db`, and returns an array of all the results, alongside any result code.
210- // Result codes: https://www.sqlite.org/rescode.html
215+ // exec executes the query on the given `db`, and returns an array of all the results, or an error on failure
211216[manualfree ]
212- pub fn (db &DB) exec (query string ) ( []Row, int ) {
217+ pub fn (db &DB) exec (query string ) ! []Row {
213218 stmt := & C.sqlite3_stmt (unsafe { nil })
214219 defer {
215220 C.sqlite3_finalize (stmt)
216221 }
217- C.sqlite3_prepare_v2 (db.conn, & char (query.str), query.len, & stmt, 0 )
222+ mut code := C.sqlite3_prepare_v2 (db.conn, & char (query.str), query.len, & stmt, 0 )
223+ if code != sqlite.sqlite_ok {
224+ return db.error_message (code, query)
225+ }
226+
218227 nr_cols := C.sqlite3_column_count (stmt)
219228 mut res := 0
220229 mut rows := []Row{}
@@ -236,26 +245,21 @@ pub fn (db &DB) exec(query string) ([]Row, int) {
236245 }
237246 rows << row
238247 }
239- return rows, res
248+ return rows
240249}
241250
242251// exec_one executes a query on the given `db`.
243252// It returns either the first row from the result, if the query was successful, or an error.
244253[manualfree ]
245254pub fn (db &DB) exec_one (query string ) ! Row {
246- rows , code := db.exec (query)
255+ rows := db.exec (query)!
247256 defer {
248257 unsafe { rows.free () }
249258 }
250259 if rows.len == 0 {
251260 return & SQLError{
252261 msg: 'No rows'
253- code: code
254- }
255- } else if code != 101 {
256- return & SQLError{
257- msg: unsafe { cstring_to_vstring (& char (C.sqlite3_errstr (code))) }
258- code: code
262+ code: sqlite.sqlite_done
259263 }
260264 }
261265 res := rows[0 ]
@@ -295,21 +299,13 @@ pub fn (db &DB) exec_param_many(query string, params []string) ![]Row {
295299
296300 mut code := C.sqlite3_prepare_v2 (db.conn, & char (query.str), - 1 , & stmt, 0 )
297301 if code != 0 {
298- return & SQLError{
299- msg: unsafe {
300- cstring_to_vstring (& char (C.sqlite3_errstr (code)))
301- }
302- code: code
303- }
302+ return db.error_message (code, query)
304303 }
305304
306305 for i, param in params {
307306 code = C.sqlite3_bind_text (stmt, i + 1 , voidptr (param.str), param.len, 0 )
308307 if code != 0 {
309- return & SQLError{
310- msg: unsafe { cstring_to_vstring (& char (C.sqlite3_errstr (code))) }
311- code: code
312- }
308+ return db.error_message (code, query)
313309 }
314310 }
315311
@@ -345,8 +341,8 @@ pub fn (db &DB) exec_param(query string, param string) ![]Row {
345341// create_table issues a "create table if not exists" command to the db.
346342// It creates the table named 'table_name', with columns generated from 'columns' array.
347343// The default columns type will be TEXT.
348- pub fn (db &DB) create_table (table_name string , columns []string ) {
349- db.exec ('create table if not exists ${table_name} (' + columns.join (',\n ' ) + ')' )
344+ pub fn (db &DB) create_table (table_name string , columns []string ) ! {
345+ db.exec ('create table if not exists ${table_name} (' + columns.join (',\n ' ) + ')' )!
350346}
351347
352348// busy_timeout sets a busy timeout in milliseconds.
@@ -359,37 +355,39 @@ pub fn (db &DB) busy_timeout(ms int) int {
359355
360356// synchronization_mode sets disk synchronization mode, which controls how
361357// aggressively SQLite will write data to physical storage.
358+ // If the command fails to execute an error is returned
362359// .off: No syncs at all. (fastest)
363360// .normal: Sync after each sequence of critical disk operations.
364361// .full: Sync after each critical disk operation (slowest).
365- pub fn (db &DB) synchronization_mode (sync_mode SyncMode) {
362+ pub fn (db &DB) synchronization_mode (sync_mode SyncMode) ! {
366363 if sync_mode == .off {
367- db.exec ('pragma synchronous = OFF;' )
364+ db.exec ('pragma synchronous = OFF;' )!
368365 } else if sync_mode == .full {
369- db.exec ('pragma synchronous = FULL;' )
366+ db.exec ('pragma synchronous = FULL;' )!
370367 } else {
371- db.exec ('pragma synchronous = NORMAL;' )
368+ db.exec ('pragma synchronous = NORMAL;' )!
372369 }
373370}
374371
375372// journal_mode controls how the journal file is stored and processed.
373+ // If the command fails to execute an error is returned
376374// .off: No journal record is kept. (fastest)
377375// .memory: Journal record is held in memory, rather than on disk.
378376// .delete: At the conclusion of a transaction, journal file is deleted.
379377// .truncate: Journal file is truncated to a length of zero bytes.
380378// .persist: Journal file is left in place, but the header is overwritten to indicate journal is no longer valid.
381- pub fn (db &DB) journal_mode (journal_mode JournalMode) {
379+ pub fn (db &DB) journal_mode (journal_mode JournalMode) ! {
382380 if journal_mode == .off {
383- db.exec ('pragma journal_mode = OFF;' )
381+ db.exec ('pragma journal_mode = OFF;' )!
384382 } else if journal_mode == .delete {
385- db.exec ('pragma journal_mode = DELETE;' )
383+ db.exec ('pragma journal_mode = DELETE;' )!
386384 } else if journal_mode == .truncate {
387- db.exec ('pragma journal_mode = TRUNCATE;' )
385+ db.exec ('pragma journal_mode = TRUNCATE;' )!
388386 } else if journal_mode == .persist {
389- db.exec ('pragma journal_mode = PERSIST;' )
387+ db.exec ('pragma journal_mode = PERSIST;' )!
390388 } else if journal_mode == .memory {
391- db.exec ('pragma journal_mode = MEMORY;' )
389+ db.exec ('pragma journal_mode = MEMORY;' )!
392390 } else {
393- db.exec ('pragma journal_mode = MEMORY;' )
391+ db.exec ('pragma journal_mode = MEMORY;' )!
394392 }
395393}
0 commit comments