sqlite3.scm.in 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. ;; Guile-SQLite3
  2. ;; Copyright (C) 2010, 2014 Andy Wingo <wingo at pobox dot com>
  3. ;; Copyright (C) 2018 Ludovic Courtès <ludo@gnu.org>
  4. ;; Copyright (C) 2020 Mathieu Othacehe <othacehe@gnu.org>
  5. ;; This library is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU Lesser General Public License as
  7. ;; published by the Free Software Foundation; either version 3 of the
  8. ;; License, or (at your option) any later version.
  9. ;;
  10. ;; This library is distributed in the hope that it will be useful, but
  11. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;; Lesser General Public License for more details.
  14. ;;
  15. ;; You should have received a copy of the GNU Lesser General Public
  16. ;; License along with this program; if not, contact:
  17. ;;
  18. ;; Free Software Foundation Voice: +1-617-542-5942
  19. ;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
  20. ;; Boston, MA 02111-1307, USA gnu@gnu.org
  21. ;;; Commentary:
  22. ;;
  23. ;; A Guile binding for sqlite.
  24. ;;
  25. ;;; Code:
  26. (define-module (sqlite3)
  27. #:use-module (system foreign)
  28. #:use-module (rnrs bytevectors)
  29. #:use-module (ice-9 match)
  30. #:use-module (srfi srfi-1)
  31. #:use-module (srfi srfi-9)
  32. #:use-module (srfi srfi-19)
  33. #:export (sqlite-open
  34. sqlite-db?
  35. sqlite-close
  36. sqlite-enable-load-extension
  37. sqlite-exec
  38. sqlite-prepare
  39. sqlite-bind
  40. sqlite-bind-arguments
  41. sqlite-column-names
  42. sqlite-step
  43. sqlite-fold
  44. sqlite-fold-right
  45. sqlite-map
  46. sqlite-reset
  47. sqlite-finalize
  48. sqlite-bind-parameter-index
  49. sqlite-busy-timeout
  50. sqlite-expanded-sql
  51. sqlite-trace
  52. SQLITE_OPEN_READONLY
  53. SQLITE_OPEN_READWRITE
  54. SQLITE_OPEN_CREATE
  55. SQLITE_OPEN_DELETEONCLOSE
  56. SQLITE_OPEN_EXCLUSIVE
  57. SQLITE_OPEN_MAIN_DB
  58. SQLITE_OPEN_TEMP_DB
  59. SQLITE_OPEN_TRANSIENT_DB
  60. SQLITE_OPEN_MAIN_JOURNAL
  61. SQLITE_OPEN_TEMP_JOURNAL
  62. SQLITE_OPEN_SUBJOURNAL
  63. SQLITE_OPEN_MASTER_JOURNAL
  64. SQLITE_OPEN_NOMUTEX
  65. SQLITE_OPEN_FULLMUTEX
  66. SQLITE_OPEN_SHAREDCACHE
  67. SQLITE_OPEN_PRIVATECACHE
  68. SQLITE_OPEN_URI
  69. SQLITE_TRACE_STMT
  70. SQLITE_TRACE_PROFILE
  71. SQLITE_TRACE_ROW
  72. SQLITE_TRACE_CLOSE
  73. SQLITE_CONSTRAINT
  74. SQLITE_CONSTRAINT_PRIMARYKEY
  75. SQLITE_CONSTRAINT_UNIQUE))
  76. ;;
  77. ;; Utils
  78. ;;
  79. (define (string->utf8-pointer s)
  80. (string->pointer s "utf-8"))
  81. (define (utf8-pointer->string p)
  82. (pointer->string p -1 "utf-8"))
  83. ;;
  84. ;; Constants
  85. ;;
  86. ;; FIXME: snarf using compiler. These are just copied from the header...
  87. ;;
  88. (define SQLITE_OPEN_READONLY #x00000001) ;; Ok for sqlite3_open_v2()
  89. (define SQLITE_OPEN_READWRITE #x00000002) ;; Ok for sqlite3_open_v2()
  90. (define SQLITE_OPEN_CREATE #x00000004) ;; Ok for sqlite3_open_v2()
  91. (define SQLITE_OPEN_DELETEONCLOSE #x00000008) ;; VFS only
  92. (define SQLITE_OPEN_EXCLUSIVE #x00000010) ;; VFS only
  93. (define SQLITE_OPEN_MAIN_DB #x00000100) ;; VFS only
  94. (define SQLITE_OPEN_TEMP_DB #x00000200) ;; VFS only
  95. (define SQLITE_OPEN_TRANSIENT_DB #x00000400) ;; VFS only
  96. (define SQLITE_OPEN_MAIN_JOURNAL #x00000800) ;; VFS only
  97. (define SQLITE_OPEN_TEMP_JOURNAL #x00001000) ;; VFS only
  98. (define SQLITE_OPEN_SUBJOURNAL #x00002000) ;; VFS only
  99. (define SQLITE_OPEN_MASTER_JOURNAL #x00004000) ;; VFS only
  100. (define SQLITE_OPEN_NOMUTEX #x00008000) ;; Ok for sqlite3_open_v2()
  101. (define SQLITE_OPEN_FULLMUTEX #x00010000) ;; Ok for sqlite3_open_v2()
  102. (define SQLITE_OPEN_SHAREDCACHE #x00020000) ;; Ok for sqlite3_open_v2()
  103. (define SQLITE_OPEN_PRIVATECACHE #x00040000) ;; Ok for sqlite3_open_v2()
  104. (define SQLITE_OPEN_URI #x00000040) ;; Ok for sqlite3_open_v2()
  105. (define SQLITE_TRACE_STMT #x00000001)
  106. (define SQLITE_TRACE_PROFILE #x00000002)
  107. (define SQLITE_TRACE_ROW #x00000004)
  108. (define SQLITE_TRACE_CLOSE #x00000008)
  109. (define SQLITE_CONSTRAINT 19)
  110. (define SQLITE_CONSTRAINT_PRIMARYKEY
  111. (logior SQLITE_CONSTRAINT (ash 6 8)))
  112. (define SQLITE_CONSTRAINT_UNIQUE
  113. (logior SQLITE_CONSTRAINT (ash 8 8)))
  114. (define libsqlite3 (dynamic-link "@SQLITE_LIBDIR@/libsqlite3"))
  115. (define-record-type <sqlite-db>
  116. (make-db pointer open? stmts)
  117. db?
  118. (pointer db-pointer)
  119. (open? db-open? set-db-open?!)
  120. (stmts db-stmts))
  121. (define-syntax sqlite-db?
  122. (identifier-syntax db?))
  123. (define-record-type <sqlite-stmt>
  124. (make-stmt pointer live? reset? cached?)
  125. stmt?
  126. (pointer stmt-pointer)
  127. (live? stmt-live? set-stmt-live?!)
  128. (reset? stmt-reset? set-stmt-reset?!)
  129. (cached? stmt-cached? set-stmt-cached?!))
  130. (define sqlite-errmsg
  131. (let ((f (pointer->procedure
  132. '*
  133. (dynamic-func "sqlite3_errmsg" libsqlite3)
  134. (list '*))))
  135. (lambda (db)
  136. (utf8-pointer->string (f (db-pointer db))))))
  137. (define sqlite-errcode
  138. (let ((f (pointer->procedure
  139. int
  140. (dynamic-func "sqlite3_extended_errcode" libsqlite3)
  141. (list '*))))
  142. (lambda (db)
  143. (f (db-pointer db)))))
  144. (define* (sqlite-error db who #:optional code
  145. (errmsg (and db (sqlite-errmsg db))))
  146. (throw 'sqlite-error who code errmsg))
  147. (define* (check-error db #:optional who)
  148. (let ((code (sqlite-errcode db)))
  149. (if (not (zero? code))
  150. (sqlite-error db who code))))
  151. (define sqlite-close
  152. (let ((f (pointer->procedure
  153. int
  154. (dynamic-func "sqlite3_close" libsqlite3)
  155. (list '*))))
  156. (lambda (db)
  157. (when (db-open? db)
  158. ;; Finalize cached statements.
  159. (hash-for-each (lambda (sql stmt)
  160. (set-stmt-cached?! stmt #f)
  161. (sqlite-finalize stmt))
  162. (db-stmts db))
  163. (hash-clear! (db-stmts db))
  164. (let ((p (db-pointer db)))
  165. (set-db-open?! db #f)
  166. (f p))))))
  167. (define db-guardian (make-guardian))
  168. (define (pump-db-guardian)
  169. (let ((db (db-guardian)))
  170. (if db
  171. (begin
  172. (sqlite-close db)
  173. (pump-db-guardian)))))
  174. (add-hook! after-gc-hook pump-db-guardian)
  175. (define (static-errcode->errmsg code)
  176. (case code
  177. ((1) "SQL error or missing database")
  178. ((2) "Internal logic error in SQLite")
  179. ((3) "Access permission denied")
  180. ((5) "The database file is locked")
  181. ((6) "A table in the database is locked")
  182. ((7) "A malloc() failed")
  183. ((8) "Attempt to write a readonly database")
  184. ((10) "Some kind of disk I/O error occurred")
  185. ((11) "The database disk image is malformed")
  186. ((14) "Unable to open the database file")
  187. ((21) "Library used incorrectly")
  188. ((22) "Uses OS features not supported on host")
  189. ((23) "Authorization denied")
  190. ((24) "Auxiliary database format error")
  191. ((26) "File opened that is not a database file")
  192. (else "Unknown error")))
  193. (define sqlite-open
  194. (let ((f (pointer->procedure
  195. int
  196. (dynamic-func "sqlite3_open_v2" libsqlite3)
  197. (list '* '* int '*))))
  198. (lambda* (filename #:optional
  199. (flags (logior SQLITE_OPEN_READWRITE
  200. SQLITE_OPEN_CREATE
  201. SQLITE_OPEN_URI))
  202. (vfs #f))
  203. (let* ((out-db (bytevector->pointer (make-bytevector (sizeof '*) 0)))
  204. (ret (f (string->utf8-pointer filename)
  205. out-db
  206. flags
  207. (if vfs (string->utf8-pointer vfs) %null-pointer))))
  208. (if (zero? ret)
  209. (let ((db (make-db (dereference-pointer out-db) #t
  210. (make-hash-table))))
  211. (db-guardian db)
  212. db)
  213. (sqlite-error #f 'sqlite-open ret (static-errcode->errmsg ret)))))))
  214. (define sqlite-enable-load-extension
  215. (let ((ele (pointer->procedure
  216. int
  217. (dynamic-func "sqlite3_enable_load_extension" libsqlite3)
  218. (list '* int))))
  219. (lambda (db onoff)
  220. (ele (db-pointer db) onoff))))
  221. (define sqlite-exec
  222. (let ((exec (pointer->procedure
  223. int
  224. (dynamic-func "sqlite3_exec" (@@ (sqlite3) libsqlite3))
  225. '(* * * * *))))
  226. (lambda* (db sql)
  227. "Evaluate the string SQL, which may contain one or several SQL
  228. statements, into DB. The result is unspecified."
  229. ;; XXX: 'sqlite3_exec' has a 'callback' parameter but we ignore it
  230. ;; here.
  231. (assert-live-db! db)
  232. (unless (zero? (exec (db-pointer db) (string->pointer sql)
  233. %null-pointer %null-pointer %null-pointer))
  234. (check-error db 'sqlite-exec)))))
  235. ;;;
  236. ;;; SQL statements
  237. ;;;
  238. (define sqlite-remove-statement!
  239. (lambda (db stmt)
  240. (when (stmt-cached? stmt)
  241. (let* ((stmts (db-stmts db))
  242. (key (catch 'value
  243. (lambda ()
  244. (hash-for-each (lambda (key value)
  245. (when (eq? value stmt)
  246. (throw 'value key)))
  247. stmts)
  248. #f)
  249. (lambda (_ key) key))))
  250. (hash-remove! stmts key)))))
  251. (define sqlite-finalize
  252. (let ((f (pointer->procedure
  253. int
  254. (dynamic-func "sqlite3_finalize" libsqlite3)
  255. (list '*))))
  256. (lambda (stmt)
  257. ;; Note: When STMT is cached, this merely resets. This ensures caching
  258. ;; actually works while still separating concerns: users can turn caching
  259. ;; on and off without having to change the rest of their code.
  260. (when (stmt-live? stmt)
  261. (if (stmt-cached? stmt)
  262. ;; It's necessary to reset cached statements due to the following:
  263. ;;
  264. ;; "An implicit transaction (a transaction that is started
  265. ;; automatically, not a transaction started by BEGIN) is committed
  266. ;; automatically when the last active statement finishes. A statement
  267. ;; finishes when its last cursor closes, which is guaranteed to happen
  268. ;; when the prepared statement is reset or finalized. Some statements
  269. ;; might "finish" for the purpose of transaction control prior to
  270. ;; being reset or finalized, but there is no guarantee of this."
  271. ;;
  272. ;; (see https://www.sqlite.org/lang_transaction.html)
  273. ;;
  274. ;; Thus, it's possible for an implicitly-started transaction to hang
  275. ;; around until sqlite-reset is called when the cached statement is
  276. ;; next used. Because the transaction is committed automatically only
  277. ;; when the *last active statement* finishes, the implicitly-started
  278. ;; transaction may later be upgraded to a write transaction (!) and
  279. ;; this non-reset statement will still be keeping the transaction from
  280. ;; committing until it is next used or the database connection is
  281. ;; closed. This has the potential to make (exclusive) write access to
  282. ;; the database necessary for much longer than it should be.
  283. ;;
  284. ;; So it's necessary to preserve the statement-finishing behavior of
  285. ;; sqlite_finalize here, which we do by calling sqlite-reset.
  286. (sqlite-reset stmt)
  287. (let ((p (stmt-pointer stmt)))
  288. (sqlite-remove-statement! (stmt->db stmt) stmt)
  289. (set-stmt-live?! stmt #f)
  290. (f p)))))))
  291. (define *stmt-map* (make-weak-key-hash-table))
  292. (define (stmt->db stmt)
  293. (hashq-ref *stmt-map* stmt))
  294. (define stmt-guardian (make-guardian))
  295. (define (pump-stmt-guardian)
  296. (let ((stmt (stmt-guardian)))
  297. (if stmt
  298. (begin
  299. (sqlite-finalize stmt)
  300. (pump-stmt-guardian)))))
  301. (add-hook! after-gc-hook pump-stmt-guardian)
  302. (define sqlite-reset
  303. (let ((reset (pointer->procedure
  304. int
  305. (dynamic-func "sqlite3_reset" libsqlite3)
  306. (list '*))))
  307. (lambda (stmt)
  308. (if (stmt-live? stmt)
  309. (let ((p (stmt-pointer stmt)))
  310. (set-stmt-reset?! stmt #t)
  311. (reset p))
  312. (error "statement already finalized" stmt)))))
  313. (define (assert-live-stmt! stmt)
  314. (if (not (stmt-live? stmt))
  315. (error "statement already finalized" stmt)))
  316. (define (assert-live-db! db)
  317. (if (not (db-open? db))
  318. (error "database already closed" db)))
  319. (define %sqlite-prepare
  320. (let ((prepare (pointer->procedure
  321. int
  322. (dynamic-func "sqlite3_prepare_v2" libsqlite3)
  323. (list '* '* int '* '*))))
  324. (lambda* (db sql #:key cache?)
  325. (assert-live-db! db)
  326. (let* ((out-stmt (bytevector->pointer (make-bytevector (sizeof '*) 0)))
  327. (out-tail (bytevector->pointer (make-bytevector (sizeof '*) 0)))
  328. (bv (string->utf8 sql))
  329. (bvp (bytevector->pointer bv))
  330. (ret (prepare (db-pointer db)
  331. bvp
  332. (bytevector-length bv)
  333. out-stmt
  334. out-tail)))
  335. (if (zero? ret)
  336. (if (= (bytevector-length bv)
  337. (- (pointer-address (dereference-pointer out-tail))
  338. (pointer-address bvp)))
  339. (let ((stmt (make-stmt (dereference-pointer out-stmt) #t #t
  340. cache?)))
  341. (stmt-guardian stmt)
  342. (hashq-set! *stmt-map* stmt db)
  343. stmt)
  344. (error "input sql has useless tail"
  345. (utf8-pointer->string
  346. (dereference-pointer out-tail))))
  347. (check-error db 'sqlite-prepare))))))
  348. (define* (sqlite-prepare db sql #:key cache?)
  349. (if cache?
  350. (match (hash-ref (db-stmts db) sql)
  351. (#f
  352. (let ((stmt (%sqlite-prepare db sql #:cache? #t)))
  353. (hash-set! (db-stmts db) sql stmt)
  354. stmt))
  355. (stmt
  356. (sqlite-reset stmt)
  357. stmt))
  358. (%sqlite-prepare db sql)))
  359. (define sqlite-bind-parameter-index
  360. (let ((bind-parameter-index (pointer->procedure
  361. int
  362. (dynamic-func "sqlite3_bind_parameter_index" libsqlite3)
  363. (list '* '*))))
  364. (lambda (stmt name)
  365. (assert-live-stmt! stmt)
  366. (let* ((ret (bind-parameter-index (stmt-pointer stmt)
  367. (string->utf8-pointer name))))
  368. (if (> ret 0)
  369. ret
  370. (begin
  371. (check-error (stmt->db stmt) 'sqlite-bind-parameter-index)
  372. (write ret)
  373. (newline)
  374. (error "No such parameter" name)))))))
  375. (define key->index
  376. (lambda (stmt key)
  377. (cond
  378. ((string? key) (sqlite-bind-parameter-index stmt key))
  379. ((symbol? key) (sqlite-bind-parameter-index stmt
  380. (string-append ":" (symbol->string key))))
  381. (else key))))
  382. (define sqlite-bind
  383. (let ((bind-blob (pointer->procedure
  384. int
  385. (dynamic-func "sqlite3_bind_blob" libsqlite3)
  386. (list '* int '* int '*)))
  387. (bind-text (pointer->procedure
  388. int
  389. (dynamic-func "sqlite3_bind_text" libsqlite3)
  390. (list '* int '* int '*)))
  391. (bind-int64 (pointer->procedure
  392. int
  393. (dynamic-func "sqlite3_bind_int64" libsqlite3)
  394. (list '* int int64)))
  395. (bind-double (pointer->procedure
  396. int
  397. (dynamic-func "sqlite3_bind_double" libsqlite3)
  398. (list '* int double)))
  399. (bind-null (pointer->procedure
  400. int
  401. (dynamic-func "sqlite3_bind_null" libsqlite3)
  402. (list '* int)))
  403. (sqlite-transient (make-pointer
  404. (bit-extract (lognot 0) 0 (* 8 (sizeof '*))))))
  405. (lambda (stmt key val)
  406. (assert-live-stmt! stmt)
  407. (let ((idx (key->index stmt key))
  408. (p (stmt-pointer stmt)))
  409. (cond
  410. ((bytevector? val)
  411. (bind-blob p idx (bytevector->pointer val) (bytevector-length val)
  412. sqlite-transient))
  413. ((string? val)
  414. (let ((bv (string->utf8 val)))
  415. (bind-text p idx (bytevector->pointer bv) (bytevector-length bv)
  416. sqlite-transient)))
  417. ((and (integer? val) (exact? val))
  418. (bind-int64 p idx val))
  419. ((number? val)
  420. (bind-double p idx (exact->inexact val)))
  421. ((not val)
  422. (bind-null p idx))
  423. (else
  424. (error "unexpected value" val)))
  425. (check-error (stmt->db stmt))))))
  426. (define (sqlite-bind-arguments stmt . args)
  427. "Bind STMT parameters, one after another, to ARGS.
  428. Also bind named parameters to the respective ones."
  429. (let loop ((i 1)
  430. (args args))
  431. (match args
  432. (()
  433. #f)
  434. (((? keyword? kw) value . rest)
  435. (sqlite-bind stmt (keyword->symbol kw) value)
  436. (loop i rest))
  437. ((arg . rest)
  438. (sqlite-bind stmt i arg)
  439. (loop (+ 1 i) rest)))))
  440. (define sqlite-column-count
  441. (let ((column-count
  442. (pointer->procedure
  443. int
  444. (dynamic-pointer "sqlite3_column_count" libsqlite3)
  445. (list '*))))
  446. (lambda (stmt)
  447. (assert-live-stmt! stmt)
  448. (column-count (stmt-pointer stmt)))))
  449. (define sqlite-column-name
  450. (let ((column-name
  451. (pointer->procedure
  452. '*
  453. (dynamic-pointer "sqlite3_column_name" libsqlite3)
  454. (list '* int))))
  455. (lambda (stmt i)
  456. (assert-live-stmt! stmt)
  457. (utf8-pointer->string (column-name (stmt-pointer stmt) i)))))
  458. (define sqlite-column-value
  459. (let ((value-type
  460. (pointer->procedure
  461. int
  462. (dynamic-pointer "sqlite3_column_type" libsqlite3)
  463. (list '* int)))
  464. (value-int
  465. (pointer->procedure
  466. int64
  467. (dynamic-pointer "sqlite3_column_int64" libsqlite3)
  468. (list '* int)))
  469. (value-double
  470. (pointer->procedure
  471. double
  472. (dynamic-pointer "sqlite3_column_double" libsqlite3)
  473. (list '* int)))
  474. (value-text
  475. (pointer->procedure
  476. '*
  477. (dynamic-pointer "sqlite3_column_text" libsqlite3)
  478. (list '* int)))
  479. (value-blob
  480. (pointer->procedure
  481. '*
  482. (dynamic-pointer "sqlite3_column_blob" libsqlite3)
  483. (list '* int)))
  484. (value-bytes
  485. (pointer->procedure
  486. int
  487. (dynamic-pointer "sqlite3_column_bytes" libsqlite3)
  488. (list '* int))))
  489. (lambda (stmt i)
  490. (assert-live-stmt! stmt)
  491. (let ((nbytes (value-bytes (stmt-pointer stmt) i)))
  492. (case (value-type (stmt-pointer stmt) i)
  493. ((1) ; SQLITE_INTEGER
  494. (value-int (stmt-pointer stmt) i))
  495. ((2) ; SQLITE_FLOAT
  496. (value-double (stmt-pointer stmt) i))
  497. ((3) ; SQLITE3_TEXT
  498. (let ((p (value-blob (stmt-pointer stmt) i)))
  499. (if (null-pointer? p)
  500. ""
  501. (utf8->string
  502. (pointer->bytevector p nbytes)))))
  503. ((4) ; SQLITE_BLOB
  504. (let ((p (value-blob (stmt-pointer stmt) i)))
  505. (if (null-pointer? p)
  506. (make-bytevector 0)
  507. (bytevector-copy
  508. (pointer->bytevector p nbytes)))))
  509. ((5) ; SQLITE_NULL
  510. #f))))))
  511. (define (sqlite-column-names stmt)
  512. (let ((v (make-vector (sqlite-column-count stmt))))
  513. (let lp ((i 0))
  514. (if (< i (vector-length v))
  515. (begin
  516. (vector-set! v i (sqlite-column-name stmt i))
  517. (lp (1+ i)))
  518. v))))
  519. (define (sqlite-row stmt)
  520. (let ((v (make-vector (sqlite-column-count stmt))))
  521. (let lp ((i 0))
  522. (if (< i (vector-length v))
  523. (begin
  524. (vector-set! v i (sqlite-column-value stmt i))
  525. (lp (1+ i)))
  526. v))))
  527. (define sqlite-busy-timeout
  528. (let ((f (pointer->procedure
  529. int
  530. (dynamic-func "sqlite3_busy_timeout" libsqlite3)
  531. (list '* int))))
  532. (lambda (db value)
  533. (assert-live-db! db)
  534. (let ((ret (f (db-pointer db) value)))
  535. (when (not (zero? ret))
  536. (check-error db 'sqlite-busy-timeout))))))
  537. (define trace-callback
  538. (lambda (callback)
  539. (procedure->pointer
  540. int
  541. ;; P and X pointers are described here:
  542. ;; https://www.sqlite.org/c3ref/c_trace.html.
  543. (lambda (trace context p x)
  544. (callback trace p x)
  545. 0)
  546. (list unsigned-int '* '* '*))))
  547. (define sqlite-expanded-sql
  548. (let ((proc (pointer->procedure
  549. '*
  550. (dynamic-func "sqlite3_expanded_sql" libsqlite3)
  551. (list '*))))
  552. (lambda (stmt-pointer)
  553. (proc stmt-pointer))))
  554. ;; Save a reference to the trace callback pointer, otherwise it may be garbage
  555. ;; collected once out of sqlite-trace scope.
  556. (define trace-callback-pointer %null-pointer)
  557. (define sqlite-trace
  558. (let ((proc (pointer->procedure
  559. int
  560. (dynamic-func "sqlite3_trace_v2" libsqlite3)
  561. (list '* unsigned-int '* '*))))
  562. (lambda (db mask callback)
  563. (set! trace-callback-pointer (trace-callback callback))
  564. (proc (db-pointer db)
  565. mask
  566. trace-callback-pointer
  567. %null-pointer))))
  568. (define sqlite-step
  569. (let ((step (pointer->procedure
  570. int
  571. (dynamic-pointer "sqlite3_step" libsqlite3)
  572. (list '*))))
  573. (lambda (stmt)
  574. (assert-live-stmt! stmt)
  575. (let ((ret (step (stmt-pointer stmt))))
  576. (case ret
  577. ((100) ; SQLITE_ROW
  578. (sqlite-row stmt))
  579. ((101) ; SQLITE_DONE
  580. #f)
  581. (else
  582. (check-error (stmt->db stmt))
  583. (error "shouldn't get here")))))))
  584. (define (sqlite-fold kons knil stmt)
  585. (assert-live-stmt! stmt)
  586. (let lp ((seed knil))
  587. (let ((row (sqlite-step stmt)))
  588. (if row
  589. (lp (kons row seed))
  590. seed))))
  591. (define (sqlite-fold-right kons knil stmt)
  592. (assert-live-stmt! stmt)
  593. (let lp ()
  594. (let ((row (sqlite-step stmt)))
  595. (if row
  596. (kons row (lp))
  597. knil))))
  598. (define (sqlite-map proc stmt)
  599. (map proc
  600. (reverse! (sqlite-fold cons '() stmt))))